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