Home | History | Annotate | Line # | Download | only in cp
      1 /* Handle the hair of processing (but not expanding) inline functions.
      2    Also manage function and variable name overloading.
      3    Copyright (C) 1987-2022 Free Software Foundation, Inc.
      4    Contributed by Michael Tiemann (tiemann (at) cygnus.com)
      5 
      6 This file is part of GCC.
      7 
      8 GCC is free software; you can redistribute it and/or modify
      9 it under the terms of the GNU General Public License as published by
     10 the Free Software Foundation; either version 3, or (at your option)
     11 any later version.
     12 
     13 GCC is distributed in the hope that it will be useful,
     14 but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 GNU General Public License for more details.
     17 
     18 You should have received a copy of the GNU General Public License
     19 along with GCC; see the file COPYING3.  If not see
     20 <http://www.gnu.org/licenses/>.  */
     21 
     22 
     23 /* Handle method declarations.  */
     24 #include "config.h"
     25 #include "system.h"
     26 #include "coretypes.h"
     27 #include "target.h"
     28 #include "cp-tree.h"
     29 #include "decl.h"
     30 #include "stringpool.h"
     31 #include "cgraph.h"
     32 #include "varasm.h"
     33 #include "toplev.h"
     34 #include "intl.h"
     35 #include "common/common-target.h"
     36 
     37 static void do_build_copy_assign (tree);
     38 static void do_build_copy_constructor (tree);
     39 static tree make_alias_for_thunk (tree);
     40 
     41 /* Called once to initialize method.cc.  */
     42 
     43 void
     44 init_method (void)
     45 {
     46   init_mangle ();
     47 }
     48 
     49 /* Return a this or result adjusting thunk to FUNCTION.  THIS_ADJUSTING
     51    indicates whether it is a this or result adjusting thunk.
     52    FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
     53    (see thunk_adjust).  VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
     54    never is.  VIRTUAL_OFFSET is the /index/ into the vtable for this
     55    adjusting thunks, we scale it to a byte offset. For covariant
     56    thunks VIRTUAL_OFFSET is the virtual binfo.  You must post process
     57    the returned thunk with finish_thunk.  */
     58 
     59 tree
     60 make_thunk (tree function, bool this_adjusting,
     61 	    tree fixed_offset, tree virtual_offset)
     62 {
     63   HOST_WIDE_INT d;
     64   tree thunk;
     65 
     66   gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
     67   /* We can have this thunks to covariant thunks, but not vice versa.  */
     68   gcc_assert (!DECL_THIS_THUNK_P (function));
     69   gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting);
     70 
     71   /* Scale the VIRTUAL_OFFSET to be in terms of bytes.  */
     72   if (this_adjusting && virtual_offset)
     73     virtual_offset
     74       = size_binop (MULT_EXPR,
     75 		    virtual_offset,
     76 		    convert (ssizetype,
     77 			     TYPE_SIZE_UNIT (vtable_entry_type)));
     78 
     79   d = tree_to_shwi (fixed_offset);
     80 
     81   /* See if we already have the thunk in question.  For this_adjusting
     82      thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
     83      will be a BINFO.  */
     84   for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk))
     85     if (DECL_THIS_THUNK_P (thunk) == this_adjusting
     86 	&& THUNK_FIXED_OFFSET (thunk) == d
     87 	&& !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
     88 	&& (!virtual_offset
     89 	    || (this_adjusting
     90 		? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
     91 				      virtual_offset)
     92 		: THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
     93       return thunk;
     94 
     95   /* All thunks must be created before FUNCTION is actually emitted;
     96      the ABI requires that all thunks be emitted together with the
     97      function to which they transfer control.  */
     98   gcc_assert (!TREE_ASM_WRITTEN (function));
     99   /* Likewise, we can only be adding thunks to a function declared in
    100      the class currently being laid out.  */
    101   gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
    102 	      && TYPE_BEING_DEFINED (DECL_CONTEXT (function)));
    103 
    104   thunk = build_decl (DECL_SOURCE_LOCATION (function),
    105 		      FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
    106   DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
    107   cxx_dup_lang_specific_decl (thunk);
    108   DECL_VIRTUAL_P (thunk) = true;
    109   SET_DECL_THUNKS (thunk, NULL_TREE);
    110 
    111   DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
    112   TREE_READONLY (thunk) = TREE_READONLY (function);
    113   TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
    114   TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
    115   SET_DECL_THUNK_P (thunk, this_adjusting);
    116   THUNK_TARGET (thunk) = function;
    117   THUNK_FIXED_OFFSET (thunk) = d;
    118   THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
    119   THUNK_ALIAS (thunk) = NULL_TREE;
    120 
    121   DECL_INTERFACE_KNOWN (thunk) = 1;
    122   DECL_NOT_REALLY_EXTERN (thunk) = 1;
    123   DECL_COMDAT (thunk) = DECL_COMDAT (function);
    124   DECL_SAVED_AUTO_RETURN_TYPE (thunk) = NULL;
    125   /* The thunk itself is not a constructor or destructor, even if
    126      the thing it is thunking to is.  */
    127   DECL_CXX_DESTRUCTOR_P (thunk) = 0;
    128   DECL_CXX_CONSTRUCTOR_P (thunk) = 0;
    129   DECL_EXTERNAL (thunk) = 1;
    130   DECL_ARTIFICIAL (thunk) = 1;
    131   /* The THUNK is not a pending inline, even if the FUNCTION is.  */
    132   DECL_PENDING_INLINE_P (thunk) = 0;
    133   DECL_DECLARED_INLINE_P (thunk) = 0;
    134   /* Nor is it a template instantiation.  */
    135   DECL_USE_TEMPLATE (thunk) = 0;
    136   DECL_TEMPLATE_INFO (thunk) = NULL;
    137 
    138   /* Add it to the list of thunks associated with FUNCTION.  */
    139   DECL_CHAIN (thunk) = DECL_THUNKS (function);
    140   SET_DECL_THUNKS (function, thunk);
    141 
    142   return thunk;
    143 }
    144 
    145 /* Finish THUNK, a thunk decl.  */
    146 
    147 void
    148 finish_thunk (tree thunk)
    149 {
    150   tree function, name;
    151   tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
    152   tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
    153 
    154   gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk));
    155   if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
    156     virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
    157   function = THUNK_TARGET (thunk);
    158   name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
    159 		       fixed_offset, virtual_offset, thunk);
    160 
    161   /* We can end up with declarations of (logically) different
    162      covariant thunks, that do identical adjustments.  The two thunks
    163      will be adjusting between within different hierarchies, which
    164      happen to have the same layout.  We must nullify one of them to
    165      refer to the other.  */
    166   if (DECL_RESULT_THUNK_P (thunk))
    167     {
    168       tree cov_probe;
    169 
    170       for (cov_probe = DECL_THUNKS (function);
    171 	   cov_probe; cov_probe = DECL_CHAIN (cov_probe))
    172 	if (DECL_NAME (cov_probe) == name)
    173 	  {
    174 	    gcc_assert (!DECL_THUNKS (thunk));
    175 	    THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
    176 				   ? THUNK_ALIAS (cov_probe) : cov_probe);
    177 	    break;
    178 	  }
    179     }
    180 
    181   DECL_NAME (thunk) = name;
    182   SET_DECL_ASSEMBLER_NAME (thunk, name);
    183 }
    184 
    185 static GTY (()) int thunk_labelno;
    186 
    187 /* Create a static alias to target.  */
    188 
    189 tree
    190 make_alias_for (tree target, tree newid)
    191 {
    192   tree alias = build_decl (DECL_SOURCE_LOCATION (target),
    193 			   TREE_CODE (target), newid, TREE_TYPE (target));
    194   DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
    195   cxx_dup_lang_specific_decl (alias);
    196   DECL_CONTEXT (alias) = DECL_CONTEXT (target);
    197   TREE_READONLY (alias) = TREE_READONLY (target);
    198   TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
    199   TREE_PUBLIC (alias) = 0;
    200   DECL_INTERFACE_KNOWN (alias) = 1;
    201   if (DECL_LANG_SPECIFIC (alias))
    202     {
    203       DECL_NOT_REALLY_EXTERN (alias) = 1;
    204       DECL_USE_TEMPLATE (alias) = 0;
    205       DECL_TEMPLATE_INFO (alias) = NULL;
    206     }
    207   DECL_EXTERNAL (alias) = 0;
    208   DECL_ARTIFICIAL (alias) = 1;
    209   DECL_TEMPLATE_INSTANTIATED (alias) = 0;
    210   if (TREE_CODE (alias) == FUNCTION_DECL)
    211     {
    212       DECL_SAVED_AUTO_RETURN_TYPE (alias) = NULL;
    213       DECL_CXX_DESTRUCTOR_P (alias) = 0;
    214       DECL_CXX_CONSTRUCTOR_P (alias) = 0;
    215       DECL_PENDING_INLINE_P (alias) = 0;
    216       DECL_DECLARED_INLINE_P (alias) = 0;
    217       DECL_INITIAL (alias) = error_mark_node;
    218       DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
    219     }
    220   else
    221     TREE_STATIC (alias) = 1;
    222   TREE_ADDRESSABLE (alias) = 1;
    223   TREE_USED (alias) = 1;
    224   SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
    225   return alias;
    226 }
    227 
    228 static tree
    229 make_alias_for_thunk (tree function)
    230 {
    231   tree alias;
    232   char buf[256];
    233 
    234   targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno);
    235   thunk_labelno++;
    236 
    237   alias = make_alias_for (function, get_identifier (buf));
    238 
    239   if (!flag_syntax_only)
    240     {
    241       struct cgraph_node *funcn, *aliasn;
    242       funcn = cgraph_node::get (function);
    243       gcc_checking_assert (funcn);
    244       aliasn = cgraph_node::create_same_body_alias (alias, function);
    245       DECL_ASSEMBLER_NAME (function);
    246       gcc_assert (aliasn != NULL);
    247     }
    248 
    249   return alias;
    250 }
    251 
    252 /* Emit the definition of a C++ multiple inheritance or covariant
    253    return vtable thunk.  If EMIT_P is nonzero, the thunk is emitted
    254    immediately.  */
    255 
    256 void
    257 use_thunk (tree thunk_fndecl, bool emit_p)
    258 {
    259   tree a, t, function, alias;
    260   tree virtual_offset;
    261   HOST_WIDE_INT fixed_offset, virtual_value;
    262   bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
    263   struct cgraph_node *funcn, *thunk_node;
    264 
    265   /* We should have called finish_thunk to give it a name.  */
    266   gcc_assert (DECL_NAME (thunk_fndecl));
    267 
    268   /* We should never be using an alias, always refer to the
    269      aliased thunk.  */
    270   gcc_assert (!THUNK_ALIAS (thunk_fndecl));
    271 
    272   if (TREE_ASM_WRITTEN (thunk_fndecl))
    273     return;
    274 
    275   function = THUNK_TARGET (thunk_fndecl);
    276   if (DECL_RESULT (thunk_fndecl))
    277     /* We already turned this thunk into an ordinary function.
    278        There's no need to process this thunk again.  */
    279     return;
    280 
    281   if (DECL_THUNK_P (function))
    282     /* The target is itself a thunk, process it now.  */
    283     use_thunk (function, emit_p);
    284 
    285   /* Thunks are always addressable; they only appear in vtables.  */
    286   TREE_ADDRESSABLE (thunk_fndecl) = 1;
    287 
    288   /* Don't diagnose deprecated or unavailable functions just because they
    289      have thunks emitted for them.  */
    290   auto du = make_temp_override (deprecated_state,
    291                                 UNAVAILABLE_DEPRECATED_SUPPRESS);
    292 
    293   /* Figure out what function is being thunked to.  It's referenced in
    294      this translation unit.  */
    295   TREE_ADDRESSABLE (function) = 1;
    296   mark_used (function);
    297   if (!emit_p)
    298     return;
    299 
    300   if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
    301    alias = make_alias_for_thunk (function);
    302   else
    303    alias = function;
    304 
    305   fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
    306   virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
    307 
    308   if (virtual_offset)
    309     {
    310       if (!this_adjusting)
    311 	virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
    312       virtual_value = tree_to_shwi (virtual_offset);
    313       gcc_assert (virtual_value);
    314     }
    315   else
    316     virtual_value = 0;
    317 
    318   /* And, if we need to emit the thunk, it's used.  */
    319   mark_used (thunk_fndecl);
    320   /* This thunk is actually defined.  */
    321   DECL_EXTERNAL (thunk_fndecl) = 0;
    322   /* The linkage of the function may have changed.  FIXME in linkage
    323      rewrite.  */
    324   gcc_assert (DECL_INTERFACE_KNOWN (function));
    325   TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
    326   DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
    327   DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
    328     = DECL_VISIBILITY_SPECIFIED (function);
    329   DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function);
    330   DECL_WEAK (thunk_fndecl) = DECL_WEAK (function);
    331 
    332   if (flag_syntax_only)
    333     {
    334       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
    335       return;
    336     }
    337 
    338   push_to_top_level ();
    339 
    340   if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
    341       && targetm_common.have_named_sections)
    342     {
    343       tree fn = function;
    344       struct symtab_node *symbol;
    345 
    346       if ((symbol = symtab_node::get (function))
    347 	  && symbol->alias)
    348 	{
    349 	  if (symbol->analyzed)
    350 	    fn = symtab_node::get (function)->ultimate_alias_target ()->decl;
    351 	  else
    352 	    fn = symtab_node::get (function)->alias_target;
    353 	}
    354       resolve_unique_section (fn, 0, flag_function_sections);
    355 
    356       if (DECL_SECTION_NAME (fn) != NULL && DECL_ONE_ONLY (fn))
    357 	{
    358 	  resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
    359 
    360 	  /* Output the thunk into the same section as function.  */
    361 	  set_decl_section_name (thunk_fndecl, fn);
    362 	  symtab_node::get (thunk_fndecl)->implicit_section
    363 	    = symtab_node::get (fn)->implicit_section;
    364 	}
    365     }
    366 
    367   /* Set up cloned argument trees for the thunk.  */
    368   t = NULL_TREE;
    369   for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))
    370     {
    371       tree x = copy_node (a);
    372       DECL_CHAIN (x) = t;
    373       DECL_CONTEXT (x) = thunk_fndecl;
    374       SET_DECL_RTL (x, NULL);
    375       DECL_HAS_VALUE_EXPR_P (x) = 0;
    376       TREE_ADDRESSABLE (x) = 0;
    377       t = x;
    378     }
    379   a = nreverse (t);
    380   DECL_ARGUMENTS (thunk_fndecl) = a;
    381   TREE_ASM_WRITTEN (thunk_fndecl) = 1;
    382   funcn = cgraph_node::get (function);
    383   gcc_checking_assert (funcn);
    384   thunk_node = funcn->create_thunk (thunk_fndecl, function,
    385 				    this_adjusting, fixed_offset, virtual_value,
    386 				    0, virtual_offset, alias);
    387   if (DECL_ONE_ONLY (function))
    388     thunk_node->add_to_same_comdat_group (funcn);
    389 
    390   pop_from_top_level ();
    391 }
    392 
    393 /* Code for synthesizing methods which have default semantics defined.  */
    395 
    396 /* True iff CTYPE has a trivial SFK.  */
    397 
    398 static bool
    399 type_has_trivial_fn (tree ctype, special_function_kind sfk)
    400 {
    401   switch (sfk)
    402     {
    403     case sfk_constructor:
    404       return !TYPE_HAS_COMPLEX_DFLT (ctype);
    405     case sfk_copy_constructor:
    406       return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype);
    407     case sfk_move_constructor:
    408       return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype);
    409     case sfk_copy_assignment:
    410       return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype);
    411     case sfk_move_assignment:
    412       return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
    413     case sfk_destructor:
    414     case sfk_virtual_destructor:
    415       return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
    416     case sfk_inheriting_constructor:
    417     case sfk_comparison:
    418       return false;
    419     default:
    420       gcc_unreachable ();
    421     }
    422 }
    423 
    424 /* Note that CTYPE has a non-trivial SFK even though we previously thought
    425    it was trivial.  */
    426 
    427 static void
    428 type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
    429 {
    430   switch (sfk)
    431     {
    432     case sfk_constructor:
    433       TYPE_HAS_COMPLEX_DFLT (ctype) = true;
    434       return;
    435     case sfk_copy_constructor:
    436       TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true;
    437       return;
    438     case sfk_move_constructor:
    439       TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true;
    440       return;
    441     case sfk_copy_assignment:
    442       TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true;
    443       return;
    444     case sfk_move_assignment:
    445       TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true;
    446       return;
    447     case sfk_destructor:
    448       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
    449       return;
    450     case sfk_inheriting_constructor:
    451     default:
    452       gcc_unreachable ();
    453     }
    454 }
    455 
    456 /* True iff FN is a trivial defaulted member function ([cd]tor, op=).  */
    457 
    458 bool
    459 trivial_fn_p (tree fn)
    460 {
    461   if (TREE_CODE (fn) == TEMPLATE_DECL)
    462     return false;
    463   if (!DECL_DEFAULTED_FN (fn))
    464     return false;
    465 
    466   /* If fn is a clone, get the primary variant.  */
    467   if (tree prim = DECL_CLONED_FUNCTION (fn))
    468     fn = prim;
    469   return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
    470 }
    471 
    472 /* PARM is a PARM_DECL for a function which we want to forward to another
    473    function without changing its value category, a la std::forward.  */
    474 
    475 tree
    476 forward_parm (tree parm)
    477 {
    478   tree exp = convert_from_reference (parm);
    479   tree type = TREE_TYPE (parm);
    480   if (DECL_PACK_P (parm))
    481     type = PACK_EXPANSION_PATTERN (type);
    482   if (!TYPE_REF_P (type))
    483     type = cp_build_reference_type (type, /*rval=*/true);
    484   warning_sentinel w (warn_useless_cast);
    485   exp = build_static_cast (input_location, type, exp,
    486 			   tf_warning_or_error);
    487   if (DECL_PACK_P (parm))
    488     exp = make_pack_expansion (exp);
    489   return exp;
    490 }
    491 
    492 /* Strip all inheriting constructors, if any, to return the original
    493    constructor from a (possibly indirect) base class.  */
    494 
    495 tree
    496 strip_inheriting_ctors (tree dfn)
    497 {
    498   if (!flag_new_inheriting_ctors)
    499     return dfn;
    500   tree fn = dfn;
    501   while (tree inh = DECL_INHERITED_CTOR (fn))
    502     fn = OVL_FIRST (inh);
    503 
    504   if (TREE_CODE (fn) == TEMPLATE_DECL
    505       && TREE_CODE (dfn) == FUNCTION_DECL)
    506     fn = DECL_TEMPLATE_RESULT (fn);
    507   return fn;
    508 }
    509 
    510 /* Find the binfo for the base subobject of BINFO being initialized by
    511    inherited constructor FNDECL (a member of a direct base of BINFO).  */
    512 
    513 static tree inherited_ctor_binfo (tree, tree);
    514 static tree
    515 inherited_ctor_binfo_1 (tree binfo, tree fndecl)
    516 {
    517   tree base = DECL_CONTEXT (fndecl);
    518   tree base_binfo;
    519   for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    520     if (BINFO_TYPE (base_binfo) == base)
    521       return inherited_ctor_binfo (base_binfo, fndecl);
    522 
    523   gcc_unreachable();
    524 }
    525 
    526 /* Find the binfo for the base subobject of BINFO being initialized by
    527    inheriting constructor FNDECL (a member of BINFO), or BINFO if FNDECL is not
    528    an inheriting constructor.  */
    529 
    530 static tree
    531 inherited_ctor_binfo (tree binfo, tree fndecl)
    532 {
    533   tree inh = DECL_INHERITED_CTOR (fndecl);
    534   if (!inh)
    535     return binfo;
    536 
    537   tree results = NULL_TREE;
    538   for (ovl_iterator iter (inh); iter; ++iter)
    539     {
    540       tree one = inherited_ctor_binfo_1 (binfo, *iter);
    541       if (!results)
    542 	results = one;
    543       else if (one != results)
    544 	results = tree_cons (NULL_TREE, one, results);
    545     }
    546   return results;
    547 }
    548 
    549 /* Find the binfo for the base subobject being initialized by inheriting
    550    constructor FNDECL, or NULL_TREE if FNDECL is not an inheriting
    551    constructor.  */
    552 
    553 tree
    554 inherited_ctor_binfo (tree fndecl)
    555 {
    556   if (!DECL_INHERITED_CTOR (fndecl))
    557     return NULL_TREE;
    558   tree binfo = TYPE_BINFO (DECL_CONTEXT (fndecl));
    559   return inherited_ctor_binfo (binfo, fndecl);
    560 }
    561 
    562 
    563 /* True if we should omit all user-declared parameters from a base
    564    construtor built from complete constructor FN.
    565    That's when the ctor is inherited from a virtual base.  */
    566 
    567 bool
    568 base_ctor_omit_inherited_parms (tree comp_ctor)
    569 {
    570   gcc_checking_assert (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (comp_ctor));
    571 
    572   if (!flag_new_inheriting_ctors)
    573     /* We only optimize away the parameters in the new model.  */
    574     return false;
    575 
    576   if (!CLASSTYPE_VBASECLASSES (DECL_CONTEXT (comp_ctor)))
    577     return false;
    578 
    579   if (FUNCTION_FIRST_USER_PARMTYPE (comp_ctor) == void_list_node)
    580     /* No user-declared parameters to omit.  */
    581     return false;
    582 
    583   for (tree binfo = inherited_ctor_binfo (comp_ctor);
    584        binfo;
    585        binfo = BINFO_INHERITANCE_CHAIN (binfo))
    586     if (BINFO_VIRTUAL_P (binfo))
    587       return true;
    588 
    589   return false;
    590 }
    591 
    592 
    593 /* True if we should omit all user-declared parameters from constructor FN,
    594    because it is a base clone of a ctor inherited from a virtual base.  */
    595 
    596 bool
    597 ctor_omit_inherited_parms (tree fn)
    598 {
    599   gcc_checking_assert (TREE_CODE (fn) == FUNCTION_DECL);
    600 
    601   if (!DECL_BASE_CONSTRUCTOR_P (fn))
    602     return false;
    603 
    604   return base_ctor_omit_inherited_parms (DECL_CLONED_FUNCTION (fn));
    605 }
    606 
    607 /* True iff constructor(s) INH inherited into BINFO initializes INIT_BINFO.
    608    This can be true for multiple virtual bases as well as one direct
    609    non-virtual base.  */
    610 
    611 static bool
    612 binfo_inherited_from (tree binfo, tree init_binfo, tree inh)
    613 {
    614   /* inh is an OVERLOAD if we inherited the same constructor along
    615      multiple paths, check all of them.  */
    616   for (ovl_iterator iter (inh); iter; ++iter)
    617     {
    618       tree fn = *iter;
    619       tree base = DECL_CONTEXT (fn);
    620       tree base_binfo = NULL_TREE;
    621       for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    622 	if (BINFO_TYPE (base_binfo) == base)
    623 	  break;
    624       if (base_binfo == init_binfo
    625 	  || (flag_new_inheriting_ctors
    626 	      && binfo_inherited_from (base_binfo, init_binfo,
    627 				       DECL_INHERITED_CTOR (fn))))
    628 	return true;
    629     }
    630   return false;
    631 }
    632 
    633 /* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
    634    given the parameter or parameters PARM, possibly inherited constructor
    635    base INH, or move flag MOVE_P.  */
    636 
    637 static tree
    638 add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
    639 		   tree member_init_list)
    640 {
    641   tree init;
    642   if (inh)
    643     {
    644       /* An inheriting constructor only has a mem-initializer for
    645 	 the base it inherits from.  */
    646       if (!binfo_inherited_from (TYPE_BINFO (current_class_type), binfo, inh))
    647 	return member_init_list;
    648 
    649       tree *p = &init;
    650       init = NULL_TREE;
    651       for (; parm; parm = DECL_CHAIN (parm))
    652 	{
    653 	  tree exp = forward_parm (parm);
    654 	  *p = build_tree_list (NULL_TREE, exp);
    655 	  p = &TREE_CHAIN (*p);
    656 	}
    657     }
    658   else
    659     {
    660       init = build_base_path (PLUS_EXPR, parm, binfo, 1,
    661 			      tf_warning_or_error);
    662       if (move_p)
    663 	init = move (init);
    664       init = build_tree_list (NULL_TREE, init);
    665     }
    666   return tree_cons (binfo, init, member_init_list);
    667 }
    668 
    669 /* Generate code for default X(X&) or X(X&&) constructor or an inheriting
    670    constructor.  */
    671 
    672 static void
    673 do_build_copy_constructor (tree fndecl)
    674 {
    675   tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
    676   bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
    677   bool trivial = trivial_fn_p (fndecl);
    678   tree inh = DECL_INHERITED_CTOR (fndecl);
    679 
    680   if (!inh)
    681     parm = convert_from_reference (parm);
    682 
    683   if (trivial)
    684     {
    685       if (is_empty_class (current_class_type))
    686 	/* Don't copy the padding byte; it might not have been allocated
    687 	   if *this is a base subobject.  */;
    688       else if (tree_int_cst_equal (TYPE_SIZE (current_class_type),
    689 				   CLASSTYPE_SIZE (current_class_type)))
    690 	{
    691 	  tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
    692 	  finish_expr_stmt (t);
    693 	}
    694       else
    695 	{
    696 	  /* We must only copy the non-tail padding parts.  */
    697 	  tree base_size = CLASSTYPE_SIZE_UNIT (current_class_type);
    698 	  base_size = size_binop (MINUS_EXPR, base_size, size_int (1));
    699 	  tree array_type = build_array_type (unsigned_char_type_node,
    700 					      build_index_type (base_size));
    701 	  tree alias_set = build_int_cst (TREE_TYPE (current_class_ptr), 0);
    702 	  tree lhs = build2 (MEM_REF, array_type,
    703 			     current_class_ptr, alias_set);
    704 	  tree rhs = build2 (MEM_REF, array_type,
    705 			     TREE_OPERAND (parm, 0), alias_set);
    706 	  tree t = build2 (INIT_EXPR, void_type_node, lhs, rhs);
    707 	  finish_expr_stmt (t);
    708 	}
    709     }
    710   else
    711     {
    712       tree member_init_list = NULL_TREE;
    713       int i;
    714       tree binfo, base_binfo;
    715       vec<tree, va_gc> *vbases;
    716 
    717       /* Initialize all the base-classes with the parameter converted
    718 	 to their type so that we get their copy constructor and not
    719 	 another constructor that takes current_class_type.  We must
    720 	 deal with the binfo's directly as a direct base might be
    721 	 inaccessible due to ambiguity.  */
    722       for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
    723 	   vec_safe_iterate (vbases, i, &binfo); i++)
    724 	{
    725 	  member_init_list = add_one_base_init (binfo, parm, move_p, inh,
    726 						member_init_list);
    727 	}
    728 
    729       for (binfo = TYPE_BINFO (current_class_type), i = 0;
    730 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    731 	{
    732 	  if (BINFO_VIRTUAL_P (base_binfo))
    733 	    continue;
    734 	  member_init_list = add_one_base_init (base_binfo, parm, move_p,
    735 						inh, member_init_list);
    736 	}
    737 
    738       if (!inh)
    739 	{
    740 	  int cvquals = cp_type_quals (TREE_TYPE (parm));
    741 
    742 	  for (tree fields = TYPE_FIELDS (current_class_type);
    743 	       fields; fields = DECL_CHAIN (fields))
    744 	    {
    745 	      tree field = fields;
    746 	      tree expr_type;
    747 
    748 	      if (TREE_CODE (field) != FIELD_DECL)
    749 		continue;
    750 
    751 	      expr_type = TREE_TYPE (field);
    752 	      if (DECL_NAME (field))
    753 		{
    754 		  if (VFIELD_NAME_P (DECL_NAME (field)))
    755 		    continue;
    756 		}
    757 	      else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
    758 		/* Just use the field; anonymous types can't have
    759 		   nontrivial copy ctors or assignment ops or this
    760 		   function would be deleted.  */;
    761 	      else
    762 		continue;
    763 
    764 	      /* Compute the type of "init->field".  If the copy-constructor
    765 		 parameter is, for example, "const S&", and the type of
    766 		 the field is "T", then the type will usually be "const
    767 		 T".  (There are no cv-qualified variants of reference
    768 		 types.)  */
    769 	      if (!TYPE_REF_P (expr_type))
    770 		{
    771 		  int quals = cvquals;
    772 
    773 		  if (DECL_MUTABLE_P (field))
    774 		    quals &= ~TYPE_QUAL_CONST;
    775 		  quals |= cp_type_quals (expr_type);
    776 		  expr_type = cp_build_qualified_type (expr_type, quals);
    777 		}
    778 
    779 	      tree init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
    780 	      if (move_p && !TYPE_REF_P (expr_type)
    781 		  /* 'move' breaks bit-fields, and has no effect for scalars.  */
    782 		  && !scalarish_type_p (expr_type))
    783 		init = move (init);
    784 	      init = build_tree_list (NULL_TREE, init);
    785 
    786 	      member_init_list = tree_cons (field, init, member_init_list);
    787 	    }
    788 	}
    789 
    790       finish_mem_initializers (member_init_list);
    791     }
    792 }
    793 
    794 static void
    795 do_build_copy_assign (tree fndecl)
    796 {
    797   tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl));
    798   tree compound_stmt;
    799   bool move_p = move_fn_p (fndecl);
    800   bool trivial = trivial_fn_p (fndecl);
    801   int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
    802 
    803   compound_stmt = begin_compound_stmt (0);
    804   parm = convert_from_reference (parm);
    805 
    806   if (trivial
    807       && is_empty_class (current_class_type))
    808     /* Don't copy the padding byte; it might not have been allocated
    809        if *this is a base subobject.  */;
    810   else if (trivial)
    811     {
    812       tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm);
    813       finish_expr_stmt (t);
    814     }
    815   else
    816     {
    817       tree fields;
    818       int cvquals = cp_type_quals (TREE_TYPE (parm));
    819       int i;
    820       tree binfo, base_binfo;
    821 
    822       /* Assign to each of the direct base classes.  */
    823       for (binfo = TYPE_BINFO (current_class_type), i = 0;
    824 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    825 	{
    826 	  tree converted_parm;
    827 
    828 	  /* We must convert PARM directly to the base class
    829 	     explicitly since the base class may be ambiguous.  */
    830 	  converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
    831 					    tf_warning_or_error);
    832 	  if (move_p)
    833 	    converted_parm = move (converted_parm);
    834 	  /* Call the base class assignment operator.  */
    835 	  releasing_vec parmvec (make_tree_vector_single (converted_parm));
    836 	  finish_expr_stmt
    837 	    (build_special_member_call (current_class_ref,
    838 					assign_op_identifier,
    839 					&parmvec,
    840 					base_binfo,
    841 					flags,
    842                                         tf_warning_or_error));
    843 	}
    844 
    845       /* Assign to each of the non-static data members.  */
    846       for (fields = TYPE_FIELDS (current_class_type);
    847 	   fields;
    848 	   fields = DECL_CHAIN (fields))
    849 	{
    850 	  tree comp = current_class_ref;
    851 	  tree init = parm;
    852 	  tree field = fields;
    853 	  tree expr_type;
    854 	  int quals;
    855 
    856 	  if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
    857 	    continue;
    858 
    859 	  expr_type = TREE_TYPE (field);
    860 
    861 	  if (CP_TYPE_CONST_P (expr_type))
    862 	    {
    863 	      error ("non-static const member %q#D, cannot use default "
    864 		     "assignment operator", field);
    865 	      continue;
    866 	    }
    867 	  else if (TYPE_REF_P (expr_type))
    868 	    {
    869 	      error ("non-static reference member %q#D, cannot use "
    870 		     "default assignment operator", field);
    871 	      continue;
    872 	    }
    873 
    874 	  if (DECL_NAME (field))
    875 	    {
    876 	      if (VFIELD_NAME_P (DECL_NAME (field)))
    877 		continue;
    878 	    }
    879 	  else if (ANON_AGGR_TYPE_P (expr_type)
    880 		   && TYPE_FIELDS (expr_type) != NULL_TREE)
    881 	    /* Just use the field; anonymous types can't have
    882 	       nontrivial copy ctors or assignment ops or this
    883 	       function would be deleted.  */;
    884 	  else
    885 	    continue;
    886 
    887 	  comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);
    888 
    889 	  /* Compute the type of init->field  */
    890 	  quals = cvquals;
    891 	  if (DECL_MUTABLE_P (field))
    892 	    quals &= ~TYPE_QUAL_CONST;
    893 	  expr_type = cp_build_qualified_type (expr_type, quals);
    894 
    895 	  init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
    896 	  if (move_p && !TYPE_REF_P (expr_type)
    897 	      /* 'move' breaks bit-fields, and has no effect for scalars.  */
    898 	      && !scalarish_type_p (expr_type))
    899 	    init = move (init);
    900 
    901 	  if (DECL_NAME (field))
    902 	    init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
    903 					 tf_warning_or_error);
    904 	  else
    905 	    init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
    906 	  finish_expr_stmt (init);
    907 	}
    908     }
    909   finish_return_stmt (current_class_ref);
    910   finish_compound_stmt (compound_stmt);
    911 }
    912 
    913 /* C++20 <compare> comparison category types.  */
    914 
    915 enum comp_cat_tag
    916 {
    917   cc_partial_ordering,
    918   cc_weak_ordering,
    919   cc_strong_ordering,
    920   cc_last
    921 };
    922 
    923 /* Names of the comparison categories and their value members, to be indexed by
    924    comp_cat_tag enumerators.  genericize_spaceship below relies on the ordering
    925    of the members.  */
    926 
    927 struct comp_cat_info_t
    928 {
    929   const char *name;
    930   const char *members[4];
    931 };
    932 static const comp_cat_info_t comp_cat_info[cc_last]
    933 = {
    934    { "partial_ordering", { "equivalent", "greater", "less", "unordered" } },
    935    { "weak_ordering", { "equivalent", "greater", "less" } },
    936    { "strong_ordering", { "equal", "greater", "less" } }
    937 };
    938 
    939 /* A cache of the category types to speed repeated lookups.  */
    940 
    941 static GTY((deletable)) tree comp_cat_cache[cc_last];
    942 
    943 /* Look up one of the result variables in the comparison category type.  */
    944 
    945 static tree
    946 lookup_comparison_result (tree type, const char *name_str,
    947 			  tsubst_flags_t complain = tf_warning_or_error)
    948 {
    949   tree name = get_identifier (name_str);
    950   tree decl = lookup_qualified_name (type, name);
    951   if (TREE_CODE (decl) != VAR_DECL)
    952     {
    953       if (complain & tf_error)
    954 	{
    955 	  auto_diagnostic_group d;
    956 	  if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
    957 	    qualified_name_lookup_error (type, name, decl, input_location);
    958 	  else
    959 	    error ("%qD is not a static data member", decl);
    960 	  inform (input_location, "determining value of %qs", "operator<=>");
    961 	}
    962       return error_mark_node;
    963     }
    964   return decl;
    965 }
    966 
    967 /* Look up a <compare> comparison category type in std.  */
    968 
    969 static tree
    970 lookup_comparison_category (comp_cat_tag tag,
    971 			    tsubst_flags_t complain = tf_warning_or_error)
    972 {
    973   if (tree cached = comp_cat_cache[tag])
    974     return cached;
    975 
    976   tree name = get_identifier (comp_cat_info[tag].name);
    977   tree decl = lookup_qualified_name (std_node, name);
    978   if (TREE_CODE (decl) != TYPE_DECL)
    979     {
    980       if (complain & tf_error)
    981 	{
    982 	  auto_diagnostic_group d;
    983 	  if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
    984 	    qualified_name_lookup_error (std_node, name, decl, input_location);
    985 	  else
    986 	    error ("%qD is not a type", decl);
    987 	  inform (input_location, "forming type of %qs", "operator<=>");
    988 	}
    989       return error_mark_node;
    990     }
    991   /* Also make sure we can look up the value members now, since we won't
    992      really use them until genericize time.  */
    993   tree type = TREE_TYPE (decl);
    994   for (int i = 0; i < 4; ++i)
    995     {
    996       const char *p = comp_cat_info[tag].members[i];
    997       if (!p) break;
    998       if (lookup_comparison_result (type, p, complain)
    999 	  == error_mark_node)
   1000 	return error_mark_node;
   1001     }
   1002   return comp_cat_cache[tag] = type;
   1003 }
   1004 
   1005 /* Wrapper that takes the tag rather than the type.  */
   1006 
   1007 static tree
   1008 lookup_comparison_result (comp_cat_tag tag, const char *name_str,
   1009 			  tsubst_flags_t complain = tf_warning_or_error)
   1010 {
   1011   tree type = lookup_comparison_category (tag, complain);
   1012   return lookup_comparison_result (type, name_str, complain);
   1013 }
   1014 
   1015 /* Wrapper that takes the index into the members array instead of the name.  */
   1016 
   1017 static tree
   1018 lookup_comparison_result (comp_cat_tag tag, tree type, int idx)
   1019 {
   1020   const char *name_str = comp_cat_info[tag].members[idx];
   1021   if (!name_str)
   1022     return NULL_TREE;
   1023   return lookup_comparison_result (type, name_str);
   1024 }
   1025 
   1026 /* Does TYPE correspond to TAG?  */
   1027 
   1028 static bool
   1029 is_cat (tree type, comp_cat_tag tag)
   1030 {
   1031   tree name = TYPE_LINKAGE_IDENTIFIER (type);
   1032   return id_equal (name, comp_cat_info[tag].name);
   1033 }
   1034 
   1035 /* Return the comp_cat_tag for TYPE.  */
   1036 
   1037 static comp_cat_tag
   1038 cat_tag_for (tree type)
   1039 {
   1040   if (!CLASS_TYPE_P (type) || !decl_in_std_namespace_p (TYPE_MAIN_DECL (type)))
   1041     return cc_last;
   1042   for (int i = 0; i < cc_last; ++i)
   1043     {
   1044       comp_cat_tag tag = (comp_cat_tag)i;
   1045       if (is_cat (type, tag))
   1046 	return tag;
   1047     }
   1048   return cc_last;
   1049 }
   1050 
   1051 /* Return the comparison category tag of a <=> expression with non-class type
   1052    OPTYPE.  */
   1053 
   1054 static comp_cat_tag
   1055 spaceship_comp_cat (tree optype)
   1056 {
   1057   if (INTEGRAL_OR_ENUMERATION_TYPE_P (optype) || TYPE_PTROBV_P (optype))
   1058     return cc_strong_ordering;
   1059   else if (TREE_CODE (optype) == REAL_TYPE)
   1060     return cc_partial_ordering;
   1061 
   1062   /* ??? should vector <=> produce a vector of one of the above?  */
   1063   gcc_unreachable ();
   1064 }
   1065 
   1066 /* Return the comparison category type of a <=> expression with non-class type
   1067    OPTYPE.  */
   1068 
   1069 tree
   1070 spaceship_type (tree optype, tsubst_flags_t complain)
   1071 {
   1072   comp_cat_tag tag = spaceship_comp_cat (optype);
   1073   return lookup_comparison_category (tag, complain);
   1074 }
   1075 
   1076 /* Turn <=> with type TYPE and operands OP0 and OP1 into GENERIC.
   1077    This is also used by build_comparison_op for fallback to op< and op==
   1078    in a defaulted op<=>.  */
   1079 
   1080 tree
   1081 genericize_spaceship (location_t loc, tree type, tree op0, tree op1)
   1082 {
   1083   /* ??? maybe optimize based on knowledge of representation? */
   1084   comp_cat_tag tag = cat_tag_for (type);
   1085 
   1086   if (tag == cc_last && is_auto (type))
   1087     {
   1088       /* build_comparison_op is checking to see if we want to suggest changing
   1089 	 the op<=> return type from auto to a specific comparison category; any
   1090 	 category will do for now.  */
   1091       tag = cc_strong_ordering;
   1092       type = lookup_comparison_category (tag, tf_none);
   1093       if (type == error_mark_node)
   1094 	return error_mark_node;
   1095     }
   1096 
   1097   gcc_checking_assert (tag < cc_last);
   1098 
   1099   tree r;
   1100   bool scalar = SCALAR_TYPE_P (TREE_TYPE (op0));
   1101   if (scalar)
   1102     {
   1103       op0 = save_expr (op0);
   1104       op1 = save_expr (op1);
   1105     }
   1106 
   1107   tree gt = lookup_comparison_result (tag, type, 1);
   1108 
   1109   int flags = LOOKUP_NORMAL;
   1110   tsubst_flags_t complain = tf_none;
   1111   tree comp;
   1112 
   1113   if (tag == cc_partial_ordering)
   1114     {
   1115       /* op0 == op1 ? equivalent : op0 < op1 ? less :
   1116 	 op1 < op0 ? greater : unordered */
   1117       tree uo = lookup_comparison_result (tag, type, 3);
   1118       if (scalar)
   1119 	{
   1120 	  /* For scalars use the low level operations; using build_new_op causes
   1121 	     trouble with constexpr eval in the middle of genericize (100367).  */
   1122 	  comp = fold_build2 (LT_EXPR, boolean_type_node, op1, op0);
   1123 	  r = fold_build3 (COND_EXPR, type, comp, gt, uo);
   1124 	}
   1125       else
   1126 	{
   1127 	  comp = build_new_op (loc, LT_EXPR, flags, op1, op0, complain);
   1128 	  r = build_conditional_expr (loc, comp, gt, uo, complain);
   1129 	}
   1130     }
   1131   else
   1132     /* op0 == op1 ? equal : op0 < op1 ? less : greater */
   1133     r = gt;
   1134 
   1135   tree lt = lookup_comparison_result (tag, type, 2);
   1136   if (scalar)
   1137     {
   1138       comp = fold_build2 (LT_EXPR, boolean_type_node, op0, op1);
   1139       r = fold_build3 (COND_EXPR, type, comp, lt, r);
   1140     }
   1141   else
   1142     {
   1143       comp = build_new_op (loc, LT_EXPR, flags, op0, op1, complain);
   1144       r = build_conditional_expr (loc, comp, lt, r, complain);
   1145     }
   1146 
   1147   tree eq = lookup_comparison_result (tag, type, 0);
   1148   if (scalar)
   1149     {
   1150       comp = fold_build2 (EQ_EXPR, boolean_type_node, op0, op1);
   1151       r = fold_build3 (COND_EXPR, type, comp, eq, r);
   1152     }
   1153   else
   1154     {
   1155       comp = build_new_op (loc, EQ_EXPR, flags, op0, op1, complain);
   1156       r = build_conditional_expr (loc, comp, eq, r, complain);
   1157     }
   1158 
   1159   return r;
   1160 }
   1161 
   1162 /* Check that the signature of a defaulted comparison operator is
   1163    well-formed.  */
   1164 
   1165 static bool
   1166 early_check_defaulted_comparison (tree fn)
   1167 {
   1168   location_t loc = DECL_SOURCE_LOCATION (fn);
   1169   tree ctx;
   1170   if (DECL_CLASS_SCOPE_P (fn))
   1171     ctx = DECL_CONTEXT (fn);
   1172   else
   1173     ctx = DECL_FRIEND_CONTEXT (fn);
   1174   bool ok = true;
   1175 
   1176   if (cxx_dialect < cxx20)
   1177     {
   1178       error_at (loc, "defaulted %qD only available with %<-std=c++20%> or "
   1179 		     "%<-std=gnu++20%>", fn);
   1180       return false;
   1181     }
   1182 
   1183   if (!DECL_OVERLOADED_OPERATOR_IS (fn, SPACESHIP_EXPR)
   1184       && !same_type_p (TREE_TYPE (TREE_TYPE (fn)), boolean_type_node))
   1185     {
   1186       diagnostic_t kind = DK_UNSPECIFIED;
   1187       int opt = 0;
   1188       if (is_auto (TREE_TYPE (fn)))
   1189 	kind = DK_PEDWARN;
   1190       else
   1191 	kind = DK_ERROR;
   1192       emit_diagnostic (kind, loc, opt,
   1193 		       "defaulted %qD must return %<bool%>", fn);
   1194       if (kind == DK_ERROR)
   1195 	ok = false;
   1196     }
   1197 
   1198   bool mem = DECL_NONSTATIC_MEMBER_FUNCTION_P (fn);
   1199   if (mem && type_memfn_quals (TREE_TYPE (fn)) != TYPE_QUAL_CONST)
   1200     {
   1201       error_at (loc, "defaulted %qD must be %<const%>", fn);
   1202       ok = false;
   1203     }
   1204   if (mem && type_memfn_rqual (TREE_TYPE (fn)) == REF_QUAL_RVALUE)
   1205     {
   1206       error_at (loc, "defaulted %qD must not have %<&&%> ref-qualifier", fn);
   1207       ok = false;
   1208     }
   1209   tree parmnode = FUNCTION_FIRST_USER_PARMTYPE (fn);
   1210   bool saw_byval = false;
   1211   bool saw_byref = mem;
   1212   bool saw_bad = false;
   1213   for (; parmnode != void_list_node; parmnode = TREE_CHAIN (parmnode))
   1214     {
   1215       tree parmtype = TREE_VALUE (parmnode);
   1216       if (CLASS_TYPE_P (parmtype))
   1217 	saw_byval = true;
   1218       else if (TREE_CODE (parmtype) == REFERENCE_TYPE
   1219 	       && !TYPE_REF_IS_RVALUE (parmtype)
   1220 	       && TYPE_QUALS (TREE_TYPE (parmtype)) == TYPE_QUAL_CONST)
   1221 	{
   1222 	  saw_byref = true;
   1223 	  parmtype = TREE_TYPE (parmtype);
   1224 	}
   1225       else
   1226 	saw_bad = true;
   1227 
   1228       if (!saw_bad && !ctx)
   1229 	{
   1230 	  /* Defaulted outside the class body.  */
   1231 	  ctx = TYPE_MAIN_VARIANT (parmtype);
   1232 	  if (!is_friend (ctx, fn))
   1233 	    {
   1234 	      error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
   1235 	      inform (location_of (ctx), "declared here");
   1236 	      ok = false;
   1237 	    }
   1238 	}
   1239       else if (!same_type_ignoring_top_level_qualifiers_p (parmtype, ctx))
   1240 	saw_bad = true;
   1241     }
   1242 
   1243   if (saw_bad || (saw_byval && saw_byref))
   1244     {
   1245       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
   1246 	error_at (loc, "defaulted member %qD must have parameter type "
   1247 		  "%<const %T&%>", fn, ctx);
   1248       else if (saw_bad)
   1249 	error_at (loc, "defaulted %qD must have parameters of either type "
   1250 		  "%<const %T&%> or %qT", fn, ctx, ctx);
   1251       else
   1252 	error_at (loc, "defaulted %qD must have parameters of either type "
   1253 		  "%<const %T&%> or %qT, not both", fn, ctx, ctx);
   1254       ok = false;
   1255     }
   1256 
   1257   /* We still need to deduce deleted/constexpr/noexcept and maybe return. */
   1258   DECL_MAYBE_DELETED (fn) = ok;
   1259 
   1260   return ok;
   1261 }
   1262 
   1263 /* Subroutine of build_comparison_op.  Given the vec of memberwise
   1264    comparisons COMPS, calculate the overall comparison category for
   1265    operator<=>.  */
   1266 
   1267 static tree
   1268 common_comparison_type (vec<tree> &comps)
   1269 {
   1270   tree seen[cc_last] = {};
   1271 
   1272   for (unsigned i = 0; i < comps.length(); ++i)
   1273     {
   1274       tree comp = comps[i];
   1275       if (TREE_CODE (comp) == TREE_LIST)
   1276 	comp = TREE_VALUE (comp);
   1277       tree ctype = TREE_TYPE (comp);
   1278       comp_cat_tag tag = cat_tag_for (ctype);
   1279       /* build_comparison_op already checked this.  */
   1280       gcc_checking_assert (tag < cc_last);
   1281       seen[tag] = ctype;
   1282     }
   1283 
   1284   /* Otherwise, if at least one T i is std::partial_ordering, U is
   1285      std::partial_ordering.  */
   1286   if (tree t = seen[cc_partial_ordering]) return t;
   1287 
   1288   /* Otherwise, if at least one T i is std::weak_ordering, U is
   1289      std::weak_ordering.  */
   1290   if (tree t = seen[cc_weak_ordering]) return t;
   1291 
   1292   /* Otherwise, U is std::strong_ordering.  */
   1293   if (tree t = seen[cc_strong_ordering]) return t;
   1294   return lookup_comparison_category (cc_strong_ordering);
   1295 }
   1296 
   1297 /* Data structure for build_comparison_op.  */
   1298 
   1299 struct comp_info
   1300 {
   1301   tree fndecl;
   1302   location_t loc;
   1303   tsubst_flags_t complain;
   1304   tree_code code;
   1305   comp_cat_tag retcat;
   1306   bool first_time;
   1307   bool constexp;
   1308   bool was_constexp;
   1309   bool noex;
   1310 
   1311   comp_info (tree fndecl, tsubst_flags_t complain)
   1312     : fndecl (fndecl), complain (complain)
   1313   {
   1314     loc = DECL_SOURCE_LOCATION (fndecl);
   1315 
   1316     first_time = DECL_MAYBE_DELETED (fndecl);
   1317     DECL_MAYBE_DELETED (fndecl) = false;
   1318 
   1319     /* Do we want to try to set constexpr?  */
   1320     was_constexp = DECL_DECLARED_CONSTEXPR_P (fndecl);
   1321     constexp = first_time;
   1322     if (constexp)
   1323       /* Set this for var_in_constexpr_fn.  */
   1324       DECL_DECLARED_CONSTEXPR_P (fndecl) = true;
   1325 
   1326     /* Do we want to try to set noexcept?  */
   1327     noex = first_time;
   1328     if (noex)
   1329       {
   1330 	tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
   1331 	if (raises && !UNEVALUATED_NOEXCEPT_SPEC_P (raises))
   1332 	  /* There was an explicit exception-specification.  */
   1333 	  noex = false;
   1334       }
   1335   }
   1336 
   1337   /* EXPR is an expression built as part of the function body.
   1338      Adjust the properties appropriately.  */
   1339   void check (tree expr)
   1340   {
   1341     if (expr == error_mark_node)
   1342       DECL_DELETED_FN (fndecl) = true;
   1343     if ((constexp || was_constexp)
   1344 	&& !potential_rvalue_constant_expression (expr))
   1345       {
   1346 	if (was_constexp)
   1347 	  require_potential_rvalue_constant_expression (expr);
   1348 	else
   1349 	  constexp = false;
   1350       }
   1351     if (noex && !expr_noexcept_p (expr, tf_none))
   1352       noex = false;
   1353   }
   1354 
   1355   ~comp_info ()
   1356   {
   1357     if (first_time)
   1358       {
   1359 	DECL_DECLARED_CONSTEXPR_P (fndecl) = constexp || was_constexp;
   1360 	tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
   1361 	if (!raises || UNEVALUATED_NOEXCEPT_SPEC_P (raises))
   1362 	  {
   1363 	    raises = noex ? noexcept_true_spec : noexcept_false_spec;
   1364 	    TREE_TYPE (fndecl) = build_exception_variant (TREE_TYPE (fndecl),
   1365 							  raises);
   1366 	  }
   1367       }
   1368   }
   1369 };
   1370 
   1371 /* Subroutine of build_comparison_op, to compare a single subobject.  */
   1372 
   1373 static tree
   1374 do_one_comp (location_t loc, const comp_info &info, tree sub, tree lhs, tree rhs)
   1375 {
   1376   const tree_code code = info.code;
   1377   const tree fndecl = info.fndecl;
   1378   const comp_cat_tag retcat = info.retcat;
   1379   const tsubst_flags_t complain = info.complain;
   1380 
   1381   tree overload = NULL_TREE;
   1382   int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
   1383   /* If we have an explicit comparison category return type we can fall back
   1384      to </=, so don't give an error yet if <=> lookup fails.  */
   1385   bool tentative = retcat != cc_last;
   1386   tree comp = build_new_op (loc, code, flags, lhs, rhs,
   1387 			    NULL_TREE, NULL_TREE, &overload,
   1388 			    tentative ? tf_none : complain);
   1389 
   1390   if (code != SPACESHIP_EXPR)
   1391     return comp;
   1392 
   1393   tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
   1394 
   1395   if (comp == error_mark_node)
   1396     {
   1397       if (overload == NULL_TREE && (tentative || complain))
   1398 	{
   1399 	  /* No viable <=>, try using op< and op==.  */
   1400 	  tree lteq = genericize_spaceship (loc, rettype, lhs, rhs);
   1401 	  if (lteq != error_mark_node)
   1402 	    {
   1403 	      /* We found usable < and ==.  */
   1404 	      if (retcat != cc_last)
   1405 		/* Return type is a comparison category, use them.  */
   1406 		comp = lteq;
   1407 	      else if (complain & tf_error)
   1408 		/* Return type is auto, suggest changing it.  */
   1409 		inform (info.loc, "changing the return type from %qs "
   1410 			"to a comparison category type will allow the "
   1411 			"comparison to use %qs and %qs", "auto",
   1412 			"operator<", "operator==");
   1413 	    }
   1414 	  else if (tentative && complain)
   1415 	    /* No usable < and ==, give an error for op<=>.  */
   1416 	    build_new_op (loc, code, flags, lhs, rhs, complain);
   1417 	}
   1418       if (comp == error_mark_node)
   1419 	return error_mark_node;
   1420     }
   1421 
   1422   if (FNDECL_USED_AUTO (fndecl)
   1423       && cat_tag_for (TREE_TYPE (comp)) == cc_last)
   1424     {
   1425       /* The operator function is defined as deleted if ... Ri is not a
   1426 	 comparison category type.  */
   1427       if (complain & tf_error)
   1428 	inform (loc,
   1429 		"three-way comparison of %qD has type %qT, not a "
   1430 		"comparison category type", sub, TREE_TYPE (comp));
   1431       return error_mark_node;
   1432     }
   1433   else if (!FNDECL_USED_AUTO (fndecl)
   1434 	   && !can_convert (rettype, TREE_TYPE (comp), complain))
   1435     {
   1436       if (complain & tf_error)
   1437 	error_at (loc,
   1438 		  "three-way comparison of %qD has type %qT, which "
   1439 		  "does not convert to %qT",
   1440 		  sub, TREE_TYPE (comp), rettype);
   1441       return error_mark_node;
   1442     }
   1443 
   1444   return comp;
   1445 }
   1446 
   1447 /* Build up the definition of a defaulted comparison operator.  Unlike other
   1448    defaulted functions that use synthesized_method_walk to determine whether
   1449    the function is e.g. deleted, for comparisons we use the same code.  We try
   1450    to use synthesize_method at the earliest opportunity and bail out if the
   1451    function ends up being deleted.  */
   1452 
   1453 void
   1454 build_comparison_op (tree fndecl, bool defining, tsubst_flags_t complain)
   1455 {
   1456   comp_info info (fndecl, complain);
   1457 
   1458   if (!defining && !(complain & tf_error) && !DECL_MAYBE_DELETED (fndecl))
   1459     return;
   1460 
   1461   int flags = LOOKUP_NORMAL;
   1462   const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (DECL_NAME (fndecl));
   1463   tree_code code = info.code = op->tree_code;
   1464 
   1465   tree lhs = DECL_ARGUMENTS (fndecl);
   1466   tree rhs = DECL_CHAIN (lhs);
   1467   if (is_this_parameter (lhs))
   1468     lhs = cp_build_fold_indirect_ref (lhs);
   1469   else
   1470     lhs = convert_from_reference (lhs);
   1471   rhs = convert_from_reference (rhs);
   1472   tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
   1473   gcc_assert (!defining || COMPLETE_TYPE_P (ctype));
   1474 
   1475   iloc_sentinel ils (info.loc);
   1476 
   1477   /* A defaulted comparison operator function for class C is defined as
   1478      deleted if ... C has variant members.  */
   1479   if (TREE_CODE (ctype) == UNION_TYPE
   1480       && next_initializable_field (TYPE_FIELDS (ctype)))
   1481     {
   1482       if (complain & tf_error)
   1483 	inform (info.loc, "cannot default compare union %qT", ctype);
   1484       DECL_DELETED_FN (fndecl) = true;
   1485       return;
   1486     }
   1487 
   1488   tree compound_stmt = NULL_TREE;
   1489   if (defining)
   1490     compound_stmt = begin_compound_stmt (0);
   1491   else
   1492     ++cp_unevaluated_operand;
   1493 
   1494   tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
   1495   if (code != SPACESHIP_EXPR && is_auto (rettype))
   1496     {
   1497       rettype = boolean_type_node;
   1498       apply_deduced_return_type (fndecl, rettype);
   1499     }
   1500 
   1501   if (code == EQ_EXPR || code == SPACESHIP_EXPR)
   1502     {
   1503       comp_cat_tag &retcat = (info.retcat = cc_last);
   1504       if (code == SPACESHIP_EXPR && !FNDECL_USED_AUTO (fndecl))
   1505 	retcat = cat_tag_for (rettype);
   1506 
   1507       bool bad = false;
   1508       auto_vec<tree> comps;
   1509 
   1510       /* Compare the base subobjects.  We handle them this way, rather than in
   1511 	 the field loop below, because maybe_instantiate_noexcept might bring
   1512 	 us here before we've built the base fields.  */
   1513       for (tree base_binfo : BINFO_BASE_BINFOS (TYPE_BINFO (ctype)))
   1514 	{
   1515 	  tree lhs_base
   1516 	    = build_base_path (PLUS_EXPR, lhs, base_binfo, 0, complain);
   1517 	  tree rhs_base
   1518 	    = build_base_path (PLUS_EXPR, rhs, base_binfo, 0, complain);
   1519 
   1520 	  location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (ctype));
   1521 	  tree comp = do_one_comp (loc, info, BINFO_TYPE (base_binfo),
   1522 				   lhs_base, rhs_base);
   1523 	  if (comp == error_mark_node)
   1524 	    {
   1525 	      bad = true;
   1526 	      continue;
   1527 	    }
   1528 
   1529 	  comps.safe_push (comp);
   1530 	}
   1531 
   1532       /* Now compare the field subobjects.  */
   1533       for (tree field = next_initializable_field (TYPE_FIELDS (ctype));
   1534 	   field;
   1535 	   field = next_initializable_field (DECL_CHAIN (field)))
   1536 	{
   1537 	  if (DECL_VIRTUAL_P (field) || DECL_FIELD_IS_BASE (field))
   1538 	    /* We ignore the vptr, and we already handled bases.  */
   1539 	    continue;
   1540 
   1541 	  tree expr_type = TREE_TYPE (field);
   1542 
   1543 	  location_t field_loc = DECL_SOURCE_LOCATION (field);
   1544 
   1545 	  /* A defaulted comparison operator function for class C is defined as
   1546 	     deleted if any non-static data member of C is of reference type or
   1547 	     C has variant members.  */
   1548 	  if (TREE_CODE (expr_type) == REFERENCE_TYPE)
   1549 	    {
   1550 	      if (complain & tf_error)
   1551 		inform (field_loc, "cannot default compare "
   1552 			"reference member %qD", field);
   1553 	      bad = true;
   1554 	      continue;
   1555 	    }
   1556 	  else if (ANON_UNION_TYPE_P (expr_type)
   1557 		   && next_initializable_field (TYPE_FIELDS (expr_type)))
   1558 	    {
   1559 	      if (complain & tf_error)
   1560 		inform (field_loc, "cannot default compare "
   1561 			"anonymous union member");
   1562 	      bad = true;
   1563 	      continue;
   1564 	    }
   1565 
   1566 	  tree lhs_mem = build3_loc (field_loc, COMPONENT_REF, expr_type, lhs,
   1567 				     field, NULL_TREE);
   1568 	  tree rhs_mem = build3_loc (field_loc, COMPONENT_REF, expr_type, rhs,
   1569 				     field, NULL_TREE);
   1570 	  tree loop_indexes = NULL_TREE;
   1571 	  while (TREE_CODE (expr_type) == ARRAY_TYPE)
   1572 	    {
   1573 	      /* Flexible array member.  */
   1574 	      if (TYPE_DOMAIN (expr_type) == NULL_TREE
   1575 		  || TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type)) == NULL_TREE)
   1576 		{
   1577 		  if (complain & tf_error)
   1578 		    inform (field_loc, "cannot default compare "
   1579 				       "flexible array member");
   1580 		  bad = true;
   1581 		  break;
   1582 		}
   1583 	      tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type));
   1584 	      /* [0] array.  No subobjects to compare, just skip it.  */
   1585 	      if (integer_all_onesp (maxval))
   1586 		break;
   1587 	      tree idx;
   1588 	      /* [1] array, no loop needed, just add [0] ARRAY_REF.
   1589 		 Similarly if !defining.  */
   1590 	      if (integer_zerop (maxval) || !defining)
   1591 		idx = size_zero_node;
   1592 	      /* Some other array, will need runtime loop.  */
   1593 	      else
   1594 		{
   1595 		  idx = force_target_expr (sizetype, maxval, complain);
   1596 		  loop_indexes = tree_cons (idx, NULL_TREE, loop_indexes);
   1597 		}
   1598 	      expr_type = TREE_TYPE (expr_type);
   1599 	      lhs_mem = build4_loc (field_loc, ARRAY_REF, expr_type, lhs_mem,
   1600 				    idx, NULL_TREE, NULL_TREE);
   1601 	      rhs_mem = build4_loc (field_loc, ARRAY_REF, expr_type, rhs_mem,
   1602 				    idx, NULL_TREE, NULL_TREE);
   1603 	    }
   1604 	  if (TREE_CODE (expr_type) == ARRAY_TYPE)
   1605 	    continue;
   1606 
   1607 	  tree comp = do_one_comp (field_loc, info, field, lhs_mem, rhs_mem);
   1608 	  if (comp == error_mark_node)
   1609 	    {
   1610 	      bad = true;
   1611 	      continue;
   1612 	    }
   1613 
   1614 	  /* Most of the time, comp is the expression that should be evaluated
   1615 	     to compare the two members.  If the expression needs to be
   1616 	     evaluated more than once in a loop, it will be a TREE_LIST
   1617 	     instead, whose TREE_VALUE is the expression for one array element,
   1618 	     TREE_PURPOSE is innermost iterator temporary and if the array
   1619 	     is multidimensional, TREE_CHAIN will contain another TREE_LIST
   1620 	     with second innermost iterator in its TREE_PURPOSE and so on.  */
   1621 	  if (loop_indexes)
   1622 	    {
   1623 	      TREE_VALUE (loop_indexes) = comp;
   1624 	      comp = loop_indexes;
   1625 	    }
   1626 	  comps.safe_push (comp);
   1627 	}
   1628       if (code == SPACESHIP_EXPR && is_auto (rettype))
   1629 	{
   1630 	  rettype = common_comparison_type (comps);
   1631 	  apply_deduced_return_type (fndecl, rettype);
   1632 	}
   1633       if (bad)
   1634 	{
   1635 	  DECL_DELETED_FN (fndecl) = true;
   1636 	  goto out;
   1637 	}
   1638       for (unsigned i = 0; i < comps.length(); ++i)
   1639 	{
   1640 	  tree comp = comps[i];
   1641 	  tree eq, retval = NULL_TREE, if_ = NULL_TREE;
   1642 	  tree loop_indexes = NULL_TREE;
   1643 	  if (defining)
   1644 	    {
   1645 	      if (TREE_CODE (comp) == TREE_LIST)
   1646 		{
   1647 		  loop_indexes = comp;
   1648 		  comp = TREE_VALUE (comp);
   1649 		  loop_indexes = nreverse (loop_indexes);
   1650 		  for (tree loop_index = loop_indexes; loop_index;
   1651 		       loop_index = TREE_CHAIN (loop_index))
   1652 		    {
   1653 		      tree for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
   1654 		      tree idx = TREE_PURPOSE (loop_index);
   1655 		      tree maxval = TARGET_EXPR_INITIAL (idx);
   1656 		      TARGET_EXPR_INITIAL (idx) = size_zero_node;
   1657 		      add_stmt (idx);
   1658 		      finish_init_stmt (for_stmt);
   1659 		      finish_for_cond (build2 (LE_EXPR, boolean_type_node, idx,
   1660 					       maxval), for_stmt, false, 0);
   1661 		      finish_for_expr (cp_build_unary_op (PREINCREMENT_EXPR,
   1662 							  TARGET_EXPR_SLOT (idx),
   1663 							  false, complain),
   1664 							  for_stmt);
   1665 		      /* Store in TREE_VALUE the for_stmt tree, so that we can
   1666 			 later on call finish_for_stmt on it (in the reverse
   1667 			 order).  */
   1668 		      TREE_VALUE (loop_index) = for_stmt;
   1669 		    }
   1670 		  loop_indexes = nreverse (loop_indexes);
   1671 		}
   1672 	      if_ = begin_if_stmt ();
   1673 	    }
   1674 	  /* Spaceship is specified to use !=, but for the comparison category
   1675 	     types, != is equivalent to !(==), so let's use == directly.  */
   1676 	  if (code == EQ_EXPR)
   1677 	    {
   1678 	      /* if (x==y); else return false; */
   1679 	      eq = comp;
   1680 	      retval = boolean_false_node;
   1681 	    }
   1682 	  else
   1683 	    {
   1684 	      /* if (auto v = x<=>y, v == 0); else return v; */
   1685 	      if (TREE_CODE (comp) == SPACESHIP_EXPR)
   1686 		TREE_TYPE (comp) = rettype;
   1687 	      else
   1688 		comp = build_static_cast (input_location, rettype, comp,
   1689 					  complain);
   1690 	      info.check (comp);
   1691 	      if (defining)
   1692 		{
   1693 		  tree var = create_temporary_var (rettype);
   1694 		  pushdecl (var);
   1695 		  cp_finish_decl (var, comp, false, NULL_TREE, flags);
   1696 		  comp = retval = var;
   1697 		}
   1698 	      eq = build_new_op (info.loc, EQ_EXPR, flags, comp,
   1699 				 integer_zero_node, NULL_TREE, NULL_TREE,
   1700 				 NULL, complain);
   1701 	    }
   1702 	  tree ceq = contextual_conv_bool (eq, complain);
   1703 	  info.check (ceq);
   1704 	  if (defining)
   1705 	    {
   1706 	      finish_if_stmt_cond (ceq, if_);
   1707 	      finish_then_clause (if_);
   1708 	      begin_else_clause (if_);
   1709 	      finish_return_stmt (retval);
   1710 	      finish_else_clause (if_);
   1711 	      finish_if_stmt (if_);
   1712 	      for (tree loop_index = loop_indexes; loop_index;
   1713 		   loop_index = TREE_CHAIN (loop_index))
   1714 		finish_for_stmt (TREE_VALUE (loop_index));
   1715 	    }
   1716 	}
   1717       if (defining)
   1718 	{
   1719 	  tree val;
   1720 	  if (code == EQ_EXPR)
   1721 	    val = boolean_true_node;
   1722 	  else
   1723 	    {
   1724 	      tree seql = lookup_comparison_result (cc_strong_ordering,
   1725 						    "equal", complain);
   1726 	      val = build_static_cast (input_location, rettype, seql,
   1727 				       complain);
   1728 	    }
   1729 	  finish_return_stmt (val);
   1730 	}
   1731     }
   1732   else if (code == NE_EXPR)
   1733     {
   1734       tree comp = build_new_op (info.loc, EQ_EXPR, flags, lhs, rhs,
   1735 				NULL_TREE, NULL_TREE, NULL, complain);
   1736       comp = contextual_conv_bool (comp, complain);
   1737       info.check (comp);
   1738       if (defining)
   1739 	{
   1740 	  tree neg = build1 (TRUTH_NOT_EXPR, boolean_type_node, comp);
   1741 	  finish_return_stmt (neg);
   1742 	}
   1743     }
   1744   else
   1745     {
   1746       tree comp = build_new_op (info.loc, SPACESHIP_EXPR, flags, lhs, rhs,
   1747 				NULL_TREE, NULL_TREE, NULL, complain);
   1748       tree comp2 = build_new_op (info.loc, code, flags, comp, integer_zero_node,
   1749 				 NULL_TREE, NULL_TREE, NULL, complain);
   1750       info.check (comp2);
   1751       if (defining)
   1752 	finish_return_stmt (comp2);
   1753     }
   1754 
   1755  out:
   1756   if (defining)
   1757     finish_compound_stmt (compound_stmt);
   1758   else
   1759     --cp_unevaluated_operand;
   1760 }
   1761 
   1762 /* True iff DECL is an implicitly-declared special member function with no real
   1763    source location, so we can use its DECL_SOURCE_LOCATION to remember where we
   1764    triggered its synthesis.  */
   1765 
   1766 bool
   1767 decl_remember_implicit_trigger_p (tree decl)
   1768 {
   1769   if (!DECL_ARTIFICIAL (decl))
   1770     return false;
   1771   special_function_kind sfk = special_function_p (decl);
   1772   /* Inherited constructors have the location of their using-declaration, and
   1773      operator== has the location of the corresponding operator<=>.  */
   1774   return (sfk != sfk_inheriting_constructor
   1775 	  && sfk != sfk_comparison);
   1776 }
   1777 
   1778 /* Synthesize FNDECL, a non-static member function.   */
   1779 
   1780 void
   1781 synthesize_method (tree fndecl)
   1782 {
   1783   bool nested = (current_function_decl != NULL_TREE);
   1784   tree context = decl_function_context (fndecl);
   1785   bool need_body = true;
   1786   tree stmt;
   1787   location_t save_input_location = input_location;
   1788   int error_count = errorcount;
   1789   int warning_count = warningcount + werrorcount;
   1790   special_function_kind sfk = special_function_p (fndecl);
   1791 
   1792   /* Reset the source location, we might have been previously
   1793      deferred, and thus have saved where we were first needed.  */
   1794   if (decl_remember_implicit_trigger_p (fndecl))
   1795     DECL_SOURCE_LOCATION (fndecl)
   1796       = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
   1797 
   1798   /* If we've been asked to synthesize a clone, just synthesize the
   1799      cloned function instead.  Doing so will automatically fill in the
   1800      body for the clone.  */
   1801   if (DECL_CLONED_FUNCTION_P (fndecl))
   1802     fndecl = DECL_CLONED_FUNCTION (fndecl);
   1803 
   1804   /* We may be in the middle of deferred access check.  Disable
   1805      it now.  */
   1806   push_deferring_access_checks (dk_no_deferred);
   1807 
   1808   if (! context)
   1809     push_to_top_level ();
   1810   else if (nested)
   1811     push_function_context ();
   1812 
   1813   input_location = DECL_SOURCE_LOCATION (fndecl);
   1814 
   1815   start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
   1816   stmt = begin_function_body ();
   1817 
   1818   if (DECL_ASSIGNMENT_OPERATOR_P (fndecl)
   1819       && DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR))
   1820     {
   1821       do_build_copy_assign (fndecl);
   1822       need_body = false;
   1823     }
   1824   else if (DECL_CONSTRUCTOR_P (fndecl))
   1825     {
   1826       tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
   1827       if (arg_chain != void_list_node)
   1828 	do_build_copy_constructor (fndecl);
   1829       else
   1830 	finish_mem_initializers (NULL_TREE);
   1831     }
   1832   else if (sfk == sfk_comparison)
   1833     {
   1834       /* Pass tf_none so the function is just deleted if there's a problem.  */
   1835       build_comparison_op (fndecl, true, tf_none);
   1836       need_body = false;
   1837     }
   1838 
   1839   /* If we haven't yet generated the body of the function, just
   1840      generate an empty compound statement.  */
   1841   if (need_body)
   1842     {
   1843       tree compound_stmt;
   1844       compound_stmt = begin_compound_stmt (BCS_FN_BODY);
   1845       finish_compound_stmt (compound_stmt);
   1846     }
   1847 
   1848   finish_function_body (stmt);
   1849   finish_function (/*inline_p=*/false);
   1850 
   1851   if (!DECL_DELETED_FN (fndecl))
   1852     expand_or_defer_fn (fndecl);
   1853 
   1854   input_location = save_input_location;
   1855 
   1856   if (! context)
   1857     pop_from_top_level ();
   1858   else if (nested)
   1859     pop_function_context ();
   1860 
   1861   pop_deferring_access_checks ();
   1862 
   1863   if (error_count != errorcount || warning_count != warningcount + werrorcount)
   1864     if (DECL_ARTIFICIAL (fndecl))
   1865       inform (input_location, "synthesized method %qD first required here",
   1866 	      fndecl);
   1867 }
   1868 
   1869 /* Like synthesize_method, but don't actually synthesize defaulted comparison
   1870    methods if their class is still incomplete.  Just deduce the return
   1871    type in that case.  */
   1872 
   1873 void
   1874 maybe_synthesize_method (tree fndecl)
   1875 {
   1876   if (special_function_p (fndecl) == sfk_comparison)
   1877     {
   1878       tree lhs = DECL_ARGUMENTS (fndecl);
   1879       if (is_this_parameter (lhs))
   1880 	lhs = cp_build_fold_indirect_ref (lhs);
   1881       else
   1882 	lhs = convert_from_reference (lhs);
   1883       tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
   1884       if (!COMPLETE_TYPE_P (ctype))
   1885 	{
   1886 	  push_deferring_access_checks (dk_no_deferred);
   1887 	  build_comparison_op (fndecl, false, tf_none);
   1888 	  pop_deferring_access_checks ();
   1889 	  return;
   1890 	}
   1891     }
   1892   return synthesize_method (fndecl);
   1893 }
   1894 
   1895 /* Build a reference to type TYPE with cv-quals QUALS, which is an
   1896    rvalue if RVALUE is true.  */
   1897 
   1898 static tree
   1899 build_stub_type (tree type, int quals, bool rvalue)
   1900 {
   1901   tree argtype = cp_build_qualified_type (type, quals);
   1902   return cp_build_reference_type (argtype, rvalue);
   1903 }
   1904 
   1905 /* Build a dummy glvalue from dereferencing a dummy reference of type
   1906    REFTYPE.  */
   1907 
   1908 tree
   1909 build_stub_object (tree reftype)
   1910 {
   1911   if (!TYPE_REF_P (reftype))
   1912     reftype = cp_build_reference_type (reftype, /*rval*/true);
   1913   tree stub = build1 (CONVERT_EXPR, reftype, integer_one_node);
   1914   return convert_from_reference (stub);
   1915 }
   1916 
   1917 /* Determine which function will be called when looking up NAME in TYPE,
   1918    called with a single ARGTYPE argument, or no argument if ARGTYPE is
   1919    null.  FLAGS and COMPLAIN are as for build_new_method_call.
   1920 
   1921    Returns a FUNCTION_DECL if all is well.
   1922    Returns NULL_TREE if overload resolution failed.
   1923    Returns error_mark_node if the chosen function cannot be called.  */
   1924 
   1925 static tree
   1926 locate_fn_flags (tree type, tree name, tree argtype, int flags,
   1927 		 tsubst_flags_t complain)
   1928 {
   1929   tree ob, fn, fns, binfo, rval;
   1930 
   1931   if (TYPE_P (type))
   1932     binfo = TYPE_BINFO (type);
   1933   else
   1934     {
   1935       binfo = type;
   1936       type = BINFO_TYPE (binfo);
   1937     }
   1938 
   1939   ob = build_stub_object (cp_build_reference_type (type, false));
   1940   releasing_vec args;
   1941   if (argtype)
   1942     {
   1943       if (TREE_CODE (argtype) == TREE_LIST)
   1944 	{
   1945 	  for (tree elt = argtype; elt && elt != void_list_node;
   1946 	       elt = TREE_CHAIN (elt))
   1947 	    {
   1948 	      tree type = TREE_VALUE (elt);
   1949 	      tree arg = build_stub_object (type);
   1950 	      vec_safe_push (args, arg);
   1951 	    }
   1952 	}
   1953       else
   1954 	{
   1955 	  tree arg = build_stub_object (argtype);
   1956 	  args->quick_push (arg);
   1957 	}
   1958     }
   1959 
   1960   fns = lookup_fnfields (binfo, name, 0, complain);
   1961   rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);
   1962 
   1963   if (fn && rval == error_mark_node)
   1964     return rval;
   1965   else
   1966     return fn;
   1967 }
   1968 
   1969 /* Locate the dtor of TYPE.  */
   1970 
   1971 tree
   1972 get_dtor (tree type, tsubst_flags_t complain)
   1973 {
   1974   tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
   1975 			     LOOKUP_NORMAL, complain);
   1976   if (fn == error_mark_node)
   1977     return NULL_TREE;
   1978   return fn;
   1979 }
   1980 
   1981 /* Locate the default ctor of TYPE.  */
   1982 
   1983 tree
   1984 locate_ctor (tree type)
   1985 {
   1986   tree fn;
   1987 
   1988   push_deferring_access_checks (dk_no_check);
   1989   fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
   1990 			LOOKUP_SPECULATIVE, tf_none);
   1991   pop_deferring_access_checks ();
   1992   if (fn == error_mark_node)
   1993     return NULL_TREE;
   1994   return fn;
   1995 }
   1996 
   1997 /* Likewise, but give any appropriate errors.  */
   1998 
   1999 tree
   2000 get_default_ctor (tree type)
   2001 {
   2002   tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
   2003 			     LOOKUP_NORMAL, tf_warning_or_error);
   2004   if (fn == error_mark_node)
   2005     return NULL_TREE;
   2006   return fn;
   2007 }
   2008 
   2009 /* Locate the copy ctor of TYPE.  */
   2010 
   2011 tree
   2012 get_copy_ctor (tree type, tsubst_flags_t complain)
   2013 {
   2014   int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
   2015 	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
   2016   tree argtype = build_stub_type (type, quals, false);
   2017   tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
   2018 			     LOOKUP_NORMAL, complain);
   2019   if (fn == error_mark_node)
   2020     return NULL_TREE;
   2021   return fn;
   2022 }
   2023 
   2024 /* Locate the copy assignment operator of TYPE.  */
   2025 
   2026 tree
   2027 get_copy_assign (tree type)
   2028 {
   2029   int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
   2030 	       ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
   2031   tree argtype = build_stub_type (type, quals, false);
   2032   tree fn = locate_fn_flags (type, assign_op_identifier, argtype,
   2033 			     LOOKUP_NORMAL, tf_warning_or_error);
   2034   if (fn == error_mark_node)
   2035     return NULL_TREE;
   2036   return fn;
   2037 }
   2038 
   2039 /* walk_tree helper function for is_trivially_xible.  If *TP is a call,
   2040    return it if it calls something other than a trivial special member
   2041    function.  */
   2042 
   2043 static tree
   2044 check_nontriv (tree *tp, int *, void *)
   2045 {
   2046   tree fn = cp_get_callee (*tp);
   2047   if (fn == NULL_TREE)
   2048     return NULL_TREE;
   2049 
   2050   if (TREE_CODE (fn) == ADDR_EXPR)
   2051     fn = TREE_OPERAND (fn, 0);
   2052 
   2053   if (TREE_CODE (fn) != FUNCTION_DECL
   2054       || !trivial_fn_p (fn))
   2055     return fn;
   2056   return NULL_TREE;
   2057 }
   2058 
   2059 /* Return declval<T>() = declval<U>() treated as an unevaluated operand.  */
   2060 
   2061 static tree
   2062 assignable_expr (tree to, tree from)
   2063 {
   2064   cp_unevaluated cp_uneval_guard;
   2065   to = build_stub_object (to);
   2066   from = build_stub_object (from);
   2067   tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
   2068   return r;
   2069 }
   2070 
   2071 /* The predicate condition for a template specialization
   2072    is_constructible<T, Args...> shall be satisfied if and only if the
   2073    following variable definition would be well-formed for some invented
   2074    variable t: T t(create<Args>()...);
   2075 
   2076    Return something equivalent in well-formedness and triviality.  */
   2077 
   2078 static tree
   2079 constructible_expr (tree to, tree from)
   2080 {
   2081   tree expr;
   2082   cp_unevaluated cp_uneval_guard;
   2083   if (CLASS_TYPE_P (to))
   2084     {
   2085       tree ctype = to;
   2086       vec<tree, va_gc> *args = NULL;
   2087       if (!TYPE_REF_P (to))
   2088 	to = cp_build_reference_type (to, /*rval*/false);
   2089       tree ob = build_stub_object (to);
   2090       for (; from; from = TREE_CHAIN (from))
   2091 	vec_safe_push (args, build_stub_object (TREE_VALUE (from)));
   2092       expr = build_special_member_call (ob, complete_ctor_identifier, &args,
   2093 					ctype, LOOKUP_NORMAL, tf_none);
   2094       if (expr == error_mark_node)
   2095 	return error_mark_node;
   2096       /* The current state of the standard vis-a-vis LWG 2116 is that
   2097 	 is_*constructible involves destruction as well.  */
   2098       if (type_build_dtor_call (ctype))
   2099 	{
   2100 	  tree dtor = build_special_member_call (ob, complete_dtor_identifier,
   2101 						 NULL, ctype, LOOKUP_NORMAL,
   2102 						 tf_none);
   2103 	  if (dtor == error_mark_node)
   2104 	    return error_mark_node;
   2105 	  if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (ctype))
   2106 	    expr = build2 (COMPOUND_EXPR, void_type_node, expr, dtor);
   2107 	}
   2108     }
   2109   else
   2110     {
   2111       if (from == NULL_TREE)
   2112 	return build_value_init (strip_array_types (to), tf_none);
   2113       const int len = list_length (from);
   2114       if (len > 1)
   2115 	{
   2116 	  if (cxx_dialect < cxx20)
   2117 	    /* Too many initializers.  */
   2118 	    return error_mark_node;
   2119 
   2120 	  /* In C++20 this is well-formed:
   2121 	       using T = int[2];
   2122 	       T t(1, 2);
   2123 	     which means that std::is_constructible_v<int[2], int, int>
   2124 	     should be true.  */
   2125 	  vec<constructor_elt, va_gc> *v;
   2126 	  vec_alloc (v, len);
   2127 	  for (tree t = from; t; t = TREE_CHAIN (t))
   2128 	    {
   2129 	      tree stub = build_stub_object (TREE_VALUE (t));
   2130 	      constructor_elt elt = { NULL_TREE, stub };
   2131 	      v->quick_push (elt);
   2132 	    }
   2133 	  from = build_constructor (init_list_type_node, v);
   2134 	  CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
   2135 	  CONSTRUCTOR_IS_PAREN_INIT (from) = true;
   2136 	}
   2137       else
   2138 	from = build_stub_object (TREE_VALUE (from));
   2139       expr = perform_direct_initialization_if_possible (to, from,
   2140 							/*cast*/false,
   2141 							tf_none);
   2142       /* If t(e) didn't work, maybe t{e} will.  */
   2143       if (expr == NULL_TREE
   2144 	  && len == 1
   2145 	  && cxx_dialect >= cxx20)
   2146 	{
   2147 	  from = build_constructor_single (init_list_type_node, NULL_TREE,
   2148 					   from);
   2149 	  CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
   2150 	  CONSTRUCTOR_IS_PAREN_INIT (from) = true;
   2151 	  expr = perform_direct_initialization_if_possible (to, from,
   2152 							    /*cast*/false,
   2153 							    tf_none);
   2154 	}
   2155     }
   2156   return expr;
   2157 }
   2158 
   2159 /* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or
   2160    constructible (otherwise) from FROM, which is a single type for
   2161    assignment or a list of types for construction.  */
   2162 
   2163 static tree
   2164 is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
   2165 {
   2166   to = complete_type (to);
   2167   deferring_access_check_sentinel acs (dk_no_deferred);
   2168   if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to)
   2169       || (from && FUNC_OR_METHOD_TYPE_P (from)
   2170 	  && (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from))))
   2171     return error_mark_node;
   2172   tree expr;
   2173   if (code == MODIFY_EXPR)
   2174     expr = assignable_expr (to, from);
   2175   else if (trivial && from && TREE_CHAIN (from)
   2176 	   && cxx_dialect < cxx20)
   2177     return error_mark_node; // only 0- and 1-argument ctors can be trivial
   2178 			    // before C++20 aggregate paren init
   2179   else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
   2180     return error_mark_node; // can't construct an array of unknown bound
   2181   else
   2182     expr = constructible_expr (to, from);
   2183   return expr;
   2184 }
   2185 
   2186 /* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or
   2187    constructible (otherwise) from FROM, which is a single type for
   2188    assignment or a list of types for construction.  */
   2189 
   2190 bool
   2191 is_trivially_xible (enum tree_code code, tree to, tree from)
   2192 {
   2193   tree expr = is_xible_helper (code, to, from, /*trivial*/true);
   2194   if (expr == NULL_TREE || expr == error_mark_node)
   2195     return false;
   2196   tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
   2197   return !nt;
   2198 }
   2199 
   2200 /* Returns true iff TO is nothrow assignable (if CODE is MODIFY_EXPR) or
   2201    constructible (otherwise) from FROM, which is a single type for
   2202    assignment or a list of types for construction.  */
   2203 
   2204 bool
   2205 is_nothrow_xible (enum tree_code code, tree to, tree from)
   2206 {
   2207   tree expr = is_xible_helper (code, to, from, /*trivial*/false);
   2208   if (expr == NULL_TREE || expr == error_mark_node)
   2209     return false;
   2210   return expr_noexcept_p (expr, tf_none);
   2211 }
   2212 
   2213 /* Returns true iff TO is assignable (if CODE is MODIFY_EXPR) or
   2214    constructible (otherwise) from FROM, which is a single type for
   2215    assignment or a list of types for construction.  */
   2216 
   2217 bool
   2218 is_xible (enum tree_code code, tree to, tree from)
   2219 {
   2220   tree expr = is_xible_helper (code, to, from, /*trivial*/false);
   2221   if (expr == error_mark_node)
   2222     return false;
   2223   return !!expr;
   2224 }
   2225 
   2226 /* Categorize various special_function_kinds.  */
   2227 #define SFK_CTOR_P(sfk) \
   2228   ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
   2229 #define SFK_DTOR_P(sfk) \
   2230   ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
   2231 #define SFK_ASSIGN_P(sfk) \
   2232   ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
   2233 #define SFK_COPY_P(sfk) \
   2234   ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
   2235 #define SFK_MOVE_P(sfk) \
   2236   ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)
   2237 
   2238 /* Subroutine of synthesized_method_walk.  Update SPEC_P, TRIVIAL_P and
   2239    DELETED_P or give an error message MSG with argument ARG.  */
   2240 
   2241 static void
   2242 process_subob_fn (tree fn, special_function_kind sfk, tree *spec_p,
   2243 		  bool *trivial_p, bool *deleted_p, bool *constexpr_p,
   2244 		  bool diag, tree arg, bool dtor_from_ctor = false)
   2245 {
   2246   if (!fn || fn == error_mark_node)
   2247     {
   2248       if (deleted_p)
   2249 	*deleted_p = true;
   2250       return;
   2251     }
   2252 
   2253   if (spec_p)
   2254     {
   2255       if (!maybe_instantiate_noexcept (fn))
   2256 	*spec_p = error_mark_node;
   2257       else
   2258 	{
   2259 	  tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
   2260 	  *spec_p = merge_exception_specifiers (*spec_p, raises);
   2261 	}
   2262     }
   2263 
   2264   if (!trivial_fn_p (fn) && !dtor_from_ctor)
   2265     {
   2266       if (trivial_p)
   2267 	*trivial_p = false;
   2268       if (TREE_CODE (arg) == FIELD_DECL
   2269 	  && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
   2270 	{
   2271 	  if (deleted_p)
   2272 	    *deleted_p = true;
   2273 	  if (diag)
   2274 	    error ("union member %q+D with non-trivial %qD", arg, fn);
   2275 	}
   2276     }
   2277 
   2278   if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
   2279     {
   2280       *constexpr_p = false;
   2281       if (diag)
   2282 	{
   2283 	  inform (DECL_SOURCE_LOCATION (fn),
   2284 		  SFK_DTOR_P (sfk)
   2285 		  ? G_("defaulted destructor calls non-%<constexpr%> %qD")
   2286 		  : G_("defaulted constructor calls non-%<constexpr%> %qD"),
   2287 		  fn);
   2288 	  explain_invalid_constexpr_fn (fn);
   2289 	}
   2290     }
   2291 }
   2292 
   2293 /* Subroutine of synthesized_method_walk to allow recursion into anonymous
   2294    aggregates.  If DTOR_FROM_CTOR is true, we're walking subobject destructors
   2295    called from a synthesized constructor, in which case we don't consider
   2296    the triviality of the subobject destructor.  */
   2297 
   2298 static void
   2299 walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
   2300 		   int quals, tree *spec_p, bool *trivial_p,
   2301 		   bool *deleted_p, bool *constexpr_p,
   2302 		   bool diag, int flags, tsubst_flags_t complain,
   2303 		   bool dtor_from_ctor)
   2304 {
   2305   tree field;
   2306   for (field = fields; field; field = DECL_CHAIN (field))
   2307     {
   2308       tree mem_type, argtype, rval;
   2309 
   2310       if (TREE_CODE (field) != FIELD_DECL
   2311 	  || DECL_ARTIFICIAL (field)
   2312 	  || DECL_UNNAMED_BIT_FIELD (field))
   2313 	continue;
   2314 
   2315       /* Variant members only affect deletedness.  In particular, they don't
   2316 	 affect the exception-specification of a user-provided destructor,
   2317 	 which we're figuring out via get_defaulted_eh_spec.  So if we aren't
   2318 	 asking if this is deleted, don't even look up the function; we don't
   2319 	 want an error about a deleted function we aren't actually calling.  */
   2320       if (sfk == sfk_destructor && deleted_p == NULL
   2321 	  && TREE_CODE (DECL_CONTEXT (field)) == UNION_TYPE)
   2322 	break;
   2323 
   2324       mem_type = strip_array_types (TREE_TYPE (field));
   2325       if (SFK_ASSIGN_P (sfk))
   2326 	{
   2327 	  bool bad = true;
   2328 	  if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
   2329 	    {
   2330 	      if (diag)
   2331 		error ("non-static const member %q#D, cannot use default "
   2332 		       "assignment operator", field);
   2333 	    }
   2334 	  else if (TYPE_REF_P (mem_type))
   2335 	    {
   2336 	      if (diag)
   2337 		error ("non-static reference member %q#D, cannot use "
   2338 		       "default assignment operator", field);
   2339 	    }
   2340 	  else
   2341 	    bad = false;
   2342 
   2343 	  if (bad && deleted_p)
   2344 	    *deleted_p = true;
   2345 	}
   2346       else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
   2347 	{
   2348 	  bool bad;
   2349 
   2350 	  if (DECL_INITIAL (field))
   2351 	    {
   2352 	      if (diag && DECL_INITIAL (field) == error_mark_node)
   2353 		inform (DECL_SOURCE_LOCATION (field),
   2354 			"initializer for %q#D is invalid", field);
   2355 	      if (trivial_p)
   2356 		*trivial_p = false;
   2357 	      /* Core 1351: If the field has an NSDMI that could throw, the
   2358 		 default constructor is noexcept(false).  */
   2359 	      if (spec_p)
   2360 		{
   2361 		  tree nsdmi = get_nsdmi (field, /*ctor*/false, complain);
   2362 		  if (nsdmi == error_mark_node)
   2363 		    *spec_p = error_mark_node;
   2364 		  else if (*spec_p != error_mark_node
   2365 			   && !expr_noexcept_p (nsdmi, tf_none))
   2366 		    *spec_p = noexcept_false_spec;
   2367 		}
   2368 	      /* Don't do the normal processing.  */
   2369 	      continue;
   2370 	    }
   2371 
   2372 	  bad = false;
   2373 	  if (CP_TYPE_CONST_P (mem_type)
   2374 	      && default_init_uninitialized_part (mem_type))
   2375 	    {
   2376 	      if (diag)
   2377 		{
   2378 		  error ("uninitialized const member in %q#T",
   2379 			 current_class_type);
   2380 		  inform (DECL_SOURCE_LOCATION (field),
   2381 			  "%q#D should be initialized", field);
   2382 		}
   2383 	      bad = true;
   2384 	    }
   2385 	  else if (TYPE_REF_P (mem_type))
   2386 	    {
   2387 	      if (diag)
   2388 		{
   2389 		  error ("uninitialized reference member in %q#T",
   2390 			 current_class_type);
   2391 		  inform (DECL_SOURCE_LOCATION (field),
   2392 			  "%q#D should be initialized", field);
   2393 		}
   2394 	      bad = true;
   2395 	    }
   2396 
   2397 	  if (bad && deleted_p)
   2398 	    *deleted_p = true;
   2399 
   2400 	  /* Before C++20, for an implicitly-defined default constructor to
   2401 	     be constexpr, every member must have a user-provided default
   2402 	     constructor or an explicit initializer.  */
   2403 	  if (constexpr_p
   2404 	      && cxx_dialect < cxx20
   2405 	      && !CLASS_TYPE_P (mem_type)
   2406 	      && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
   2407 	    {
   2408 	      *constexpr_p = false;
   2409 	      if (diag)
   2410 		inform (DECL_SOURCE_LOCATION (field),
   2411 			"defaulted default constructor does not "
   2412 			"initialize %q#D", field);
   2413 	    }
   2414 	}
   2415       else if (sfk == sfk_copy_constructor)
   2416 	{
   2417 	  /* 12.8p11b5 */
   2418 	  if (TYPE_REF_P (mem_type)
   2419 	      && TYPE_REF_IS_RVALUE (mem_type))
   2420 	    {
   2421 	      if (diag)
   2422 		error ("copying non-static data member %q#D of rvalue "
   2423 		       "reference type", field);
   2424 	      if (deleted_p)
   2425 		*deleted_p = true;
   2426 	    }
   2427 	}
   2428 
   2429       if (!CLASS_TYPE_P (mem_type))
   2430 	continue;
   2431 
   2432       if (ANON_AGGR_TYPE_P (mem_type))
   2433 	{
   2434 	  walk_field_subobs (TYPE_FIELDS (mem_type), sfk, fnname, quals,
   2435 			     spec_p, trivial_p, deleted_p, constexpr_p,
   2436 			     diag, flags, complain, dtor_from_ctor);
   2437 	  continue;
   2438 	}
   2439 
   2440       if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
   2441 	{
   2442 	  int mem_quals = cp_type_quals (mem_type) | quals;
   2443 	  if (DECL_MUTABLE_P (field))
   2444 	    mem_quals &= ~TYPE_QUAL_CONST;
   2445 	  argtype = build_stub_type (mem_type, mem_quals, SFK_MOVE_P (sfk));
   2446 	}
   2447       else
   2448 	argtype = NULL_TREE;
   2449 
   2450       rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);
   2451 
   2452       process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
   2453 			constexpr_p, diag, field, dtor_from_ctor);
   2454     }
   2455 }
   2456 
   2457 /* Base walker helper for synthesized_method_walk.  Inspect a direct
   2458    or virtual base.  BINFO is the parent type's binfo.  BASE_BINFO is
   2459    the base binfo of interests.  All other parms are as for
   2460    synthesized_method_walk, or its local vars.  */
   2461 
   2462 static tree
   2463 synthesized_method_base_walk (tree binfo, tree base_binfo,
   2464 			      special_function_kind sfk, tree fnname, int quals,
   2465 			      tree *inheriting_ctor, tree inherited_parms,
   2466 			      int flags, bool diag,
   2467 			      tree *spec_p, bool *trivial_p,
   2468 			      bool *deleted_p, bool *constexpr_p)
   2469 {
   2470   bool inherited_binfo = false;
   2471   tree argtype = NULL_TREE;
   2472   deferring_kind defer = dk_no_deferred;
   2473 
   2474   if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
   2475     argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, SFK_MOVE_P (sfk));
   2476   else if (inheriting_ctor
   2477 	   && (inherited_binfo
   2478 	       = binfo_inherited_from (binfo, base_binfo, *inheriting_ctor)))
   2479     {
   2480       argtype = inherited_parms;
   2481       /* Don't check access on the inherited constructor.  */
   2482       if (flag_new_inheriting_ctors)
   2483 	defer = dk_deferred;
   2484     }
   2485   else if (cxx_dialect >= cxx14 && sfk == sfk_virtual_destructor
   2486 	   && BINFO_VIRTUAL_P (base_binfo)
   2487 	   && ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo)))
   2488     /* Don't check access when looking at vbases of abstract class's
   2489        virtual destructor.  */
   2490     defer = dk_no_check;
   2491 
   2492   if (defer != dk_no_deferred)
   2493     push_deferring_access_checks (defer);
   2494   tree rval = locate_fn_flags (base_binfo, fnname, argtype, flags,
   2495 			       diag ? tf_warning_or_error : tf_none);
   2496   if (defer != dk_no_deferred)
   2497     pop_deferring_access_checks ();
   2498 
   2499   /* Replace an inherited template with the appropriate specialization.  */
   2500   if (inherited_binfo && rval
   2501       && DECL_P (*inheriting_ctor) && DECL_P (rval)
   2502       && DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval))
   2503     *inheriting_ctor = DECL_CLONED_FUNCTION (rval);
   2504 
   2505   process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
   2506 		    constexpr_p, diag, BINFO_TYPE (base_binfo));
   2507   if (SFK_CTOR_P (sfk)
   2508       && (!BINFO_VIRTUAL_P (base_binfo)
   2509 	  || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
   2510     {
   2511       /* In a constructor we also need to check the subobject
   2512 	 destructors for cleanup of partially constructed objects.  */
   2513       tree dtor = locate_fn_flags (base_binfo, complete_dtor_identifier,
   2514 				   NULL_TREE, flags,
   2515 				   diag ? tf_warning_or_error : tf_none);
   2516       /* Note that we don't pass down trivial_p; the subobject
   2517 	 destructors don't affect triviality of the constructor.  Nor
   2518 	 do they affect constexpr-ness (a constant expression doesn't
   2519 	 throw) or exception-specification (a throw from one of the
   2520 	 dtors would be a double-fault).  */
   2521       process_subob_fn (dtor, sfk, NULL, NULL, deleted_p, NULL, false,
   2522 			BINFO_TYPE (base_binfo), /*dtor_from_ctor*/true);
   2523     }
   2524 
   2525   return rval;
   2526 }
   2527 
   2528 /* The caller wants to generate an implicit declaration of SFK for
   2529    CTYPE which is const if relevant and CONST_P is set.  If SPEC_P,
   2530    TRIVIAL_P, DELETED_P or CONSTEXPR_P are non-null, set their
   2531    referent appropriately.  If DIAG is true, we're either being called
   2532    from maybe_explain_implicit_delete to give errors, or if
   2533    CONSTEXPR_P is non-null, from explain_invalid_constexpr_fn.  */
   2534 
   2535 static void
   2536 synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
   2537 			 tree *spec_p, bool *trivial_p, bool *deleted_p,
   2538 			 bool *constexpr_p, bool diag,
   2539 			 tree *inheriting_ctor, tree inherited_parms)
   2540 {
   2541   tree binfo, base_binfo;
   2542   int i;
   2543 
   2544   /* SFK must be exactly one category.  */
   2545   gcc_checking_assert (SFK_DTOR_P(sfk) + SFK_CTOR_P(sfk)
   2546 		       + SFK_ASSIGN_P(sfk) == 1);
   2547 
   2548   if (spec_p)
   2549     *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec);
   2550 
   2551   if (deleted_p)
   2552     {
   2553       /* "The closure type associated with a lambda-expression has a deleted
   2554 	 default constructor and a deleted copy assignment operator."
   2555 	 This is diagnosed in maybe_explain_implicit_delete.
   2556 	 In C++20, only lambda-expressions with lambda-captures have those
   2557 	 deleted.  */
   2558       if (LAMBDA_TYPE_P (ctype)
   2559 	  && (sfk == sfk_constructor || sfk == sfk_copy_assignment)
   2560 	  && (cxx_dialect < cxx20
   2561 	      || LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (ctype))
   2562 	      || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE
   2563 				(CLASSTYPE_LAMBDA_EXPR (ctype)) != CPLD_NONE))
   2564 	{
   2565 	  *deleted_p = true;
   2566 	  return;
   2567 	}
   2568 
   2569       *deleted_p = false;
   2570     }
   2571 
   2572   bool check_vdtor = false;
   2573   tree fnname;
   2574 
   2575   if (SFK_DTOR_P (sfk))
   2576     {
   2577       check_vdtor = true;
   2578       /* The synthesized method will call base dtors, but check complete
   2579 	 here to avoid having to deal with VTT.  */
   2580       fnname = complete_dtor_identifier;
   2581     }
   2582   else if (SFK_ASSIGN_P (sfk))
   2583     fnname = assign_op_identifier;
   2584   else
   2585     fnname = complete_ctor_identifier;
   2586 
   2587   gcc_assert ((sfk == sfk_inheriting_constructor)
   2588 	      == (inheriting_ctor && *inheriting_ctor != NULL_TREE));
   2589 
   2590   /* If that user-written default constructor would satisfy the
   2591      requirements of a constexpr constructor (7.1.5), the
   2592      implicitly-defined default constructor is constexpr.
   2593 
   2594      The implicitly-defined copy/move assignment operator is constexpr if
   2595       - X is a literal type, and
   2596       - the assignment operator selected to copy/move each direct base class
   2597 	subobject is a constexpr function, and
   2598       - for each non-static data member of X that is of class type (or array
   2599 	thereof), the assignment operator selected to copy/move that
   2600 	member is a constexpr function.  */
   2601   if (constexpr_p)
   2602     *constexpr_p = (SFK_CTOR_P (sfk)
   2603 		    || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14)
   2604 		    || (SFK_DTOR_P (sfk) && cxx_dialect >= cxx20));
   2605 
   2606   bool expected_trivial = type_has_trivial_fn (ctype, sfk);
   2607   if (trivial_p)
   2608     *trivial_p = expected_trivial;
   2609 
   2610   /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
   2611      class versions and other properties of the type.  But a subobject
   2612      class can be trivially copyable and yet have overload resolution
   2613      choose a template constructor for initialization, depending on
   2614      rvalueness and cv-quals.  And furthermore, a member in a base might
   2615      be trivial but deleted or otherwise not callable.  So we can't exit
   2616      early in C++0x.  The same considerations apply in C++98/03, but
   2617      there the definition of triviality does not consider overload
   2618      resolution, so a constructor can be trivial even if it would otherwise
   2619      call a non-trivial constructor.  */
   2620   if (expected_trivial
   2621       && (!(SFK_COPY_P (sfk) || SFK_MOVE_P (sfk)) || cxx_dialect < cxx11))
   2622     {
   2623       if (constexpr_p && sfk == sfk_constructor)
   2624 	{
   2625 	  bool cx = trivial_default_constructor_is_constexpr (ctype);
   2626 	  *constexpr_p = cx;
   2627 	  if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
   2628 	    /* A trivial constructor doesn't have any NSDMI.  */
   2629 	    inform (input_location, "defaulted default constructor does "
   2630 		    "not initialize any non-static data member");
   2631 	}
   2632       if (!diag && cxx_dialect < cxx11)
   2633 	return;
   2634     }
   2635 
   2636   ++cp_unevaluated_operand;
   2637   ++c_inhibit_evaluation_warnings;
   2638   push_deferring_access_checks (dk_no_deferred);
   2639 
   2640   tree scope = push_scope (ctype);
   2641 
   2642   int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE;
   2643   if (sfk != sfk_inheriting_constructor)
   2644     flags |= LOOKUP_DEFAULTED;
   2645 
   2646   tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none;
   2647   if (diag && spec_p)
   2648     /* We're in get_defaulted_eh_spec; we don't actually want any walking
   2649        diagnostics, we just want complain set.  */
   2650     diag = false;
   2651   int quals = const_p ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED;
   2652 
   2653   for (binfo = TYPE_BINFO (ctype), i = 0;
   2654        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
   2655     {
   2656       if (!SFK_ASSIGN_P (sfk) && BINFO_VIRTUAL_P (base_binfo))
   2657 	/* We'll handle virtual bases below.  */
   2658 	continue;
   2659 
   2660       tree fn = synthesized_method_base_walk (binfo, base_binfo,
   2661 					      sfk, fnname, quals,
   2662 					      inheriting_ctor, inherited_parms,
   2663 					      flags, diag, spec_p, trivial_p,
   2664 					      deleted_p, constexpr_p);
   2665 
   2666       if (diag && SFK_ASSIGN_P (sfk) && SFK_MOVE_P (sfk)
   2667 	  && BINFO_VIRTUAL_P (base_binfo)
   2668 	  && fn && TREE_CODE (fn) == FUNCTION_DECL
   2669 	  && move_fn_p (fn) && !trivial_fn_p (fn)
   2670 	  && vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
   2671 	warning (OPT_Wvirtual_move_assign,
   2672 		 "defaulted move assignment for %qT calls a non-trivial "
   2673 		 "move assignment operator for virtual base %qT",
   2674 		 ctype, BINFO_TYPE (base_binfo));
   2675 
   2676       if (check_vdtor && type_has_virtual_destructor (BINFO_TYPE (base_binfo)))
   2677 	{
   2678 	  /* Unlike for base ctor/op=/dtor, for operator delete it's fine
   2679 	     to have a null fn (no class-specific op delete).  */
   2680 	  fn = locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
   2681 				ptr_type_node, flags, tf_none);
   2682 	  if (fn && fn == error_mark_node)
   2683 	    {
   2684 	      if (complain & tf_error)
   2685 		locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
   2686 				 ptr_type_node, flags, complain);
   2687 	      if (deleted_p)
   2688 		*deleted_p = true;
   2689 	    }
   2690 	  check_vdtor = false;
   2691 	}
   2692     }
   2693 
   2694   vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (ctype);
   2695   if (SFK_ASSIGN_P (sfk))
   2696     /* Already examined vbases above.  */;
   2697   else if (vec_safe_is_empty (vbases))
   2698     /* No virtual bases to worry about.  */;
   2699   else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14
   2700 	   /* DR 1658 specifies that vbases of abstract classes are
   2701 	      ignored for both ctors and dtors.  Except DR 2336
   2702 	      overrides that skipping when determing the eh-spec of a
   2703 	      virtual destructor.  */
   2704 	   && sfk != sfk_virtual_destructor)
   2705     /* Vbase cdtors are not relevant.  */;
   2706   else
   2707     {
   2708       if (constexpr_p)
   2709 	*constexpr_p = false;
   2710 
   2711       FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
   2712 	synthesized_method_base_walk (binfo, base_binfo, sfk, fnname, quals,
   2713 				      inheriting_ctor, inherited_parms,
   2714 				      flags, diag,
   2715 				      spec_p, trivial_p, deleted_p, constexpr_p);
   2716     }
   2717 
   2718   /* Now handle the non-static data members.  */
   2719   walk_field_subobs (TYPE_FIELDS (ctype), sfk, fnname, quals,
   2720 		     spec_p, trivial_p, deleted_p, constexpr_p,
   2721 		     diag, flags, complain, /*dtor_from_ctor*/false);
   2722   if (SFK_CTOR_P (sfk))
   2723     walk_field_subobs (TYPE_FIELDS (ctype), sfk_destructor,
   2724 		       complete_dtor_identifier, TYPE_UNQUALIFIED,
   2725 		       NULL, NULL, deleted_p, NULL,
   2726 		       false, flags, complain, /*dtor_from_ctor*/true);
   2727 
   2728   pop_scope (scope);
   2729 
   2730   pop_deferring_access_checks ();
   2731   --cp_unevaluated_operand;
   2732   --c_inhibit_evaluation_warnings;
   2733 }
   2734 
   2735 /* DECL is a defaulted function whose exception specification is now
   2736    needed.  Return what it should be.  */
   2737 
   2738 tree
   2739 get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
   2740 {
   2741   /* For DECL_MAYBE_DELETED this should already have been handled by
   2742      synthesize_method.  */
   2743   gcc_assert (!DECL_MAYBE_DELETED (decl));
   2744 
   2745   if (DECL_CLONED_FUNCTION_P (decl))
   2746     decl = DECL_CLONED_FUNCTION (decl);
   2747   special_function_kind sfk = special_function_p (decl);
   2748   tree ctype = DECL_CONTEXT (decl);
   2749   tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
   2750   tree parm_type = TREE_VALUE (parms);
   2751   bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
   2752   tree spec = empty_except_spec;
   2753   bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
   2754   tree inh = DECL_INHERITED_CTOR (decl);
   2755   if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
   2756     /* We have to examine virtual bases even if abstract.  */
   2757     sfk = sfk_virtual_destructor;
   2758   bool pushed = false;
   2759   if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
   2760     pushed = push_tinst_level (decl);
   2761   synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
   2762 			   NULL, diag, &inh, parms);
   2763   if (pushed)
   2764     pop_tinst_level ();
   2765   return spec;
   2766 }
   2767 
   2768 /* DECL is a deleted function.  If it's implicitly deleted, explain why and
   2769    return true; else return false.  */
   2770 
   2771 bool
   2772 maybe_explain_implicit_delete (tree decl)
   2773 {
   2774   /* If decl is a clone, get the primary variant.  */
   2775   decl = DECL_ORIGIN (decl);
   2776   gcc_assert (DECL_DELETED_FN (decl));
   2777   if (DECL_DEFAULTED_FN (decl))
   2778     {
   2779       /* Not marked GTY; it doesn't need to be GC'd or written to PCH.  */
   2780       static hash_set<tree> *explained;
   2781 
   2782       special_function_kind sfk;
   2783       location_t loc;
   2784       bool informed;
   2785       tree ctype;
   2786 
   2787       if (!explained)
   2788 	explained = new hash_set<tree>;
   2789       if (explained->add (decl))
   2790 	return true;
   2791 
   2792       sfk = special_function_p (decl);
   2793       ctype = DECL_CONTEXT (decl);
   2794       loc = input_location;
   2795       input_location = DECL_SOURCE_LOCATION (decl);
   2796 
   2797       informed = false;
   2798       if (LAMBDA_TYPE_P (ctype))
   2799 	{
   2800 	  informed = true;
   2801 	  if (sfk == sfk_constructor)
   2802 	    inform (DECL_SOURCE_LOCATION (decl),
   2803 		    "a lambda closure type has a deleted default constructor");
   2804 	  else if (sfk == sfk_copy_assignment)
   2805 	    inform (DECL_SOURCE_LOCATION (decl),
   2806 		    "a lambda closure type has a deleted copy assignment operator");
   2807 	  else
   2808 	    informed = false;
   2809 	}
   2810       else if (DECL_ARTIFICIAL (decl)
   2811 	       && (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
   2812 	       && classtype_has_move_assign_or_move_ctor_p (ctype, true))
   2813 	{
   2814 	  inform (DECL_SOURCE_LOCATION (decl),
   2815 		  "%q#D is implicitly declared as deleted because %qT "
   2816 		  "declares a move constructor or move assignment operator",
   2817 		  decl, ctype);
   2818 	  informed = true;
   2819 	}
   2820       else if (sfk == sfk_inheriting_constructor)
   2821 	{
   2822 	  tree binfo = inherited_ctor_binfo (decl);
   2823 	  if (TREE_CODE (binfo) != TREE_BINFO)
   2824 	    {
   2825 	      inform (DECL_SOURCE_LOCATION (decl),
   2826 		      "%q#D inherits from multiple base subobjects",
   2827 		      decl);
   2828 	      informed = true;
   2829 	    }
   2830 	}
   2831       if (!informed && sfk == sfk_comparison)
   2832 	{
   2833 	  inform (DECL_SOURCE_LOCATION (decl),
   2834 		  "%q#D is implicitly deleted because the default "
   2835 		  "definition would be ill-formed:", decl);
   2836 	  build_comparison_op (decl, false, tf_warning_or_error);
   2837 	}
   2838       else if (!informed)
   2839 	{
   2840 	  tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
   2841 	  bool const_p = false;
   2842 	  if (parms)
   2843 	    {
   2844 	      tree parm_type = TREE_VALUE (parms);
   2845 	      const_p = CP_TYPE_CONST_P (non_reference (parm_type));
   2846 	    }
   2847 	  tree raises = NULL_TREE;
   2848 	  bool deleted_p = false;
   2849 	  tree scope = push_scope (ctype);
   2850 	  tree inh = DECL_INHERITED_CTOR (decl);
   2851 
   2852 	  synthesized_method_walk (ctype, sfk, const_p,
   2853 				   &raises, NULL, &deleted_p, NULL, false,
   2854 				   &inh, parms);
   2855 	  if (deleted_p)
   2856 	    {
   2857 	      inform (DECL_SOURCE_LOCATION (decl),
   2858 		      "%q#D is implicitly deleted because the default "
   2859 		      "definition would be ill-formed:", decl);
   2860 	      synthesized_method_walk (ctype, sfk, const_p,
   2861 				       NULL, NULL, &deleted_p, NULL, true,
   2862 				       &inh, parms);
   2863 	    }
   2864 	  else if (!comp_except_specs
   2865 		   (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
   2866 		    raises, ce_normal))
   2867 	    inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly "
   2868 		    "deleted because its exception-specification does not "
   2869 		    "match the implicit exception-specification %qX",
   2870 		    decl, raises);
   2871 	  else if (flag_checking)
   2872 	    gcc_unreachable ();
   2873 
   2874 	  pop_scope (scope);
   2875 	}
   2876 
   2877       input_location = loc;
   2878       return true;
   2879     }
   2880   return false;
   2881 }
   2882 
   2883 /* DECL is a defaulted function which was declared constexpr.  Explain why
   2884    it can't be constexpr.  */
   2885 
   2886 void
   2887 explain_implicit_non_constexpr (tree decl)
   2888 {
   2889   tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
   2890   bool const_p = CP_TYPE_CONST_P (non_reference (TREE_VALUE (parms)));
   2891   tree inh = DECL_INHERITED_CTOR (decl);
   2892   bool dummy;
   2893   special_function_kind sfk = special_function_p (decl);
   2894   if (sfk == sfk_comparison)
   2895     {
   2896       DECL_DECLARED_CONSTEXPR_P (decl) = true;
   2897       build_comparison_op (decl, false, tf_warning_or_error);
   2898       DECL_DECLARED_CONSTEXPR_P (decl) = false;
   2899     }
   2900   else
   2901     synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
   2902 			     sfk, const_p,
   2903 			     NULL, NULL, NULL, &dummy, true,
   2904 			     &inh, parms);
   2905 }
   2906 
   2907 /* DECL is an instantiation of an inheriting constructor template.  Deduce
   2908    the correct exception-specification and deletedness for this particular
   2909    specialization.  Return true if the deduction succeeds; false otherwise.  */
   2910 
   2911 bool
   2912 deduce_inheriting_ctor (tree decl)
   2913 {
   2914   decl = DECL_ORIGIN (decl);
   2915   gcc_assert (DECL_INHERITED_CTOR (decl));
   2916   tree spec;
   2917   bool trivial, constexpr_, deleted;
   2918   tree inh = DECL_INHERITED_CTOR (decl);
   2919   synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
   2920 			   false, &spec, &trivial, &deleted, &constexpr_,
   2921 			   /*diag*/false,
   2922 			   &inh,
   2923 			   FUNCTION_FIRST_USER_PARMTYPE (decl));
   2924   if (spec == error_mark_node)
   2925     return false;
   2926   if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO)
   2927     /* Inherited the same constructor from different base subobjects.  */
   2928     deleted = true;
   2929   DECL_DELETED_FN (decl) = deleted;
   2930   TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
   2931   SET_DECL_INHERITED_CTOR (decl, inh);
   2932 
   2933   tree clone;
   2934   FOR_EACH_CLONE (clone, decl)
   2935     {
   2936       DECL_DELETED_FN (clone) = deleted;
   2937       TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
   2938       SET_DECL_INHERITED_CTOR (clone, inh);
   2939     }
   2940 
   2941   return true;
   2942 }
   2943 
   2944 /* Implicitly declare the special function indicated by KIND, as a
   2945    member of TYPE.  For copy constructors and assignment operators,
   2946    CONST_P indicates whether these functions should take a const
   2947    reference argument or a non-const reference.
   2948    Returns the FUNCTION_DECL for the implicitly declared function.  */
   2949 
   2950 tree
   2951 implicitly_declare_fn (special_function_kind kind, tree type,
   2952 		       bool const_p, tree pattern_fn,
   2953 		       tree inherited_parms)
   2954 {
   2955   tree fn;
   2956   tree parameter_types = void_list_node;
   2957   tree return_type;
   2958   tree fn_type;
   2959   tree raises = empty_except_spec;
   2960   tree rhs_parm_type = NULL_TREE;
   2961   tree this_parm;
   2962   tree name;
   2963   HOST_WIDE_INT saved_processing_template_decl;
   2964   bool deleted_p = false;
   2965   bool constexpr_p = false;
   2966   tree inherited_ctor = (kind == sfk_inheriting_constructor
   2967 			 ? pattern_fn : NULL_TREE);
   2968 
   2969   /* Because we create declarations for implicitly declared functions
   2970      lazily, we may be creating the declaration for a member of TYPE
   2971      while in some completely different context.  However, TYPE will
   2972      never be a dependent class (because we never want to do lookups
   2973      for implicitly defined functions in a dependent class).  */
   2974   gcc_assert (!dependent_type_p (type));
   2975 
   2976   /* If the member-specification does not explicitly declare any member or
   2977      friend named operator==, an == operator function is declared
   2978      implicitly for each three-way comparison operator function defined as
   2979      defaulted in the member-specification, with the same access and
   2980      function-definition and in the same class scope as the respective
   2981      three-way comparison operator function, except that the return type is
   2982      replaced with bool and the declarator-id is replaced with
   2983      operator==.
   2984 
   2985      [Note: Such an implicitly-declared == operator for a class X is
   2986      defined as defaulted in the definition of X and has the same
   2987      parameter-declaration-clause and trailing requires-clause as the
   2988      respective three-way comparison operator. It is declared with friend,
   2989      virtual, constexpr, or consteval if the three-way comparison operator
   2990      function is so declared. If the three-way comparison operator function
   2991      has no noexcept-specifier, the implicitly-declared == operator
   2992      function has an implicit exception specification (14.5) that may
   2993      differ from the implicit exception specification of the three-way
   2994      comparison operator function. --end note]  */
   2995   if (kind == sfk_comparison)
   2996     {
   2997       fn = copy_operator_fn (pattern_fn, EQ_EXPR);
   2998       DECL_ARTIFICIAL (fn) = 1;
   2999       TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
   3000       return fn;
   3001     }
   3002 
   3003   /* Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
   3004      because we only create clones for constructors and destructors
   3005      when not in a template.  */
   3006   saved_processing_template_decl = processing_template_decl;
   3007   processing_template_decl = 0;
   3008 
   3009   type = TYPE_MAIN_VARIANT (type);
   3010 
   3011   if (targetm.cxx.cdtor_returns_this ())
   3012     {
   3013       if (kind == sfk_destructor)
   3014 	/* See comment in check_special_function_return_type.  */
   3015 	return_type = build_pointer_type (void_type_node);
   3016       else
   3017 	return_type = build_pointer_type (type);
   3018     }
   3019   else
   3020     return_type = void_type_node;
   3021 
   3022   int this_quals = TYPE_UNQUALIFIED;
   3023   switch (kind)
   3024     {
   3025     case sfk_destructor:
   3026       /* Destructor.  */
   3027       name = dtor_identifier;
   3028       break;
   3029 
   3030     case sfk_constructor:
   3031       /* Default constructor.  */
   3032       name = ctor_identifier;
   3033       break;
   3034 
   3035     case sfk_copy_constructor:
   3036     case sfk_copy_assignment:
   3037     case sfk_move_constructor:
   3038     case sfk_move_assignment:
   3039     case sfk_inheriting_constructor:
   3040     {
   3041       if (kind == sfk_copy_assignment
   3042 	  || kind == sfk_move_assignment)
   3043 	{
   3044 	  return_type = build_reference_type (type);
   3045 	  name = assign_op_identifier;
   3046 	}
   3047       else
   3048 	name = ctor_identifier;
   3049 
   3050       if (kind == sfk_inheriting_constructor)
   3051 	parameter_types = inherited_parms;
   3052       else
   3053 	{
   3054 	  if (const_p)
   3055 	    rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
   3056 	  else
   3057 	    rhs_parm_type = type;
   3058 	  bool move_p = (kind == sfk_move_assignment
   3059 			 || kind == sfk_move_constructor);
   3060 	  rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
   3061 
   3062 	  parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
   3063 	}
   3064       break;
   3065     }
   3066 
   3067     default:
   3068       gcc_unreachable ();
   3069     }
   3070 
   3071   bool trivial_p = false;
   3072 
   3073   if (inherited_ctor)
   3074     {
   3075       /* For an inheriting constructor, just copy these flags from the
   3076 	 inherited constructor until deduce_inheriting_ctor.  */
   3077       raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
   3078       deleted_p = DECL_DELETED_FN (inherited_ctor);
   3079       constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
   3080     }
   3081   else if (cxx_dialect >= cxx11)
   3082     {
   3083       raises = noexcept_deferred_spec;
   3084       synthesized_method_walk (type, kind, const_p, NULL, &trivial_p,
   3085 			       &deleted_p, &constexpr_p, false,
   3086 			       &inherited_ctor, inherited_parms);
   3087     }
   3088   else
   3089     synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
   3090 			     &deleted_p, &constexpr_p, false,
   3091 			     &inherited_ctor, inherited_parms);
   3092   /* Don't bother marking a deleted constructor as constexpr.  */
   3093   if (deleted_p)
   3094     constexpr_p = false;
   3095   /* A trivial copy/move constructor is also a constexpr constructor,
   3096      unless the class has virtual bases (7.1.5p4).  */
   3097   else if (trivial_p
   3098 	   && cxx_dialect >= cxx11
   3099 	   && (kind == sfk_copy_constructor
   3100 	       || kind == sfk_move_constructor)
   3101 	   && !CLASSTYPE_VBASECLASSES (type))
   3102     gcc_assert (constexpr_p);
   3103 
   3104   if (!trivial_p && type_has_trivial_fn (type, kind))
   3105     type_set_nontrivial_flag (type, kind);
   3106 
   3107   /* Create the function.  */
   3108   tree this_type = cp_build_qualified_type (type, this_quals);
   3109   fn_type = build_method_type_directly (this_type, return_type,
   3110 					parameter_types);
   3111 
   3112   if (raises)
   3113     {
   3114       if (raises != error_mark_node)
   3115 	fn_type = build_exception_variant (fn_type, raises);
   3116       else
   3117 	{
   3118 	  /* Can happen, e.g., in C++98 mode for an ill-formed non-static data
   3119 	     member initializer (c++/89914).  Also, in C++98, we might have
   3120 	     failed to deduce RAISES, so try again but complain this time.  */
   3121 	  if (cxx_dialect < cxx11)
   3122 	    synthesized_method_walk (type, kind, const_p, &raises, nullptr,
   3123 				     nullptr, nullptr, /*diag=*/true,
   3124 				     &inherited_ctor, inherited_parms);
   3125 	  /* We should have seen an error at this point.  */
   3126 	  gcc_assert (seen_error ());
   3127 	}
   3128     }
   3129   fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
   3130   if (kind != sfk_inheriting_constructor)
   3131     DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
   3132 
   3133   if (IDENTIFIER_OVL_OP_P (name))
   3134     {
   3135       const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (name);
   3136       DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) = op->ovl_op_code;
   3137     }
   3138   else if (IDENTIFIER_CTOR_P (name))
   3139     DECL_CXX_CONSTRUCTOR_P (fn) = true;
   3140   else if (IDENTIFIER_DTOR_P (name))
   3141     DECL_CXX_DESTRUCTOR_P (fn) = true;
   3142   else
   3143     gcc_unreachable ();
   3144 
   3145   SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
   3146 
   3147   /* Create the explicit arguments.  */
   3148   if (rhs_parm_type)
   3149     {
   3150       /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
   3151 	 want its type to be included in the mangled function
   3152 	 name.  */
   3153       tree decl = cp_build_parm_decl (fn, NULL_TREE, rhs_parm_type);
   3154       TREE_READONLY (decl) = 1;
   3155       retrofit_lang_decl (decl);
   3156       DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
   3157       DECL_ARGUMENTS (fn) = decl;
   3158     }
   3159   else if (kind == sfk_inheriting_constructor)
   3160     {
   3161       tree *p = &DECL_ARGUMENTS (fn);
   3162       int index = 1;
   3163       for (tree parm = inherited_parms; parm && parm != void_list_node;
   3164 	   parm = TREE_CHAIN (parm))
   3165 	{
   3166 	  *p = cp_build_parm_decl (fn, NULL_TREE, TREE_VALUE (parm));
   3167 	  retrofit_lang_decl (*p);
   3168 	  DECL_PARM_LEVEL (*p) = 1;
   3169 	  DECL_PARM_INDEX (*p) = index++;
   3170 	  p = &DECL_CHAIN (*p);
   3171 	}
   3172       SET_DECL_INHERITED_CTOR (fn, inherited_ctor);
   3173       DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
   3174       /* A constructor so declared has the same access as the corresponding
   3175 	 constructor in X.  */
   3176       TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
   3177       TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
   3178       /* Copy constexpr from the inherited constructor even if the
   3179 	 inheriting constructor doesn't satisfy the requirements.  */
   3180       constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
   3181     }
   3182 
   3183   /* Add the "this" parameter.  */
   3184   this_parm = build_this_parm (fn, fn_type, this_quals);
   3185   DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
   3186   DECL_ARGUMENTS (fn) = this_parm;
   3187 
   3188   grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
   3189 
   3190   DECL_IN_AGGR_P (fn) = 1;
   3191   DECL_ARTIFICIAL (fn) = 1;
   3192   DECL_DEFAULTED_FN (fn) = 1;
   3193   if (cxx_dialect >= cxx11)
   3194     {
   3195       DECL_DELETED_FN (fn) = deleted_p;
   3196       DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
   3197     }
   3198   DECL_EXTERNAL (fn) = true;
   3199   DECL_NOT_REALLY_EXTERN (fn) = 1;
   3200   DECL_DECLARED_INLINE_P (fn) = 1;
   3201   set_linkage_according_to_type (type, fn);
   3202   if (TREE_PUBLIC (fn))
   3203     DECL_COMDAT (fn) = 1;
   3204   rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
   3205   gcc_assert (!TREE_USED (fn));
   3206 
   3207   /* Propagate constraints from the inherited constructor. */
   3208   if (flag_concepts && inherited_ctor)
   3209     if (tree orig_ci = get_constraints (inherited_ctor))
   3210       {
   3211         tree new_ci = copy_node (orig_ci);
   3212         set_constraints (fn, new_ci);
   3213       }
   3214 
   3215   /* Restore PROCESSING_TEMPLATE_DECL.  */
   3216   processing_template_decl = saved_processing_template_decl;
   3217 
   3218   if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
   3219     fn = add_inherited_template_parms (fn, inherited_ctor);
   3220 
   3221   /* Warn about calling a non-trivial move assignment in a virtual base.  */
   3222   if (kind == sfk_move_assignment && !deleted_p && !trivial_p
   3223       && CLASSTYPE_VBASECLASSES (type))
   3224     {
   3225       location_t loc = input_location;
   3226       input_location = DECL_SOURCE_LOCATION (fn);
   3227       synthesized_method_walk (type, kind, const_p,
   3228 			       NULL, NULL, NULL, NULL, true,
   3229 			       NULL, NULL_TREE);
   3230       input_location = loc;
   3231     }
   3232 
   3233   return fn;
   3234 }
   3235 
   3236 /* Gives any errors about defaulted functions which need to be deferred
   3237    until the containing class is complete.  */
   3238 
   3239 void
   3240 defaulted_late_check (tree fn)
   3241 {
   3242   /* Complain about invalid signature for defaulted fn.  */
   3243   tree ctx = DECL_CONTEXT (fn);
   3244   special_function_kind kind = special_function_p (fn);
   3245 
   3246   if (kind == sfk_comparison)
   3247     {
   3248       /* If the function was declared constexpr, check that the definition
   3249 	 qualifies.  Otherwise we can define the function lazily.  */
   3250       if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn))
   3251 	{
   3252 	  /* Prevent GC.  */
   3253 	  function_depth++;
   3254 	  synthesize_method (fn);
   3255 	  function_depth--;
   3256 	}
   3257       return;
   3258     }
   3259 
   3260   bool fn_const_p = (copy_fn_p (fn) == 2);
   3261   tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
   3262 					    NULL, NULL);
   3263   tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
   3264 
   3265   if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
   3266 		    TREE_TYPE (TREE_TYPE (implicit_fn)))
   3267       || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
   3268 		     TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
   3269     {
   3270       error ("defaulted declaration %q+D does not match the "
   3271 	     "expected signature", fn);
   3272       inform (DECL_SOURCE_LOCATION (fn),
   3273 	      "expected signature: %qD", implicit_fn);
   3274     }
   3275 
   3276   if (DECL_DELETED_FN (implicit_fn))
   3277     {
   3278       DECL_DELETED_FN (fn) = 1;
   3279       return;
   3280     }
   3281 
   3282   /* If a function is explicitly defaulted on its first declaration without an
   3283      exception-specification, it is implicitly considered to have the same
   3284      exception-specification as if it had been implicitly declared.  */
   3285   if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
   3286       && DECL_DEFAULTED_IN_CLASS_P (fn))
   3287     TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
   3288 
   3289   if (DECL_DEFAULTED_IN_CLASS_P (fn)
   3290       && DECL_DECLARED_CONSTEXPR_P (implicit_fn))
   3291     {
   3292       /* Hmm...should we do this for out-of-class too? Should it be OK to
   3293 	 add constexpr later like inline, rather than requiring
   3294 	 declarations to match?  */
   3295       DECL_DECLARED_CONSTEXPR_P (fn) = true;
   3296       if (kind == sfk_constructor)
   3297 	TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
   3298     }
   3299 
   3300   if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
   3301       && DECL_DECLARED_CONSTEXPR_P (fn))
   3302     {
   3303       if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
   3304 	{
   3305 	  error ("explicitly defaulted function %q+D cannot be declared "
   3306 		 "%qs because the implicit declaration is not %qs:", fn,
   3307 		 DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr",
   3308 		 "constexpr");
   3309 	  explain_implicit_non_constexpr (fn);
   3310 	}
   3311       DECL_DECLARED_CONSTEXPR_P (fn) = false;
   3312     }
   3313 }
   3314 
   3315 /* Returns true iff FN can be explicitly defaulted, and gives any
   3316    errors if defaulting FN is ill-formed.  */
   3317 
   3318 bool
   3319 defaultable_fn_check (tree fn)
   3320 {
   3321   special_function_kind kind = sfk_none;
   3322 
   3323   if (template_parm_scope_p ())
   3324     {
   3325       error ("a template cannot be defaulted");
   3326       return false;
   3327     }
   3328 
   3329   if (DECL_CONSTRUCTOR_P (fn))
   3330     {
   3331       if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
   3332 	kind = sfk_constructor;
   3333       else if (copy_fn_p (fn) > 0
   3334 	       && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
   3335 		   == void_list_node))
   3336 	kind = sfk_copy_constructor;
   3337       else if (move_fn_p (fn))
   3338 	kind = sfk_move_constructor;
   3339     }
   3340   else if (DECL_DESTRUCTOR_P (fn))
   3341     kind = sfk_destructor;
   3342   else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
   3343 	   && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
   3344     {
   3345       if (copy_fn_p (fn))
   3346 	kind = sfk_copy_assignment;
   3347       else if (move_fn_p (fn))
   3348 	kind = sfk_move_assignment;
   3349     }
   3350   else if (DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) >= OVL_OP_EQ_EXPR
   3351 	   && DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) <= OVL_OP_SPACESHIP_EXPR)
   3352     {
   3353       kind = sfk_comparison;
   3354       if (!early_check_defaulted_comparison (fn))
   3355 	return false;
   3356     }
   3357 
   3358   if (kind == sfk_none)
   3359     {
   3360       error ("%qD cannot be defaulted", fn);
   3361       return false;
   3362     }
   3363   else
   3364     {
   3365       for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
   3366 	   t && t != void_list_node; t = TREE_CHAIN (t))
   3367 	if (TREE_PURPOSE (t))
   3368 	  {
   3369 	    error ("defaulted function %q+D with default argument", fn);
   3370 	    break;
   3371 	  }
   3372 
   3373       /* Avoid do_warn_unused_parameter warnings.  */
   3374       for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p))
   3375 	if (DECL_NAME (p))
   3376 	  suppress_warning (p, OPT_Wunused_parameter);
   3377 
   3378       if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
   3379 	/* Defer checking.  */;
   3380       else if (!processing_template_decl)
   3381 	defaulted_late_check (fn);
   3382 
   3383       return true;
   3384     }
   3385 }
   3386 
   3387 /* Add an implicit declaration to TYPE for the kind of function
   3388    indicated by SFK.  Return the FUNCTION_DECL for the new implicit
   3389    declaration.  */
   3390 
   3391 tree
   3392 lazily_declare_fn (special_function_kind sfk, tree type)
   3393 {
   3394   tree fn;
   3395   /* Whether or not the argument has a const reference type.  */
   3396   bool const_p = false;
   3397 
   3398   type = TYPE_MAIN_VARIANT (type);
   3399 
   3400   switch (sfk)
   3401     {
   3402     case sfk_constructor:
   3403       CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
   3404       break;
   3405     case sfk_copy_constructor:
   3406       const_p = TYPE_HAS_CONST_COPY_CTOR (type);
   3407       CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
   3408       break;
   3409     case sfk_move_constructor:
   3410       CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
   3411       break;
   3412     case sfk_copy_assignment:
   3413       const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
   3414       CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
   3415       break;
   3416     case sfk_move_assignment:
   3417       CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
   3418       break;
   3419     case sfk_destructor:
   3420       CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
   3421       break;
   3422     default:
   3423       gcc_unreachable ();
   3424     }
   3425 
   3426   /* Declare the function.  */
   3427   fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);
   3428 
   3429   /* [class.copy]/8 If the class definition declares a move constructor or
   3430      move assignment operator, the implicitly declared copy constructor is
   3431      defined as deleted.... */
   3432   if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
   3433       && cxx_dialect >= cxx11)
   3434     {
   3435       if (classtype_has_move_assign_or_move_ctor_p (type, true))
   3436 	DECL_DELETED_FN (fn) = true;
   3437       else if (classtype_has_depr_implicit_copy (type))
   3438 	/* The implicit definition of a copy constructor as defaulted is
   3439 	   deprecated if the class has a user-declared copy assignment operator
   3440 	   or a user-declared destructor. The implicit definition of a copy
   3441 	   assignment operator as defaulted is deprecated if the class has a
   3442 	   user-declared copy constructor or a user-declared destructor (15.4,
   3443 	   15.8).  */
   3444 	TREE_DEPRECATED (fn) = true;
   3445     }
   3446 
   3447   /* Destructors and assignment operators may be virtual.  */
   3448   if (sfk == sfk_destructor
   3449       || sfk == sfk_move_assignment
   3450       || sfk == sfk_copy_assignment)
   3451     check_for_override (fn, type);
   3452 
   3453   /* Add it to the class  */
   3454   bool added = add_method (type, fn, false);
   3455   gcc_assert (added || errorcount);
   3456 
   3457   /* Add it to TYPE_FIELDS.  */
   3458   if (sfk == sfk_destructor
   3459       && DECL_VIRTUAL_P (fn))
   3460     /* The ABI requires that a virtual destructor go at the end of the
   3461        vtable.  */
   3462     TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
   3463   else
   3464     {
   3465       DECL_CHAIN (fn) = TYPE_FIELDS (type);
   3466       TYPE_FIELDS (type) = fn;
   3467     }
   3468   /* Propagate TYPE_FIELDS.  */
   3469   fixup_type_variants (type);
   3470 
   3471   maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
   3472   if (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
   3473     /* Create appropriate clones.  */
   3474     clone_cdtor (fn, /*update_methods=*/true);
   3475 
   3476   return fn;
   3477 }
   3478 
   3479 /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
   3480    as there are artificial parms in FN.  */
   3481 
   3482 tree
   3483 skip_artificial_parms_for (const_tree fn, tree list)
   3484 {
   3485   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
   3486     list = TREE_CHAIN (list);
   3487   else
   3488     return list;
   3489 
   3490   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
   3491     list = TREE_CHAIN (list);
   3492   if (DECL_HAS_VTT_PARM_P (fn))
   3493     list = TREE_CHAIN (list);
   3494   return list;
   3495 }
   3496 
   3497 /* Given a FUNCTION_DECL FN and a chain LIST, return the number of
   3498    artificial parms in FN.  */
   3499 
   3500 int
   3501 num_artificial_parms_for (const_tree fn)
   3502 {
   3503   int count = 0;
   3504 
   3505   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
   3506     count++;
   3507   else
   3508     return 0;
   3509 
   3510   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
   3511     count++;
   3512   if (DECL_HAS_VTT_PARM_P (fn))
   3513     count++;
   3514   return count;
   3515 }
   3516 
   3517 
   3518 #include "gt-cp-method.h"
   3519