1 /* Handle the hair of processing (but not expanding) inline functions.
2    Also manage function and variable name overloading.
3    Copyright (C) 1987-2022 Free Software Foundation, Inc.
4    Contributed by Michael Tiemann (tiemann@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.cc.  */
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
lookup_comparison_result(tree type,const char * name_str,tsubst_flags_t complain=tf_warning_or_error)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
lookup_comparison_category(comp_cat_tag tag,tsubst_flags_t complain=tf_warning_or_error)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
lookup_comparison_result(comp_cat_tag tag,const char * name_str,tsubst_flags_t complain=tf_warning_or_error)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               {
1226                 error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
1227                 inform (location_of (ctx), "declared here");
1228                 ok = false;
1229               }
1230           }
1231       else if (!same_type_ignoring_top_level_qualifiers_p (parmtype, ctx))
1232           saw_bad = true;
1233     }
1234 
1235   if (saw_bad || (saw_byval && saw_byref))
1236     {
1237       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1238           error_at (loc, "defaulted member %qD must have parameter type "
1239                       "%<const %T&%>", fn, ctx);
1240       else if (saw_bad)
1241           error_at (loc, "defaulted %qD must have parameters of either type "
1242                       "%<const %T&%> or %qT", fn, ctx, ctx);
1243       else
1244           error_at (loc, "defaulted %qD must have parameters of either type "
1245                       "%<const %T&%> or %qT, not both", fn, ctx, ctx);
1246       ok = false;
1247     }
1248 
1249   /* We still need to deduce deleted/constexpr/noexcept and maybe return. */
1250   DECL_MAYBE_DELETED (fn) = ok;
1251 
1252   return ok;
1253 }
1254 
1255 /* Subroutine of build_comparison_op.  Given the vec of memberwise
1256    comparisons COMPS, calculate the overall comparison category for
1257    operator<=>.  */
1258 
1259 static tree
common_comparison_type(vec<tree> & comps)1260 common_comparison_type (vec<tree> &comps)
1261 {
1262   tree seen[cc_last] = {};
1263 
1264   for (unsigned i = 0; i < comps.length(); ++i)
1265     {
1266       tree comp = comps[i];
1267       if (TREE_CODE (comp) == TREE_LIST)
1268           comp = TREE_VALUE (comp);
1269       tree ctype = TREE_TYPE (comp);
1270       comp_cat_tag tag = cat_tag_for (ctype);
1271       /* build_comparison_op already checked this.  */
1272       gcc_checking_assert (tag < cc_last);
1273       seen[tag] = ctype;
1274     }
1275 
1276   /* Otherwise, if at least one T i is std::partial_ordering, U is
1277      std::partial_ordering.  */
1278   if (tree t = seen[cc_partial_ordering]) return t;
1279 
1280   /* Otherwise, if at least one T i is std::weak_ordering, U is
1281      std::weak_ordering.  */
1282   if (tree t = seen[cc_weak_ordering]) return t;
1283 
1284   /* Otherwise, U is std::strong_ordering.  */
1285   if (tree t = seen[cc_strong_ordering]) return t;
1286   return lookup_comparison_category (cc_strong_ordering);
1287 }
1288 
1289 /* Data structure for build_comparison_op.  */
1290 
1291 struct comp_info
1292 {
1293   tree fndecl;
1294   location_t loc;
1295   tsubst_flags_t complain;
1296   tree_code code;
1297   comp_cat_tag retcat;
1298   bool first_time;
1299   bool constexp;
1300   bool was_constexp;
1301   bool noex;
1302 
comp_infocomp_info1303   comp_info (tree fndecl, tsubst_flags_t complain)
1304     : fndecl (fndecl), complain (complain)
1305   {
1306     loc = DECL_SOURCE_LOCATION (fndecl);
1307 
1308     first_time = DECL_MAYBE_DELETED (fndecl);
1309     DECL_MAYBE_DELETED (fndecl) = false;
1310 
1311     /* Do we want to try to set constexpr?  */
1312     was_constexp = DECL_DECLARED_CONSTEXPR_P (fndecl);
1313     constexp = first_time;
1314     if (constexp)
1315       /* Set this for var_in_constexpr_fn.  */
1316       DECL_DECLARED_CONSTEXPR_P (fndecl) = true;
1317 
1318     /* Do we want to try to set noexcept?  */
1319     noex = first_time;
1320     if (noex)
1321       {
1322           tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
1323           if (raises && !UNEVALUATED_NOEXCEPT_SPEC_P (raises))
1324             /* There was an explicit exception-specification.  */
1325             noex = false;
1326       }
1327   }
1328 
1329   /* EXPR is an expression built as part of the function body.
1330      Adjust the properties appropriately.  */
checkcomp_info1331   void check (tree expr)
1332   {
1333     if (expr == error_mark_node)
1334       DECL_DELETED_FN (fndecl) = true;
1335     if ((constexp || was_constexp)
1336           && !potential_rvalue_constant_expression (expr))
1337       {
1338           if (was_constexp)
1339             require_potential_rvalue_constant_expression (expr);
1340           else
1341             constexp = false;
1342       }
1343     if (noex && !expr_noexcept_p (expr, tf_none))
1344       noex = false;
1345   }
1346 
~comp_infocomp_info1347   ~comp_info ()
1348   {
1349     if (first_time)
1350       {
1351           DECL_DECLARED_CONSTEXPR_P (fndecl) = constexp || was_constexp;
1352           tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
1353           if (!raises || UNEVALUATED_NOEXCEPT_SPEC_P (raises))
1354             {
1355               raises = noex ? noexcept_true_spec : noexcept_false_spec;
1356               TREE_TYPE (fndecl) = build_exception_variant (TREE_TYPE (fndecl),
1357                                                                         raises);
1358             }
1359       }
1360   }
1361 };
1362 
1363 /* Subroutine of build_comparison_op, to compare a single subobject.  */
1364 
1365 static tree
do_one_comp(location_t loc,const comp_info & info,tree sub,tree lhs,tree rhs)1366 do_one_comp (location_t loc, const comp_info &info, tree sub, tree lhs, tree rhs)
1367 {
1368   const tree_code code = info.code;
1369   const tree fndecl = info.fndecl;
1370   const comp_cat_tag retcat = info.retcat;
1371   const tsubst_flags_t complain = info.complain;
1372 
1373   tree overload = NULL_TREE;
1374   int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
1375   /* If we have an explicit comparison category return type we can fall back
1376      to </=, so don't give an error yet if <=> lookup fails.  */
1377   bool tentative = retcat != cc_last;
1378   tree comp = build_new_op (loc, code, flags, lhs, rhs,
1379                                   NULL_TREE, NULL_TREE, &overload,
1380                                   tentative ? tf_none : complain);
1381 
1382   if (code != SPACESHIP_EXPR)
1383     return comp;
1384 
1385   tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
1386 
1387   if (comp == error_mark_node)
1388     {
1389       if (overload == NULL_TREE && (tentative || complain))
1390           {
1391             /* No viable <=>, try using op< and op==.  */
1392             tree lteq = genericize_spaceship (loc, rettype, lhs, rhs);
1393             if (lteq != error_mark_node)
1394               {
1395                 /* We found usable < and ==.  */
1396                 if (retcat != cc_last)
1397                     /* Return type is a comparison category, use them.  */
1398                     comp = lteq;
1399                 else if (complain & tf_error)
1400                     /* Return type is auto, suggest changing it.  */
1401                     inform (info.loc, "changing the return type from %qs "
1402                               "to a comparison category type will allow the "
1403                               "comparison to use %qs and %qs", "auto",
1404                               "operator<", "operator==");
1405               }
1406             else if (tentative && complain)
1407               /* No usable < and ==, give an error for op<=>.  */
1408               build_new_op (loc, code, flags, lhs, rhs, complain);
1409           }
1410       if (comp == error_mark_node)
1411           return error_mark_node;
1412     }
1413 
1414   if (FNDECL_USED_AUTO (fndecl)
1415       && cat_tag_for (TREE_TYPE (comp)) == cc_last)
1416     {
1417       /* The operator function is defined as deleted if ... Ri is not a
1418            comparison category type.  */
1419       if (complain & tf_error)
1420           inform (loc,
1421                     "three-way comparison of %qD has type %qT, not a "
1422                     "comparison category type", sub, TREE_TYPE (comp));
1423       return error_mark_node;
1424     }
1425   else if (!FNDECL_USED_AUTO (fndecl)
1426              && !can_convert (rettype, TREE_TYPE (comp), complain))
1427     {
1428       if (complain & tf_error)
1429           error_at (loc,
1430                       "three-way comparison of %qD has type %qT, which "
1431                       "does not convert to %qT",
1432                       sub, TREE_TYPE (comp), rettype);
1433       return error_mark_node;
1434     }
1435 
1436   return comp;
1437 }
1438 
1439 /* Build up the definition of a defaulted comparison operator.  Unlike other
1440    defaulted functions that use synthesized_method_walk to determine whether
1441    the function is e.g. deleted, for comparisons we use the same code.  We try
1442    to use synthesize_method at the earliest opportunity and bail out if the
1443    function ends up being deleted.  */
1444 
1445 void
build_comparison_op(tree fndecl,bool defining,tsubst_flags_t complain)1446 build_comparison_op (tree fndecl, bool defining, tsubst_flags_t complain)
1447 {
1448   comp_info info (fndecl, complain);
1449 
1450   if (!defining && !(complain & tf_error) && !DECL_MAYBE_DELETED (fndecl))
1451     return;
1452 
1453   int flags = LOOKUP_NORMAL;
1454   const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (DECL_NAME (fndecl));
1455   tree_code code = info.code = op->tree_code;
1456 
1457   tree lhs = DECL_ARGUMENTS (fndecl);
1458   tree rhs = DECL_CHAIN (lhs);
1459   if (is_this_parameter (lhs))
1460     lhs = cp_build_fold_indirect_ref (lhs);
1461   else
1462     lhs = convert_from_reference (lhs);
1463   rhs = convert_from_reference (rhs);
1464   tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
1465   gcc_assert (!defining || COMPLETE_TYPE_P (ctype));
1466 
1467   iloc_sentinel ils (info.loc);
1468 
1469   /* A defaulted comparison operator function for class C is defined as
1470      deleted if ... C has variant members.  */
1471   if (TREE_CODE (ctype) == UNION_TYPE
1472       && next_initializable_field (TYPE_FIELDS (ctype)))
1473     {
1474       if (complain & tf_error)
1475           inform (info.loc, "cannot default compare union %qT", ctype);
1476       DECL_DELETED_FN (fndecl) = true;
1477       return;
1478     }
1479 
1480   tree compound_stmt = NULL_TREE;
1481   if (defining)
1482     compound_stmt = begin_compound_stmt (0);
1483   else
1484     ++cp_unevaluated_operand;
1485 
1486   tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
1487   if (code != SPACESHIP_EXPR && is_auto (rettype))
1488     {
1489       rettype = boolean_type_node;
1490       apply_deduced_return_type (fndecl, rettype);
1491     }
1492 
1493   if (code == EQ_EXPR || code == SPACESHIP_EXPR)
1494     {
1495       comp_cat_tag &retcat = (info.retcat = cc_last);
1496       if (code == SPACESHIP_EXPR && !FNDECL_USED_AUTO (fndecl))
1497           retcat = cat_tag_for (rettype);
1498 
1499       bool bad = false;
1500       auto_vec<tree> comps;
1501 
1502       /* Compare the base subobjects.  We handle them this way, rather than in
1503            the field loop below, because maybe_instantiate_noexcept might bring
1504            us here before we've built the base fields.  */
1505       for (tree base_binfo : BINFO_BASE_BINFOS (TYPE_BINFO (ctype)))
1506           {
1507             tree lhs_base
1508               = build_base_path (PLUS_EXPR, lhs, base_binfo, 0, complain);
1509             tree rhs_base
1510               = build_base_path (PLUS_EXPR, rhs, base_binfo, 0, complain);
1511 
1512             location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (ctype));
1513             tree comp = do_one_comp (loc, info, BINFO_TYPE (base_binfo),
1514                                            lhs_base, rhs_base);
1515             if (comp == error_mark_node)
1516               {
1517                 bad = true;
1518                 continue;
1519               }
1520 
1521             comps.safe_push (comp);
1522           }
1523 
1524       /* Now compare the field subobjects.  */
1525       for (tree field = next_initializable_field (TYPE_FIELDS (ctype));
1526              field;
1527              field = next_initializable_field (DECL_CHAIN (field)))
1528           {
1529             if (DECL_VIRTUAL_P (field) || DECL_FIELD_IS_BASE (field))
1530               /* We ignore the vptr, and we already handled bases.  */
1531               continue;
1532 
1533             tree expr_type = TREE_TYPE (field);
1534 
1535             location_t field_loc = DECL_SOURCE_LOCATION (field);
1536 
1537             /* A defaulted comparison operator function for class C is defined as
1538                deleted if any non-static data member of C is of reference type or
1539                C has variant members.  */
1540             if (TREE_CODE (expr_type) == REFERENCE_TYPE)
1541               {
1542                 if (complain & tf_error)
1543                     inform (field_loc, "cannot default compare "
1544                               "reference member %qD", field);
1545                 bad = true;
1546                 continue;
1547               }
1548             else if (ANON_UNION_TYPE_P (expr_type)
1549                        && next_initializable_field (TYPE_FIELDS (expr_type)))
1550               {
1551                 if (complain & tf_error)
1552                     inform (field_loc, "cannot default compare "
1553                               "anonymous union member");
1554                 bad = true;
1555                 continue;
1556               }
1557 
1558             tree lhs_mem = build3_loc (field_loc, COMPONENT_REF, expr_type, lhs,
1559                                              field, NULL_TREE);
1560             tree rhs_mem = build3_loc (field_loc, COMPONENT_REF, expr_type, rhs,
1561                                              field, NULL_TREE);
1562             tree loop_indexes = NULL_TREE;
1563             while (TREE_CODE (expr_type) == ARRAY_TYPE)
1564               {
1565                 /* Flexible array member.  */
1566                 if (TYPE_DOMAIN (expr_type) == NULL_TREE
1567                       || TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type)) == NULL_TREE)
1568                     {
1569                       if (complain & tf_error)
1570                         inform (field_loc, "cannot default compare "
1571                                                "flexible array member");
1572                       bad = true;
1573                       break;
1574                     }
1575                 tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type));
1576                 /* [0] array.  No subobjects to compare, just skip it.  */
1577                 if (integer_all_onesp (maxval))
1578                     break;
1579                 tree idx;
1580                 /* [1] array, no loop needed, just add [0] ARRAY_REF.
1581                      Similarly if !defining.  */
1582                 if (integer_zerop (maxval) || !defining)
1583                     idx = size_zero_node;
1584                 /* Some other array, will need runtime loop.  */
1585                 else
1586                     {
1587                       idx = force_target_expr (sizetype, maxval, complain);
1588                       loop_indexes = tree_cons (idx, NULL_TREE, loop_indexes);
1589                     }
1590                 expr_type = TREE_TYPE (expr_type);
1591                 lhs_mem = build4_loc (field_loc, ARRAY_REF, expr_type, lhs_mem,
1592                                             idx, NULL_TREE, NULL_TREE);
1593                 rhs_mem = build4_loc (field_loc, ARRAY_REF, expr_type, rhs_mem,
1594                                             idx, NULL_TREE, NULL_TREE);
1595               }
1596             if (TREE_CODE (expr_type) == ARRAY_TYPE)
1597               continue;
1598 
1599             tree comp = do_one_comp (field_loc, info, field, lhs_mem, rhs_mem);
1600             if (comp == error_mark_node)
1601               {
1602                 bad = true;
1603                 continue;
1604               }
1605 
1606             /* Most of the time, comp is the expression that should be evaluated
1607                to compare the two members.  If the expression needs to be
1608                evaluated more than once in a loop, it will be a TREE_LIST
1609                instead, whose TREE_VALUE is the expression for one array element,
1610                TREE_PURPOSE is innermost iterator temporary and if the array
1611                is multidimensional, TREE_CHAIN will contain another TREE_LIST
1612                with second innermost iterator in its TREE_PURPOSE and so on.  */
1613             if (loop_indexes)
1614               {
1615                 TREE_VALUE (loop_indexes) = comp;
1616                 comp = loop_indexes;
1617               }
1618             comps.safe_push (comp);
1619           }
1620       if (code == SPACESHIP_EXPR && is_auto (rettype))
1621           {
1622             rettype = common_comparison_type (comps);
1623             apply_deduced_return_type (fndecl, rettype);
1624           }
1625       if (bad)
1626           {
1627             DECL_DELETED_FN (fndecl) = true;
1628             goto out;
1629           }
1630       for (unsigned i = 0; i < comps.length(); ++i)
1631           {
1632             tree comp = comps[i];
1633             tree eq, retval = NULL_TREE, if_ = NULL_TREE;
1634             tree loop_indexes = NULL_TREE;
1635             if (defining)
1636               {
1637                 if (TREE_CODE (comp) == TREE_LIST)
1638                     {
1639                       loop_indexes = comp;
1640                       comp = TREE_VALUE (comp);
1641                       loop_indexes = nreverse (loop_indexes);
1642                       for (tree loop_index = loop_indexes; loop_index;
1643                            loop_index = TREE_CHAIN (loop_index))
1644                         {
1645                           tree for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
1646                           tree idx = TREE_PURPOSE (loop_index);
1647                           tree maxval = TARGET_EXPR_INITIAL (idx);
1648                           TARGET_EXPR_INITIAL (idx) = size_zero_node;
1649                           add_stmt (idx);
1650                           finish_init_stmt (for_stmt);
1651                           finish_for_cond (build2 (LE_EXPR, boolean_type_node, idx,
1652                                                          maxval), for_stmt, false, 0);
1653                           finish_for_expr (cp_build_unary_op (PREINCREMENT_EXPR,
1654                                                                         TARGET_EXPR_SLOT (idx),
1655                                                                         false, complain),
1656                                                                         for_stmt);
1657                           /* Store in TREE_VALUE the for_stmt tree, so that we can
1658                                later on call finish_for_stmt on it (in the reverse
1659                                order).  */
1660                           TREE_VALUE (loop_index) = for_stmt;
1661                         }
1662                       loop_indexes = nreverse (loop_indexes);
1663                     }
1664                 if_ = begin_if_stmt ();
1665               }
1666             /* Spaceship is specified to use !=, but for the comparison category
1667                types, != is equivalent to !(==), so let's use == directly.  */
1668             if (code == EQ_EXPR)
1669               {
1670                 /* if (x==y); else return false; */
1671                 eq = comp;
1672                 retval = boolean_false_node;
1673               }
1674             else
1675               {
1676                 /* if (auto v = x<=>y, v == 0); else return v; */
1677                 if (TREE_CODE (comp) == SPACESHIP_EXPR)
1678                     TREE_TYPE (comp) = rettype;
1679                 else
1680                     comp = build_static_cast (input_location, rettype, comp,
1681                                                     complain);
1682                 info.check (comp);
1683                 if (defining)
1684                     {
1685                       tree var = create_temporary_var (rettype);
1686                       pushdecl (var);
1687                       cp_finish_decl (var, comp, false, NULL_TREE, flags);
1688                       comp = retval = var;
1689                     }
1690                 eq = build_new_op (info.loc, EQ_EXPR, flags, comp,
1691                                          integer_zero_node, NULL_TREE, NULL_TREE,
1692                                          NULL, complain);
1693               }
1694             tree ceq = contextual_conv_bool (eq, complain);
1695             info.check (ceq);
1696             if (defining)
1697               {
1698                 finish_if_stmt_cond (ceq, if_);
1699                 finish_then_clause (if_);
1700                 begin_else_clause (if_);
1701                 finish_return_stmt (retval);
1702                 finish_else_clause (if_);
1703                 finish_if_stmt (if_);
1704                 for (tree loop_index = loop_indexes; loop_index;
1705                        loop_index = TREE_CHAIN (loop_index))
1706                     finish_for_stmt (TREE_VALUE (loop_index));
1707               }
1708           }
1709       if (defining)
1710           {
1711             tree val;
1712             if (code == EQ_EXPR)
1713               val = boolean_true_node;
1714             else
1715               {
1716                 tree seql = lookup_comparison_result (cc_strong_ordering,
1717                                                                 "equal", complain);
1718                 val = build_static_cast (input_location, rettype, seql,
1719                                                complain);
1720               }
1721             finish_return_stmt (val);
1722           }
1723     }
1724   else if (code == NE_EXPR)
1725     {
1726       tree comp = build_new_op (info.loc, EQ_EXPR, flags, lhs, rhs,
1727                                         NULL_TREE, NULL_TREE, NULL, complain);
1728       comp = contextual_conv_bool (comp, complain);
1729       info.check (comp);
1730       if (defining)
1731           {
1732             tree neg = build1 (TRUTH_NOT_EXPR, boolean_type_node, comp);
1733             finish_return_stmt (neg);
1734           }
1735     }
1736   else
1737     {
1738       tree comp = build_new_op (info.loc, SPACESHIP_EXPR, flags, lhs, rhs,
1739                                         NULL_TREE, NULL_TREE, NULL, complain);
1740       tree comp2 = build_new_op (info.loc, code, flags, comp, integer_zero_node,
1741                                          NULL_TREE, NULL_TREE, NULL, complain);
1742       info.check (comp2);
1743       if (defining)
1744           finish_return_stmt (comp2);
1745     }
1746 
1747  out:
1748   if (defining)
1749     finish_compound_stmt (compound_stmt);
1750   else
1751     --cp_unevaluated_operand;
1752 }
1753 
1754 /* True iff DECL is an implicitly-declared special member function with no real
1755    source location, so we can use its DECL_SOURCE_LOCATION to remember where we
1756    triggered its synthesis.  */
1757 
1758 bool
decl_remember_implicit_trigger_p(tree decl)1759 decl_remember_implicit_trigger_p (tree decl)
1760 {
1761   if (!DECL_ARTIFICIAL (decl))
1762     return false;
1763   special_function_kind sfk = special_function_p (decl);
1764   /* Inherited constructors have the location of their using-declaration, and
1765      operator== has the location of the corresponding operator<=>.  */
1766   return (sfk != sfk_inheriting_constructor
1767             && sfk != sfk_comparison);
1768 }
1769 
1770 /* Synthesize FNDECL, a non-static member function.   */
1771 
1772 void
synthesize_method(tree fndecl)1773 synthesize_method (tree fndecl)
1774 {
1775   bool nested = (current_function_decl != NULL_TREE);
1776   tree context = decl_function_context (fndecl);
1777   bool need_body = true;
1778   tree stmt;
1779   location_t save_input_location = input_location;
1780   int error_count = errorcount;
1781   int warning_count = warningcount + werrorcount;
1782   special_function_kind sfk = special_function_p (fndecl);
1783 
1784   /* Reset the source location, we might have been previously
1785      deferred, and thus have saved where we were first needed.  */
1786   if (decl_remember_implicit_trigger_p (fndecl))
1787     DECL_SOURCE_LOCATION (fndecl)
1788       = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
1789 
1790   /* If we've been asked to synthesize a clone, just synthesize the
1791      cloned function instead.  Doing so will automatically fill in the
1792      body for the clone.  */
1793   if (DECL_CLONED_FUNCTION_P (fndecl))
1794     fndecl = DECL_CLONED_FUNCTION (fndecl);
1795 
1796   /* We may be in the middle of deferred access check.  Disable
1797      it now.  */
1798   push_deferring_access_checks (dk_no_deferred);
1799 
1800   if (! context)
1801     push_to_top_level ();
1802   else if (nested)
1803     push_function_context ();
1804 
1805   input_location = DECL_SOURCE_LOCATION (fndecl);
1806 
1807   start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
1808   stmt = begin_function_body ();
1809 
1810   if (DECL_ASSIGNMENT_OPERATOR_P (fndecl)
1811       && DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR))
1812     {
1813       do_build_copy_assign (fndecl);
1814       need_body = false;
1815     }
1816   else if (DECL_CONSTRUCTOR_P (fndecl))
1817     {
1818       tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
1819       if (arg_chain != void_list_node)
1820           do_build_copy_constructor (fndecl);
1821       else
1822           finish_mem_initializers (NULL_TREE);
1823     }
1824   else if (sfk == sfk_comparison)
1825     {
1826       /* Pass tf_none so the function is just deleted if there's a problem.  */
1827       build_comparison_op (fndecl, true, tf_none);
1828       need_body = false;
1829     }
1830 
1831   /* If we haven't yet generated the body of the function, just
1832      generate an empty compound statement.  */
1833   if (need_body)
1834     {
1835       tree compound_stmt;
1836       compound_stmt = begin_compound_stmt (BCS_FN_BODY);
1837       finish_compound_stmt (compound_stmt);
1838     }
1839 
1840   finish_function_body (stmt);
1841   finish_function (/*inline_p=*/false);
1842 
1843   if (!DECL_DELETED_FN (fndecl))
1844     expand_or_defer_fn (fndecl);
1845 
1846   input_location = save_input_location;
1847 
1848   if (! context)
1849     pop_from_top_level ();
1850   else if (nested)
1851     pop_function_context ();
1852 
1853   pop_deferring_access_checks ();
1854 
1855   if (error_count != errorcount || warning_count != warningcount + werrorcount)
1856     if (DECL_ARTIFICIAL (fndecl))
1857       inform (input_location, "synthesized method %qD first required here",
1858                 fndecl);
1859 }
1860 
1861 /* Like synthesize_method, but don't actually synthesize defaulted comparison
1862    methods if their class is still incomplete.  Just deduce the return
1863    type in that case.  */
1864 
1865 void
maybe_synthesize_method(tree fndecl)1866 maybe_synthesize_method (tree fndecl)
1867 {
1868   if (special_function_p (fndecl) == sfk_comparison)
1869     {
1870       tree lhs = DECL_ARGUMENTS (fndecl);
1871       if (is_this_parameter (lhs))
1872           lhs = cp_build_fold_indirect_ref (lhs);
1873       else
1874           lhs = convert_from_reference (lhs);
1875       tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
1876       if (!COMPLETE_TYPE_P (ctype))
1877           {
1878             push_deferring_access_checks (dk_no_deferred);
1879             build_comparison_op (fndecl, false, tf_none);
1880             pop_deferring_access_checks ();
1881             return;
1882           }
1883     }
1884   return synthesize_method (fndecl);
1885 }
1886 
1887 /* Build a reference to type TYPE with cv-quals QUALS, which is an
1888    rvalue if RVALUE is true.  */
1889 
1890 static tree
build_stub_type(tree type,int quals,bool rvalue)1891 build_stub_type (tree type, int quals, bool rvalue)
1892 {
1893   tree argtype = cp_build_qualified_type (type, quals);
1894   return cp_build_reference_type (argtype, rvalue);
1895 }
1896 
1897 /* Build a dummy glvalue from dereferencing a dummy reference of type
1898    REFTYPE.  */
1899 
1900 tree
build_stub_object(tree reftype)1901 build_stub_object (tree reftype)
1902 {
1903   if (!TYPE_REF_P (reftype))
1904     reftype = cp_build_reference_type (reftype, /*rval*/true);
1905   tree stub = build1 (CONVERT_EXPR, reftype, integer_one_node);
1906   return convert_from_reference (stub);
1907 }
1908 
1909 /* Determine which function will be called when looking up NAME in TYPE,
1910    called with a single ARGTYPE argument, or no argument if ARGTYPE is
1911    null.  FLAGS and COMPLAIN are as for build_new_method_call.
1912 
1913    Returns a FUNCTION_DECL if all is well.
1914    Returns NULL_TREE if overload resolution failed.
1915    Returns error_mark_node if the chosen function cannot be called.  */
1916 
1917 static tree
locate_fn_flags(tree type,tree name,tree argtype,int flags,tsubst_flags_t complain)1918 locate_fn_flags (tree type, tree name, tree argtype, int flags,
1919                      tsubst_flags_t complain)
1920 {
1921   tree ob, fn, fns, binfo, rval;
1922 
1923   if (TYPE_P (type))
1924     binfo = TYPE_BINFO (type);
1925   else
1926     {
1927       binfo = type;
1928       type = BINFO_TYPE (binfo);
1929     }
1930 
1931   ob = build_stub_object (cp_build_reference_type (type, false));
1932   releasing_vec args;
1933   if (argtype)
1934     {
1935       if (TREE_CODE (argtype) == TREE_LIST)
1936           {
1937             for (tree elt = argtype; elt && elt != void_list_node;
1938                  elt = TREE_CHAIN (elt))
1939               {
1940                 tree type = TREE_VALUE (elt);
1941                 tree arg = build_stub_object (type);
1942                 vec_safe_push (args, arg);
1943               }
1944           }
1945       else
1946           {
1947             tree arg = build_stub_object (argtype);
1948             args->quick_push (arg);
1949           }
1950     }
1951 
1952   fns = lookup_fnfields (binfo, name, 0, complain);
1953   rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);
1954 
1955   if (fn && rval == error_mark_node)
1956     return rval;
1957   else
1958     return fn;
1959 }
1960 
1961 /* Locate the dtor of TYPE.  */
1962 
1963 tree
get_dtor(tree type,tsubst_flags_t complain)1964 get_dtor (tree type, tsubst_flags_t complain)
1965 {
1966   tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
1967                                    LOOKUP_NORMAL, complain);
1968   if (fn == error_mark_node)
1969     return NULL_TREE;
1970   return fn;
1971 }
1972 
1973 /* Locate the default ctor of TYPE.  */
1974 
1975 tree
locate_ctor(tree type)1976 locate_ctor (tree type)
1977 {
1978   tree fn;
1979 
1980   push_deferring_access_checks (dk_no_check);
1981   fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
1982                               LOOKUP_SPECULATIVE, tf_none);
1983   pop_deferring_access_checks ();
1984   if (fn == error_mark_node)
1985     return NULL_TREE;
1986   return fn;
1987 }
1988 
1989 /* Likewise, but give any appropriate errors.  */
1990 
1991 tree
get_default_ctor(tree type)1992 get_default_ctor (tree type)
1993 {
1994   tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
1995                                    LOOKUP_NORMAL, tf_warning_or_error);
1996   if (fn == error_mark_node)
1997     return NULL_TREE;
1998   return fn;
1999 }
2000 
2001 /* Locate the copy ctor of TYPE.  */
2002 
2003 tree
get_copy_ctor(tree type,tsubst_flags_t complain)2004 get_copy_ctor (tree type, tsubst_flags_t complain)
2005 {
2006   int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
2007                  ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
2008   tree argtype = build_stub_type (type, quals, false);
2009   tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
2010                                    LOOKUP_NORMAL, complain);
2011   if (fn == error_mark_node)
2012     return NULL_TREE;
2013   return fn;
2014 }
2015 
2016 /* Locate the copy assignment operator of TYPE.  */
2017 
2018 tree
get_copy_assign(tree type)2019 get_copy_assign (tree type)
2020 {
2021   int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
2022                  ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
2023   tree argtype = build_stub_type (type, quals, false);
2024   tree fn = locate_fn_flags (type, assign_op_identifier, argtype,
2025                                    LOOKUP_NORMAL, tf_warning_or_error);
2026   if (fn == error_mark_node)
2027     return NULL_TREE;
2028   return fn;
2029 }
2030 
2031 /* walk_tree helper function for is_trivially_xible.  If *TP is a call,
2032    return it if it calls something other than a trivial special member
2033    function.  */
2034 
2035 static tree
check_nontriv(tree * tp,int *,void *)2036 check_nontriv (tree *tp, int *, void *)
2037 {
2038   tree fn = cp_get_callee (*tp);
2039   if (fn == NULL_TREE)
2040     return NULL_TREE;
2041 
2042   if (TREE_CODE (fn) == ADDR_EXPR)
2043     fn = TREE_OPERAND (fn, 0);
2044 
2045   if (TREE_CODE (fn) != FUNCTION_DECL
2046       || !trivial_fn_p (fn))
2047     return fn;
2048   return NULL_TREE;
2049 }
2050 
2051 /* Return declval<T>() = declval<U>() treated as an unevaluated operand.  */
2052 
2053 static tree
assignable_expr(tree to,tree from)2054 assignable_expr (tree to, tree from)
2055 {
2056   cp_unevaluated cp_uneval_guard;
2057   to = build_stub_object (to);
2058   from = build_stub_object (from);
2059   tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
2060   return r;
2061 }
2062 
2063 /* The predicate condition for a template specialization
2064    is_constructible<T, Args...> shall be satisfied if and only if the
2065    following variable definition would be well-formed for some invented
2066    variable t: T t(create<Args>()...);
2067 
2068    Return something equivalent in well-formedness and triviality.  */
2069 
2070 static tree
constructible_expr(tree to,tree from)2071 constructible_expr (tree to, tree from)
2072 {
2073   tree expr;
2074   cp_unevaluated cp_uneval_guard;
2075   if (CLASS_TYPE_P (to))
2076     {
2077       tree ctype = to;
2078       vec<tree, va_gc> *args = NULL;
2079       if (!TYPE_REF_P (to))
2080           to = cp_build_reference_type (to, /*rval*/false);
2081       tree ob = build_stub_object (to);
2082       for (; from; from = TREE_CHAIN (from))
2083           vec_safe_push (args, build_stub_object (TREE_VALUE (from)));
2084       expr = build_special_member_call (ob, complete_ctor_identifier, &args,
2085                                                   ctype, LOOKUP_NORMAL, tf_none);
2086       if (expr == error_mark_node)
2087           return error_mark_node;
2088       /* The current state of the standard vis-a-vis LWG 2116 is that
2089            is_*constructible involves destruction as well.  */
2090       if (type_build_dtor_call (ctype))
2091           {
2092             tree dtor = build_special_member_call (ob, complete_dtor_identifier,
2093                                                              NULL, ctype, LOOKUP_NORMAL,
2094                                                              tf_none);
2095             if (dtor == error_mark_node)
2096               return error_mark_node;
2097             if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (ctype))
2098               expr = build2 (COMPOUND_EXPR, void_type_node, expr, dtor);
2099           }
2100     }
2101   else
2102     {
2103       if (from == NULL_TREE)
2104           return build_value_init (strip_array_types (to), tf_none);
2105       const int len = list_length (from);
2106       if (len > 1)
2107           {
2108             if (cxx_dialect < cxx20)
2109               /* Too many initializers.  */
2110               return error_mark_node;
2111 
2112             /* In C++20 this is well-formed:
2113                  using T = int[2];
2114                  T t(1, 2);
2115                which means that std::is_constructible_v<int[2], int, int>
2116                should be true.  */
2117             vec<constructor_elt, va_gc> *v;
2118             vec_alloc (v, len);
2119             for (tree t = from; t; t = TREE_CHAIN (t))
2120               {
2121                 tree stub = build_stub_object (TREE_VALUE (t));
2122                 constructor_elt elt = { NULL_TREE, stub };
2123                 v->quick_push (elt);
2124               }
2125             from = build_constructor (init_list_type_node, v);
2126             CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
2127             CONSTRUCTOR_IS_PAREN_INIT (from) = true;
2128           }
2129       else
2130           from = build_stub_object (TREE_VALUE (from));
2131       expr = perform_direct_initialization_if_possible (to, from,
2132                                                                       /*cast*/false,
2133                                                                       tf_none);
2134       /* If t(e) didn't work, maybe t{e} will.  */
2135       if (expr == NULL_TREE
2136             && len == 1
2137             && cxx_dialect >= cxx20)
2138           {
2139             from = build_constructor_single (init_list_type_node, NULL_TREE,
2140                                                      from);
2141             CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
2142             CONSTRUCTOR_IS_PAREN_INIT (from) = true;
2143             expr = perform_direct_initialization_if_possible (to, from,
2144                                                                           /*cast*/false,
2145                                                                           tf_none);
2146           }
2147     }
2148   return expr;
2149 }
2150 
2151 /* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or
2152    constructible (otherwise) from FROM, which is a single type for
2153    assignment or a list of types for construction.  */
2154 
2155 static tree
is_xible_helper(enum tree_code code,tree to,tree from,bool trivial)2156 is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
2157 {
2158   to = complete_type (to);
2159   deferring_access_check_sentinel acs (dk_no_deferred);
2160   if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to)
2161       || (from && FUNC_OR_METHOD_TYPE_P (from)
2162             && (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from))))
2163     return error_mark_node;
2164   tree expr;
2165   if (code == MODIFY_EXPR)
2166     expr = assignable_expr (to, from);
2167   else if (trivial && from && TREE_CHAIN (from)
2168              && cxx_dialect < cxx20)
2169     return error_mark_node; // only 0- and 1-argument ctors can be trivial
2170                                   // before C++20 aggregate paren init
2171   else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
2172     return error_mark_node; // can't construct an array of unknown bound
2173   else
2174     expr = constructible_expr (to, from);
2175   return expr;
2176 }
2177 
2178 /* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or
2179    constructible (otherwise) from FROM, which is a single type for
2180    assignment or a list of types for construction.  */
2181 
2182 bool
is_trivially_xible(enum tree_code code,tree to,tree from)2183 is_trivially_xible (enum tree_code code, tree to, tree from)
2184 {
2185   tree expr = is_xible_helper (code, to, from, /*trivial*/true);
2186   if (expr == NULL_TREE || expr == error_mark_node)
2187     return false;
2188   tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
2189   return !nt;
2190 }
2191 
2192 /* Returns true iff TO is nothrow assignable (if CODE is MODIFY_EXPR) or
2193    constructible (otherwise) from FROM, which is a single type for
2194    assignment or a list of types for construction.  */
2195 
2196 bool
is_nothrow_xible(enum tree_code code,tree to,tree from)2197 is_nothrow_xible (enum tree_code code, tree to, tree from)
2198 {
2199   tree expr = is_xible_helper (code, to, from, /*trivial*/false);
2200   if (expr == NULL_TREE || expr == error_mark_node)
2201     return false;
2202   return expr_noexcept_p (expr, tf_none);
2203 }
2204 
2205 /* Returns true iff TO is assignable (if CODE is MODIFY_EXPR) or
2206    constructible (otherwise) from FROM, which is a single type for
2207    assignment or a list of types for construction.  */
2208 
2209 bool
is_xible(enum tree_code code,tree to,tree from)2210 is_xible (enum tree_code code, tree to, tree from)
2211 {
2212   tree expr = is_xible_helper (code, to, from, /*trivial*/false);
2213   if (expr == error_mark_node)
2214     return false;
2215   return !!expr;
2216 }
2217 
2218 /* Categorize various special_function_kinds.  */
2219 #define SFK_CTOR_P(sfk) \
2220   ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
2221 #define SFK_DTOR_P(sfk) \
2222   ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
2223 #define SFK_ASSIGN_P(sfk) \
2224   ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
2225 #define SFK_COPY_P(sfk) \
2226   ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
2227 #define SFK_MOVE_P(sfk) \
2228   ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)
2229 
2230 /* Subroutine of synthesized_method_walk.  Update SPEC_P, TRIVIAL_P and
2231    DELETED_P or give an error message MSG with argument ARG.  */
2232 
2233 static void
process_subob_fn(tree fn,special_function_kind sfk,tree * spec_p,bool * trivial_p,bool * deleted_p,bool * constexpr_p,bool diag,tree arg,bool dtor_from_ctor=false)2234 process_subob_fn (tree fn, special_function_kind sfk, tree *spec_p,
2235                       bool *trivial_p, bool *deleted_p, bool *constexpr_p,
2236                       bool diag, tree arg, bool dtor_from_ctor = false)
2237 {
2238   if (!fn || fn == error_mark_node)
2239     {
2240       if (deleted_p)
2241           *deleted_p = true;
2242       return;
2243     }
2244 
2245   if (spec_p)
2246     {
2247       if (!maybe_instantiate_noexcept (fn))
2248           *spec_p = error_mark_node;
2249       else
2250           {
2251             tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
2252             *spec_p = merge_exception_specifiers (*spec_p, raises);
2253           }
2254     }
2255 
2256   if (!trivial_fn_p (fn) && !dtor_from_ctor)
2257     {
2258       if (trivial_p)
2259           *trivial_p = false;
2260       if (TREE_CODE (arg) == FIELD_DECL
2261             && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
2262           {
2263             if (deleted_p)
2264               *deleted_p = true;
2265             if (diag)
2266               error ("union member %q+D with non-trivial %qD", arg, fn);
2267           }
2268     }
2269 
2270   if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
2271     {
2272       *constexpr_p = false;
2273       if (diag)
2274           {
2275             inform (DECL_SOURCE_LOCATION (fn),
2276                       SFK_DTOR_P (sfk)
2277                       ? G_("defaulted destructor calls non-%<constexpr%> %qD")
2278                       : G_("defaulted constructor calls non-%<constexpr%> %qD"),
2279                       fn);
2280             explain_invalid_constexpr_fn (fn);
2281           }
2282     }
2283 }
2284 
2285 /* Subroutine of synthesized_method_walk to allow recursion into anonymous
2286    aggregates.  If DTOR_FROM_CTOR is true, we're walking subobject destructors
2287    called from a synthesized constructor, in which case we don't consider
2288    the triviality of the subobject destructor.  */
2289 
2290 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)2291 walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
2292                        int quals, tree *spec_p, bool *trivial_p,
2293                        bool *deleted_p, bool *constexpr_p,
2294                        bool diag, int flags, tsubst_flags_t complain,
2295                        bool dtor_from_ctor)
2296 {
2297   tree field;
2298   for (field = fields; field; field = DECL_CHAIN (field))
2299     {
2300       tree mem_type, argtype, rval;
2301 
2302       if (TREE_CODE (field) != FIELD_DECL
2303             || DECL_ARTIFICIAL (field)
2304             || DECL_UNNAMED_BIT_FIELD (field))
2305           continue;
2306 
2307       /* Variant members only affect deletedness.  In particular, they don't
2308            affect the exception-specification of a user-provided destructor,
2309            which we're figuring out via get_defaulted_eh_spec.  So if we aren't
2310            asking if this is deleted, don't even look up the function; we don't
2311            want an error about a deleted function we aren't actually calling.  */
2312       if (sfk == sfk_destructor && deleted_p == NULL
2313             && TREE_CODE (DECL_CONTEXT (field)) == UNION_TYPE)
2314           break;
2315 
2316       mem_type = strip_array_types (TREE_TYPE (field));
2317       if (SFK_ASSIGN_P (sfk))
2318           {
2319             bool bad = true;
2320             if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
2321               {
2322                 if (diag)
2323                     error ("non-static const member %q#D, cannot use default "
2324                            "assignment operator", field);
2325               }
2326             else if (TYPE_REF_P (mem_type))
2327               {
2328                 if (diag)
2329                     error ("non-static reference member %q#D, cannot use "
2330                            "default assignment operator", field);
2331               }
2332             else
2333               bad = false;
2334 
2335             if (bad && deleted_p)
2336               *deleted_p = true;
2337           }
2338       else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
2339           {
2340             bool bad;
2341 
2342             if (DECL_INITIAL (field))
2343               {
2344                 if (diag && DECL_INITIAL (field) == error_mark_node)
2345                     inform (DECL_SOURCE_LOCATION (field),
2346                               "initializer for %q#D is invalid", field);
2347                 if (trivial_p)
2348                     *trivial_p = false;
2349                 /* Core 1351: If the field has an NSDMI that could throw, the
2350                      default constructor is noexcept(false).  */
2351                 if (spec_p)
2352                     {
2353                       tree nsdmi = get_nsdmi (field, /*ctor*/false, complain);
2354                       if (nsdmi == error_mark_node)
2355                         *spec_p = error_mark_node;
2356                       else if (*spec_p != error_mark_node
2357                                  && !expr_noexcept_p (nsdmi, tf_none))
2358                         *spec_p = noexcept_false_spec;
2359                     }
2360                 /* Don't do the normal processing.  */
2361                 continue;
2362               }
2363 
2364             bad = false;
2365             if (CP_TYPE_CONST_P (mem_type)
2366                 && default_init_uninitialized_part (mem_type))
2367               {
2368                 if (diag)
2369                     {
2370                       error ("uninitialized const member in %q#T",
2371                                current_class_type);
2372                       inform (DECL_SOURCE_LOCATION (field),
2373                                 "%q#D should be initialized", field);
2374                     }
2375                 bad = true;
2376               }
2377             else if (TYPE_REF_P (mem_type))
2378               {
2379                 if (diag)
2380                     {
2381                       error ("uninitialized reference member in %q#T",
2382                                current_class_type);
2383                       inform (DECL_SOURCE_LOCATION (field),
2384                                 "%q#D should be initialized", field);
2385                     }
2386                 bad = true;
2387               }
2388 
2389             if (bad && deleted_p)
2390               *deleted_p = true;
2391 
2392             /* Before C++20, for an implicitly-defined default constructor to
2393                be constexpr, every member must have a user-provided default
2394                constructor or an explicit initializer.  */
2395             if (constexpr_p
2396                 && cxx_dialect < cxx20
2397                 && !CLASS_TYPE_P (mem_type)
2398                 && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
2399               {
2400                 *constexpr_p = false;
2401                 if (diag)
2402                     inform (DECL_SOURCE_LOCATION (field),
2403                               "defaulted default constructor does not "
2404                               "initialize %q#D", field);
2405               }
2406           }
2407       else if (sfk == sfk_copy_constructor)
2408           {
2409             /* 12.8p11b5 */
2410             if (TYPE_REF_P (mem_type)
2411                 && TYPE_REF_IS_RVALUE (mem_type))
2412               {
2413                 if (diag)
2414                     error ("copying non-static data member %q#D of rvalue "
2415                            "reference type", field);
2416                 if (deleted_p)
2417                     *deleted_p = true;
2418               }
2419           }
2420 
2421       if (!CLASS_TYPE_P (mem_type))
2422           continue;
2423 
2424       if (ANON_AGGR_TYPE_P (mem_type))
2425           {
2426             walk_field_subobs (TYPE_FIELDS (mem_type), sfk, fnname, quals,
2427                                    spec_p, trivial_p, deleted_p, constexpr_p,
2428                                    diag, flags, complain, dtor_from_ctor);
2429             continue;
2430           }
2431 
2432       if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
2433           {
2434             int mem_quals = cp_type_quals (mem_type) | quals;
2435             if (DECL_MUTABLE_P (field))
2436               mem_quals &= ~TYPE_QUAL_CONST;
2437             argtype = build_stub_type (mem_type, mem_quals, SFK_MOVE_P (sfk));
2438           }
2439       else
2440           argtype = NULL_TREE;
2441 
2442       rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);
2443 
2444       process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
2445                               constexpr_p, diag, field, dtor_from_ctor);
2446     }
2447 }
2448 
2449 /* Base walker helper for synthesized_method_walk.  Inspect a direct
2450    or virtual base.  BINFO is the parent type's binfo.  BASE_BINFO is
2451    the base binfo of interests.  All other parms are as for
2452    synthesized_method_walk, or its local vars.  */
2453 
2454 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)2455 synthesized_method_base_walk (tree binfo, tree base_binfo,
2456                                     special_function_kind sfk, tree fnname, int quals,
2457                                     tree *inheriting_ctor, tree inherited_parms,
2458                                     int flags, bool diag,
2459                                     tree *spec_p, bool *trivial_p,
2460                                     bool *deleted_p, bool *constexpr_p)
2461 {
2462   bool inherited_binfo = false;
2463   tree argtype = NULL_TREE;
2464   deferring_kind defer = dk_no_deferred;
2465 
2466   if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
2467     argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, SFK_MOVE_P (sfk));
2468   else if (inheriting_ctor
2469              && (inherited_binfo
2470                  = binfo_inherited_from (binfo, base_binfo, *inheriting_ctor)))
2471     {
2472       argtype = inherited_parms;
2473       /* Don't check access on the inherited constructor.  */
2474       if (flag_new_inheriting_ctors)
2475           defer = dk_deferred;
2476     }
2477   else if (cxx_dialect >= cxx14 && sfk == sfk_virtual_destructor
2478              && BINFO_VIRTUAL_P (base_binfo)
2479              && ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo)))
2480     /* Don't check access when looking at vbases of abstract class's
2481        virtual destructor.  */
2482     defer = dk_no_check;
2483 
2484   if (defer != dk_no_deferred)
2485     push_deferring_access_checks (defer);
2486   tree rval = locate_fn_flags (base_binfo, fnname, argtype, flags,
2487                                      diag ? tf_warning_or_error : tf_none);
2488   if (defer != dk_no_deferred)
2489     pop_deferring_access_checks ();
2490 
2491   /* Replace an inherited template with the appropriate specialization.  */
2492   if (inherited_binfo && rval
2493       && DECL_P (*inheriting_ctor) && DECL_P (rval)
2494       && DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval))
2495     *inheriting_ctor = DECL_CLONED_FUNCTION (rval);
2496 
2497   process_subob_fn (rval, sfk, spec_p, trivial_p, deleted_p,
2498                         constexpr_p, diag, BINFO_TYPE (base_binfo));
2499   if (SFK_CTOR_P (sfk)
2500       && (!BINFO_VIRTUAL_P (base_binfo)
2501             || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
2502     {
2503       /* In a constructor we also need to check the subobject
2504            destructors for cleanup of partially constructed objects.  */
2505       tree dtor = locate_fn_flags (base_binfo, complete_dtor_identifier,
2506                                            NULL_TREE, flags,
2507                                            diag ? tf_warning_or_error : tf_none);
2508       /* Note that we don't pass down trivial_p; the subobject
2509            destructors don't affect triviality of the constructor.  Nor
2510            do they affect constexpr-ness (a constant expression doesn't
2511            throw) or exception-specification (a throw from one of the
2512            dtors would be a double-fault).  */
2513       process_subob_fn (dtor, sfk, NULL, NULL, deleted_p, NULL, false,
2514                               BINFO_TYPE (base_binfo), /*dtor_from_ctor*/true);
2515     }
2516 
2517   return rval;
2518 }
2519 
2520 /* The caller wants to generate an implicit declaration of SFK for
2521    CTYPE which is const if relevant and CONST_P is set.  If SPEC_P,
2522    TRIVIAL_P, DELETED_P or CONSTEXPR_P are non-null, set their
2523    referent appropriately.  If DIAG is true, we're either being called
2524    from maybe_explain_implicit_delete to give errors, or if
2525    CONSTEXPR_P is non-null, from explain_invalid_constexpr_fn.  */
2526 
2527 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)2528 synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
2529                                tree *spec_p, bool *trivial_p, bool *deleted_p,
2530                                bool *constexpr_p, bool diag,
2531                                tree *inheriting_ctor, tree inherited_parms)
2532 {
2533   tree binfo, base_binfo;
2534   int i;
2535 
2536   /* SFK must be exactly one category.  */
2537   gcc_checking_assert (SFK_DTOR_P(sfk) + SFK_CTOR_P(sfk)
2538                            + SFK_ASSIGN_P(sfk) == 1);
2539 
2540   if (spec_p)
2541     *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec);
2542 
2543   if (deleted_p)
2544     {
2545       /* "The closure type associated with a lambda-expression has a deleted
2546            default constructor and a deleted copy assignment operator."
2547            This is diagnosed in maybe_explain_implicit_delete.
2548            In C++20, only lambda-expressions with lambda-captures have those
2549            deleted.  */
2550       if (LAMBDA_TYPE_P (ctype)
2551             && (sfk == sfk_constructor || sfk == sfk_copy_assignment)
2552             && (cxx_dialect < cxx20
2553                 || LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (ctype))
2554                 || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE
2555                                         (CLASSTYPE_LAMBDA_EXPR (ctype)) != CPLD_NONE))
2556           {
2557             *deleted_p = true;
2558             return;
2559           }
2560 
2561       *deleted_p = false;
2562     }
2563 
2564   bool check_vdtor = false;
2565   tree fnname;
2566 
2567   if (SFK_DTOR_P (sfk))
2568     {
2569       check_vdtor = true;
2570       /* The synthesized method will call base dtors, but check complete
2571            here to avoid having to deal with VTT.  */
2572       fnname = complete_dtor_identifier;
2573     }
2574   else if (SFK_ASSIGN_P (sfk))
2575     fnname = assign_op_identifier;
2576   else
2577     fnname = complete_ctor_identifier;
2578 
2579   gcc_assert ((sfk == sfk_inheriting_constructor)
2580                 == (inheriting_ctor && *inheriting_ctor != NULL_TREE));
2581 
2582   /* If that user-written default constructor would satisfy the
2583      requirements of a constexpr constructor (7.1.5), the
2584      implicitly-defined default constructor is constexpr.
2585 
2586      The implicitly-defined copy/move assignment operator is constexpr if
2587       - X is a literal type, and
2588       - the assignment operator selected to copy/move each direct base class
2589           subobject is a constexpr function, and
2590       - for each non-static data member of X that is of class type (or array
2591           thereof), the assignment operator selected to copy/move that
2592           member is a constexpr function.  */
2593   if (constexpr_p)
2594     *constexpr_p = (SFK_CTOR_P (sfk)
2595                         || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14)
2596                         || (SFK_DTOR_P (sfk) && cxx_dialect >= cxx20));
2597 
2598   bool expected_trivial = type_has_trivial_fn (ctype, sfk);
2599   if (trivial_p)
2600     *trivial_p = expected_trivial;
2601 
2602   /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
2603      class versions and other properties of the type.  But a subobject
2604      class can be trivially copyable and yet have overload resolution
2605      choose a template constructor for initialization, depending on
2606      rvalueness and cv-quals.  And furthermore, a member in a base might
2607      be trivial but deleted or otherwise not callable.  So we can't exit
2608      early in C++0x.  The same considerations apply in C++98/03, but
2609      there the definition of triviality does not consider overload
2610      resolution, so a constructor can be trivial even if it would otherwise
2611      call a non-trivial constructor.  */
2612   if (expected_trivial
2613       && (!(SFK_COPY_P (sfk) || SFK_MOVE_P (sfk)) || cxx_dialect < cxx11))
2614     {
2615       if (constexpr_p && sfk == sfk_constructor)
2616           {
2617             bool cx = trivial_default_constructor_is_constexpr (ctype);
2618             *constexpr_p = cx;
2619             if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
2620               /* A trivial constructor doesn't have any NSDMI.  */
2621               inform (input_location, "defaulted default constructor does "
2622                         "not initialize any non-static data member");
2623           }
2624       if (!diag && cxx_dialect < cxx11)
2625           return;
2626     }
2627 
2628   ++cp_unevaluated_operand;
2629   ++c_inhibit_evaluation_warnings;
2630   push_deferring_access_checks (dk_no_deferred);
2631 
2632   tree scope = push_scope (ctype);
2633 
2634   int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE;
2635   if (sfk != sfk_inheriting_constructor)
2636     flags |= LOOKUP_DEFAULTED;
2637 
2638   tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none;
2639   if (diag && spec_p)
2640     /* We're in get_defaulted_eh_spec; we don't actually want any walking
2641        diagnostics, we just want complain set.  */
2642     diag = false;
2643   int quals = const_p ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED;
2644 
2645   for (binfo = TYPE_BINFO (ctype), i = 0;
2646        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
2647     {
2648       if (!SFK_ASSIGN_P (sfk) && BINFO_VIRTUAL_P (base_binfo))
2649           /* We'll handle virtual bases below.  */
2650           continue;
2651 
2652       tree fn = synthesized_method_base_walk (binfo, base_binfo,
2653                                                         sfk, fnname, quals,
2654                                                         inheriting_ctor, inherited_parms,
2655                                                         flags, diag, spec_p, trivial_p,
2656                                                         deleted_p, constexpr_p);
2657 
2658       if (diag && SFK_ASSIGN_P (sfk) && SFK_MOVE_P (sfk)
2659             && BINFO_VIRTUAL_P (base_binfo)
2660             && fn && TREE_CODE (fn) == FUNCTION_DECL
2661             && move_fn_p (fn) && !trivial_fn_p (fn)
2662             && vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
2663           warning (OPT_Wvirtual_move_assign,
2664                      "defaulted move assignment for %qT calls a non-trivial "
2665                      "move assignment operator for virtual base %qT",
2666                      ctype, BINFO_TYPE (base_binfo));
2667 
2668       if (check_vdtor && type_has_virtual_destructor (BINFO_TYPE (base_binfo)))
2669           {
2670             /* Unlike for base ctor/op=/dtor, for operator delete it's fine
2671                to have a null fn (no class-specific op delete).  */
2672             fn = locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
2673                                         ptr_type_node, flags, tf_none);
2674             if (fn && fn == error_mark_node)
2675               {
2676                 if (complain & tf_error)
2677                     locate_fn_flags (ctype, ovl_op_identifier (false, DELETE_EXPR),
2678                                          ptr_type_node, flags, complain);
2679                 if (deleted_p)
2680                     *deleted_p = true;
2681               }
2682             check_vdtor = false;
2683           }
2684     }
2685 
2686   vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (ctype);
2687   if (SFK_ASSIGN_P (sfk))
2688     /* Already examined vbases above.  */;
2689   else if (vec_safe_is_empty (vbases))
2690     /* No virtual bases to worry about.  */;
2691   else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14
2692              /* DR 1658 specifies that vbases of abstract classes are
2693                 ignored for both ctors and dtors.  Except DR 2336
2694                 overrides that skipping when determing the eh-spec of a
2695                 virtual destructor.  */
2696              && sfk != sfk_virtual_destructor)
2697     /* Vbase cdtors are not relevant.  */;
2698   else
2699     {
2700       if (constexpr_p)
2701           *constexpr_p = false;
2702 
2703       FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
2704           synthesized_method_base_walk (binfo, base_binfo, sfk, fnname, quals,
2705                                               inheriting_ctor, inherited_parms,
2706                                               flags, diag,
2707                                               spec_p, trivial_p, deleted_p, constexpr_p);
2708     }
2709 
2710   /* Now handle the non-static data members.  */
2711   walk_field_subobs (TYPE_FIELDS (ctype), sfk, fnname, quals,
2712                          spec_p, trivial_p, deleted_p, constexpr_p,
2713                          diag, flags, complain, /*dtor_from_ctor*/false);
2714   if (SFK_CTOR_P (sfk))
2715     walk_field_subobs (TYPE_FIELDS (ctype), sfk_destructor,
2716                            complete_dtor_identifier, TYPE_UNQUALIFIED,
2717                            NULL, NULL, deleted_p, NULL,
2718                            false, flags, complain, /*dtor_from_ctor*/true);
2719 
2720   pop_scope (scope);
2721 
2722   pop_deferring_access_checks ();
2723   --cp_unevaluated_operand;
2724   --c_inhibit_evaluation_warnings;
2725 }
2726 
2727 /* DECL is a defaulted function whose exception specification is now
2728    needed.  Return what it should be.  */
2729 
2730 tree
get_defaulted_eh_spec(tree decl,tsubst_flags_t complain)2731 get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
2732 {
2733   /* For DECL_MAYBE_DELETED this should already have been handled by
2734      synthesize_method.  */
2735   gcc_assert (!DECL_MAYBE_DELETED (decl));
2736 
2737   if (DECL_CLONED_FUNCTION_P (decl))
2738     decl = DECL_CLONED_FUNCTION (decl);
2739   special_function_kind sfk = special_function_p (decl);
2740   tree ctype = DECL_CONTEXT (decl);
2741   tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
2742   tree parm_type = TREE_VALUE (parms);
2743   bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
2744   tree spec = empty_except_spec;
2745   bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
2746   tree inh = DECL_INHERITED_CTOR (decl);
2747   if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
2748     /* We have to examine virtual bases even if abstract.  */
2749     sfk = sfk_virtual_destructor;
2750   bool pushed = false;
2751   if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
2752     pushed = push_tinst_level (decl);
2753   synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
2754                                  NULL, diag, &inh, parms);
2755   if (pushed)
2756     pop_tinst_level ();
2757   return spec;
2758 }
2759 
2760 /* DECL is a deleted function.  If it's implicitly deleted, explain why and
2761    return true; else return false.  */
2762 
2763 bool
maybe_explain_implicit_delete(tree decl)2764 maybe_explain_implicit_delete (tree decl)
2765 {
2766   /* If decl is a clone, get the primary variant.  */
2767   decl = DECL_ORIGIN (decl);
2768   gcc_assert (DECL_DELETED_FN (decl));
2769   if (DECL_DEFAULTED_FN (decl))
2770     {
2771       /* Not marked GTY; it doesn't need to be GC'd or written to PCH.  */
2772       static hash_set<tree> *explained;
2773 
2774       special_function_kind sfk;
2775       location_t loc;
2776       bool informed;
2777       tree ctype;
2778 
2779       if (!explained)
2780           explained = new hash_set<tree>;
2781       if (explained->add (decl))
2782           return true;
2783 
2784       sfk = special_function_p (decl);
2785       ctype = DECL_CONTEXT (decl);
2786       loc = input_location;
2787       input_location = DECL_SOURCE_LOCATION (decl);
2788 
2789       informed = false;
2790       if (LAMBDA_TYPE_P (ctype))
2791           {
2792             informed = true;
2793             if (sfk == sfk_constructor)
2794               inform (DECL_SOURCE_LOCATION (decl),
2795                         "a lambda closure type has a deleted default constructor");
2796             else if (sfk == sfk_copy_assignment)
2797               inform (DECL_SOURCE_LOCATION (decl),
2798                         "a lambda closure type has a deleted copy assignment operator");
2799             else
2800               informed = false;
2801           }
2802       else if (DECL_ARTIFICIAL (decl)
2803                  && (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
2804                  && classtype_has_move_assign_or_move_ctor_p (ctype, true))
2805           {
2806             inform (DECL_SOURCE_LOCATION (decl),
2807                       "%q#D is implicitly declared as deleted because %qT "
2808                       "declares a move constructor or move assignment operator",
2809                       decl, ctype);
2810             informed = true;
2811           }
2812       else if (sfk == sfk_inheriting_constructor)
2813           {
2814             tree binfo = inherited_ctor_binfo (decl);
2815             if (TREE_CODE (binfo) != TREE_BINFO)
2816               {
2817                 inform (DECL_SOURCE_LOCATION (decl),
2818                           "%q#D inherits from multiple base subobjects",
2819                           decl);
2820                 informed = true;
2821               }
2822           }
2823       if (!informed && sfk == sfk_comparison)
2824           {
2825             inform (DECL_SOURCE_LOCATION (decl),
2826                       "%q#D is implicitly deleted because the default "
2827                       "definition would be ill-formed:", decl);
2828             build_comparison_op (decl, false, tf_warning_or_error);
2829           }
2830       else if (!informed)
2831           {
2832             tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
2833             bool const_p = false;
2834             if (parms)
2835               {
2836                 tree parm_type = TREE_VALUE (parms);
2837                 const_p = CP_TYPE_CONST_P (non_reference (parm_type));
2838               }
2839             tree raises = NULL_TREE;
2840             bool deleted_p = false;
2841             tree scope = push_scope (ctype);
2842             tree inh = DECL_INHERITED_CTOR (decl);
2843 
2844             synthesized_method_walk (ctype, sfk, const_p,
2845                                            &raises, NULL, &deleted_p, NULL, false,
2846                                            &inh, parms);
2847             if (deleted_p)
2848               {
2849                 inform (DECL_SOURCE_LOCATION (decl),
2850                           "%q#D is implicitly deleted because the default "
2851                           "definition would be ill-formed:", decl);
2852                 synthesized_method_walk (ctype, sfk, const_p,
2853                                                NULL, NULL, &deleted_p, NULL, true,
2854                                                &inh, parms);
2855               }
2856             else if (!comp_except_specs
2857                        (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
2858                         raises, ce_normal))
2859               inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly "
2860                         "deleted because its exception-specification does not "
2861                         "match the implicit exception-specification %qX",
2862                         decl, raises);
2863             else if (flag_checking)
2864               gcc_unreachable ();
2865 
2866             pop_scope (scope);
2867           }
2868 
2869       input_location = loc;
2870       return true;
2871     }
2872   return false;
2873 }
2874 
2875 /* DECL is a defaulted function which was declared constexpr.  Explain why
2876    it can't be constexpr.  */
2877 
2878 void
explain_implicit_non_constexpr(tree decl)2879 explain_implicit_non_constexpr (tree decl)
2880 {
2881   tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
2882   bool const_p = CP_TYPE_CONST_P (non_reference (TREE_VALUE (parms)));
2883   tree inh = DECL_INHERITED_CTOR (decl);
2884   bool dummy;
2885   special_function_kind sfk = special_function_p (decl);
2886   if (sfk == sfk_comparison)
2887     {
2888       DECL_DECLARED_CONSTEXPR_P (decl) = true;
2889       build_comparison_op (decl, false, tf_warning_or_error);
2890       DECL_DECLARED_CONSTEXPR_P (decl) = false;
2891     }
2892   else
2893     synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
2894                                    sfk, const_p,
2895                                    NULL, NULL, NULL, &dummy, true,
2896                                    &inh, parms);
2897 }
2898 
2899 /* DECL is an instantiation of an inheriting constructor template.  Deduce
2900    the correct exception-specification and deletedness for this particular
2901    specialization.  Return true if the deduction succeeds; false otherwise.  */
2902 
2903 bool
deduce_inheriting_ctor(tree decl)2904 deduce_inheriting_ctor (tree decl)
2905 {
2906   decl = DECL_ORIGIN (decl);
2907   gcc_assert (DECL_INHERITED_CTOR (decl));
2908   tree spec;
2909   bool trivial, constexpr_, deleted;
2910   tree inh = DECL_INHERITED_CTOR (decl);
2911   synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
2912                                  false, &spec, &trivial, &deleted, &constexpr_,
2913                                  /*diag*/false,
2914                                  &inh,
2915                                  FUNCTION_FIRST_USER_PARMTYPE (decl));
2916   if (spec == error_mark_node)
2917     return false;
2918   if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO)
2919     /* Inherited the same constructor from different base subobjects.  */
2920     deleted = true;
2921   DECL_DELETED_FN (decl) = deleted;
2922   TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
2923   SET_DECL_INHERITED_CTOR (decl, inh);
2924 
2925   tree clone;
2926   FOR_EACH_CLONE (clone, decl)
2927     {
2928       DECL_DELETED_FN (clone) = deleted;
2929       TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
2930       SET_DECL_INHERITED_CTOR (clone, inh);
2931     }
2932 
2933   return true;
2934 }
2935 
2936 /* Implicitly declare the special function indicated by KIND, as a
2937    member of TYPE.  For copy constructors and assignment operators,
2938    CONST_P indicates whether these functions should take a const
2939    reference argument or a non-const reference.
2940    Returns the FUNCTION_DECL for the implicitly declared function.  */
2941 
2942 tree
implicitly_declare_fn(special_function_kind kind,tree type,bool const_p,tree pattern_fn,tree inherited_parms)2943 implicitly_declare_fn (special_function_kind kind, tree type,
2944                            bool const_p, tree pattern_fn,
2945                            tree inherited_parms)
2946 {
2947   tree fn;
2948   tree parameter_types = void_list_node;
2949   tree return_type;
2950   tree fn_type;
2951   tree raises = empty_except_spec;
2952   tree rhs_parm_type = NULL_TREE;
2953   tree this_parm;
2954   tree name;
2955   HOST_WIDE_INT saved_processing_template_decl;
2956   bool deleted_p = false;
2957   bool constexpr_p = false;
2958   tree inherited_ctor = (kind == sfk_inheriting_constructor
2959                                ? pattern_fn : NULL_TREE);
2960 
2961   /* Because we create declarations for implicitly declared functions
2962      lazily, we may be creating the declaration for a member of TYPE
2963      while in some completely different context.  However, TYPE will
2964      never be a dependent class (because we never want to do lookups
2965      for implicitly defined functions in a dependent class).  */
2966   gcc_assert (!dependent_type_p (type));
2967 
2968   /* If the member-specification does not explicitly declare any member or
2969      friend named operator==, an == operator function is declared
2970      implicitly for each three-way comparison operator function defined as
2971      defaulted in the member-specification, with the same access and
2972      function-definition and in the same class scope as the respective
2973      three-way comparison operator function, except that the return type is
2974      replaced with bool and the declarator-id is replaced with
2975      operator==.
2976 
2977      [Note: Such an implicitly-declared == operator for a class X is
2978      defined as defaulted in the definition of X and has the same
2979      parameter-declaration-clause and trailing requires-clause as the
2980      respective three-way comparison operator. It is declared with friend,
2981      virtual, constexpr, or consteval if the three-way comparison operator
2982      function is so declared. If the three-way comparison operator function
2983      has no noexcept-specifier, the implicitly-declared == operator
2984      function has an implicit exception specification (14.5) that may
2985      differ from the implicit exception specification of the three-way
2986      comparison operator function. --end note]  */
2987   if (kind == sfk_comparison)
2988     {
2989       fn = copy_operator_fn (pattern_fn, EQ_EXPR);
2990       DECL_ARTIFICIAL (fn) = 1;
2991       TREE_TYPE (fn) = change_return_type (boolean_type_node, TREE_TYPE (fn));
2992       return fn;
2993     }
2994 
2995   /* Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
2996      because we only create clones for constructors and destructors
2997      when not in a template.  */
2998   saved_processing_template_decl = processing_template_decl;
2999   processing_template_decl = 0;
3000 
3001   type = TYPE_MAIN_VARIANT (type);
3002 
3003   if (targetm.cxx.cdtor_returns_this ())
3004     {
3005       if (kind == sfk_destructor)
3006           /* See comment in check_special_function_return_type.  */
3007           return_type = build_pointer_type (void_type_node);
3008       else
3009           return_type = build_pointer_type (type);
3010     }
3011   else
3012     return_type = void_type_node;
3013 
3014   int this_quals = TYPE_UNQUALIFIED;
3015   switch (kind)
3016     {
3017     case sfk_destructor:
3018       /* Destructor.  */
3019       name = dtor_identifier;
3020       break;
3021 
3022     case sfk_constructor:
3023       /* Default constructor.  */
3024       name = ctor_identifier;
3025       break;
3026 
3027     case sfk_copy_constructor:
3028     case sfk_copy_assignment:
3029     case sfk_move_constructor:
3030     case sfk_move_assignment:
3031     case sfk_inheriting_constructor:
3032     {
3033       if (kind == sfk_copy_assignment
3034             || kind == sfk_move_assignment)
3035           {
3036             return_type = build_reference_type (type);
3037             name = assign_op_identifier;
3038           }
3039       else
3040           name = ctor_identifier;
3041 
3042       if (kind == sfk_inheriting_constructor)
3043           parameter_types = inherited_parms;
3044       else
3045           {
3046             if (const_p)
3047               rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
3048             else
3049               rhs_parm_type = type;
3050             bool move_p = (kind == sfk_move_assignment
3051                                || kind == sfk_move_constructor);
3052             rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
3053 
3054             parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
3055           }
3056       break;
3057     }
3058 
3059     default:
3060       gcc_unreachable ();
3061     }
3062 
3063   bool trivial_p = false;
3064 
3065   if (inherited_ctor)
3066     {
3067       /* For an inheriting constructor, just copy these flags from the
3068            inherited constructor until deduce_inheriting_ctor.  */
3069       raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
3070       deleted_p = DECL_DELETED_FN (inherited_ctor);
3071       constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
3072     }
3073   else if (cxx_dialect >= cxx11)
3074     {
3075       raises = noexcept_deferred_spec;
3076       synthesized_method_walk (type, kind, const_p, NULL, &trivial_p,
3077                                      &deleted_p, &constexpr_p, false,
3078                                      &inherited_ctor, inherited_parms);
3079     }
3080   else
3081     synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
3082                                    &deleted_p, &constexpr_p, false,
3083                                    &inherited_ctor, inherited_parms);
3084   /* Don't bother marking a deleted constructor as constexpr.  */
3085   if (deleted_p)
3086     constexpr_p = false;
3087   /* A trivial copy/move constructor is also a constexpr constructor,
3088      unless the class has virtual bases (7.1.5p4).  */
3089   else if (trivial_p
3090              && cxx_dialect >= cxx11
3091              && (kind == sfk_copy_constructor
3092                  || kind == sfk_move_constructor)
3093              && !CLASSTYPE_VBASECLASSES (type))
3094     gcc_assert (constexpr_p);
3095 
3096   if (!trivial_p && type_has_trivial_fn (type, kind))
3097     type_set_nontrivial_flag (type, kind);
3098 
3099   /* Create the function.  */
3100   tree this_type = cp_build_qualified_type (type, this_quals);
3101   fn_type = build_method_type_directly (this_type, return_type,
3102                                                   parameter_types);
3103 
3104   if (raises)
3105     {
3106       if (raises != error_mark_node)
3107           fn_type = build_exception_variant (fn_type, raises);
3108       else
3109           {
3110             /* Can happen, e.g., in C++98 mode for an ill-formed non-static data
3111                member initializer (c++/89914).  Also, in C++98, we might have
3112                failed to deduce RAISES, so try again but complain this time.  */
3113             if (cxx_dialect < cxx11)
3114               synthesized_method_walk (type, kind, const_p, &raises, nullptr,
3115                                              nullptr, nullptr, /*diag=*/true,
3116                                              &inherited_ctor, inherited_parms);
3117             /* We should have seen an error at this point.  */
3118             gcc_assert (seen_error ());
3119           }
3120     }
3121   fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
3122   if (kind != sfk_inheriting_constructor)
3123     DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
3124 
3125   if (IDENTIFIER_OVL_OP_P (name))
3126     {
3127       const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (name);
3128       DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) = op->ovl_op_code;
3129     }
3130   else if (IDENTIFIER_CTOR_P (name))
3131     DECL_CXX_CONSTRUCTOR_P (fn) = true;
3132   else if (IDENTIFIER_DTOR_P (name))
3133     DECL_CXX_DESTRUCTOR_P (fn) = true;
3134   else
3135     gcc_unreachable ();
3136 
3137   SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
3138 
3139   /* Create the explicit arguments.  */
3140   if (rhs_parm_type)
3141     {
3142       /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
3143            want its type to be included in the mangled function
3144            name.  */
3145       tree decl = cp_build_parm_decl (fn, NULL_TREE, rhs_parm_type);
3146       TREE_READONLY (decl) = 1;
3147       retrofit_lang_decl (decl);
3148       DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
3149       DECL_ARGUMENTS (fn) = decl;
3150     }
3151   else if (kind == sfk_inheriting_constructor)
3152     {
3153       tree *p = &DECL_ARGUMENTS (fn);
3154       int index = 1;
3155       for (tree parm = inherited_parms; parm && parm != void_list_node;
3156              parm = TREE_CHAIN (parm))
3157           {
3158             *p = cp_build_parm_decl (fn, NULL_TREE, TREE_VALUE (parm));
3159             retrofit_lang_decl (*p);
3160             DECL_PARM_LEVEL (*p) = 1;
3161             DECL_PARM_INDEX (*p) = index++;
3162             p = &DECL_CHAIN (*p);
3163           }
3164       SET_DECL_INHERITED_CTOR (fn, inherited_ctor);
3165       DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
3166       /* A constructor so declared has the same access as the corresponding
3167            constructor in X.  */
3168       TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
3169       TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
3170       /* Copy constexpr from the inherited constructor even if the
3171            inheriting constructor doesn't satisfy the requirements.  */
3172       constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
3173     }
3174 
3175   /* Add the "this" parameter.  */
3176   this_parm = build_this_parm (fn, fn_type, this_quals);
3177   DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
3178   DECL_ARGUMENTS (fn) = this_parm;
3179 
3180   grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
3181 
3182   DECL_IN_AGGR_P (fn) = 1;
3183   DECL_ARTIFICIAL (fn) = 1;
3184   DECL_DEFAULTED_FN (fn) = 1;
3185   if (cxx_dialect >= cxx11)
3186     {
3187       DECL_DELETED_FN (fn) = deleted_p;
3188       DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
3189     }
3190   DECL_EXTERNAL (fn) = true;
3191   DECL_NOT_REALLY_EXTERN (fn) = 1;
3192   DECL_DECLARED_INLINE_P (fn) = 1;
3193   set_linkage_according_to_type (type, fn);
3194   if (TREE_PUBLIC (fn))
3195     DECL_COMDAT (fn) = 1;
3196   rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
3197   gcc_assert (!TREE_USED (fn));
3198 
3199   /* Propagate constraints from the inherited constructor. */
3200   if (flag_concepts && inherited_ctor)
3201     if (tree orig_ci = get_constraints (inherited_ctor))
3202       {
3203         tree new_ci = copy_node (orig_ci);
3204         set_constraints (fn, new_ci);
3205       }
3206 
3207   /* Restore PROCESSING_TEMPLATE_DECL.  */
3208   processing_template_decl = saved_processing_template_decl;
3209 
3210   if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
3211     fn = add_inherited_template_parms (fn, inherited_ctor);
3212 
3213   /* Warn about calling a non-trivial move assignment in a virtual base.  */
3214   if (kind == sfk_move_assignment && !deleted_p && !trivial_p
3215       && CLASSTYPE_VBASECLASSES (type))
3216     {
3217       location_t loc = input_location;
3218       input_location = DECL_SOURCE_LOCATION (fn);
3219       synthesized_method_walk (type, kind, const_p,
3220                                      NULL, NULL, NULL, NULL, true,
3221                                      NULL, NULL_TREE);
3222       input_location = loc;
3223     }
3224 
3225   return fn;
3226 }
3227 
3228 /* Gives any errors about defaulted functions which need to be deferred
3229    until the containing class is complete.  */
3230 
3231 void
defaulted_late_check(tree fn)3232 defaulted_late_check (tree fn)
3233 {
3234   /* Complain about invalid signature for defaulted fn.  */
3235   tree ctx = DECL_CONTEXT (fn);
3236   special_function_kind kind = special_function_p (fn);
3237 
3238   if (kind == sfk_comparison)
3239     {
3240       /* If the function was declared constexpr, check that the definition
3241            qualifies.  Otherwise we can define the function lazily.  */
3242       if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn))
3243           {
3244             /* Prevent GC.  */
3245             function_depth++;
3246             synthesize_method (fn);
3247             function_depth--;
3248           }
3249       return;
3250     }
3251 
3252   bool fn_const_p = (copy_fn_p (fn) == 2);
3253   tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
3254                                                       NULL, NULL);
3255   tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
3256 
3257   if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
3258                         TREE_TYPE (TREE_TYPE (implicit_fn)))
3259       || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
3260                          TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
3261     {
3262       error ("defaulted declaration %q+D does not match the "
3263                "expected signature", fn);
3264       inform (DECL_SOURCE_LOCATION (fn),
3265                 "expected signature: %qD", implicit_fn);
3266     }
3267 
3268   if (DECL_DELETED_FN (implicit_fn))
3269     {
3270       DECL_DELETED_FN (fn) = 1;
3271       return;
3272     }
3273 
3274   /* If a function is explicitly defaulted on its first declaration without an
3275      exception-specification, it is implicitly considered to have the same
3276      exception-specification as if it had been implicitly declared.  */
3277   if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
3278       && DECL_DEFAULTED_IN_CLASS_P (fn))
3279     TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
3280 
3281   if (DECL_DEFAULTED_IN_CLASS_P (fn)
3282       && DECL_DECLARED_CONSTEXPR_P (implicit_fn))
3283     {
3284       /* Hmm...should we do this for out-of-class too? Should it be OK to
3285            add constexpr later like inline, rather than requiring
3286            declarations to match?  */
3287       DECL_DECLARED_CONSTEXPR_P (fn) = true;
3288       if (kind == sfk_constructor)
3289           TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
3290     }
3291 
3292   if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
3293       && DECL_DECLARED_CONSTEXPR_P (fn))
3294     {
3295       if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
3296           {
3297             error ("explicitly defaulted function %q+D cannot be declared "
3298                      "%qs because the implicit declaration is not %qs:", fn,
3299                      DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr",
3300                      "constexpr");
3301             explain_implicit_non_constexpr (fn);
3302           }
3303       DECL_DECLARED_CONSTEXPR_P (fn) = false;
3304     }
3305 }
3306 
3307 /* Returns true iff FN can be explicitly defaulted, and gives any
3308    errors if defaulting FN is ill-formed.  */
3309 
3310 bool
defaultable_fn_check(tree fn)3311 defaultable_fn_check (tree fn)
3312 {
3313   special_function_kind kind = sfk_none;
3314 
3315   if (template_parm_scope_p ())
3316     {
3317       error ("a template cannot be defaulted");
3318       return false;
3319     }
3320 
3321   if (DECL_CONSTRUCTOR_P (fn))
3322     {
3323       if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
3324           kind = sfk_constructor;
3325       else if (copy_fn_p (fn) > 0
3326                  && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
3327                        == void_list_node))
3328           kind = sfk_copy_constructor;
3329       else if (move_fn_p (fn))
3330           kind = sfk_move_constructor;
3331     }
3332   else if (DECL_DESTRUCTOR_P (fn))
3333     kind = sfk_destructor;
3334   else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
3335              && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
3336     {
3337       if (copy_fn_p (fn))
3338           kind = sfk_copy_assignment;
3339       else if (move_fn_p (fn))
3340           kind = sfk_move_assignment;
3341     }
3342   else if (DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) >= OVL_OP_EQ_EXPR
3343              && DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) <= OVL_OP_SPACESHIP_EXPR)
3344     {
3345       kind = sfk_comparison;
3346       if (!early_check_defaulted_comparison (fn))
3347           return false;
3348     }
3349 
3350   if (kind == sfk_none)
3351     {
3352       error ("%qD cannot be defaulted", fn);
3353       return false;
3354     }
3355   else
3356     {
3357       for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
3358              t && t != void_list_node; t = TREE_CHAIN (t))
3359           if (TREE_PURPOSE (t))
3360             {
3361               error ("defaulted function %q+D with default argument", fn);
3362               break;
3363             }
3364 
3365       /* Avoid do_warn_unused_parameter warnings.  */
3366       for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p))
3367           if (DECL_NAME (p))
3368             suppress_warning (p, OPT_Wunused_parameter);
3369 
3370       if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
3371           /* Defer checking.  */;
3372       else if (!processing_template_decl)
3373           defaulted_late_check (fn);
3374 
3375       return true;
3376     }
3377 }
3378 
3379 /* Add an implicit declaration to TYPE for the kind of function
3380    indicated by SFK.  Return the FUNCTION_DECL for the new implicit
3381    declaration.  */
3382 
3383 tree
lazily_declare_fn(special_function_kind sfk,tree type)3384 lazily_declare_fn (special_function_kind sfk, tree type)
3385 {
3386   tree fn;
3387   /* Whether or not the argument has a const reference type.  */
3388   bool const_p = false;
3389 
3390   type = TYPE_MAIN_VARIANT (type);
3391 
3392   switch (sfk)
3393     {
3394     case sfk_constructor:
3395       CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
3396       break;
3397     case sfk_copy_constructor:
3398       const_p = TYPE_HAS_CONST_COPY_CTOR (type);
3399       CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
3400       break;
3401     case sfk_move_constructor:
3402       CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
3403       break;
3404     case sfk_copy_assignment:
3405       const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
3406       CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
3407       break;
3408     case sfk_move_assignment:
3409       CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
3410       break;
3411     case sfk_destructor:
3412       CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
3413       break;
3414     default:
3415       gcc_unreachable ();
3416     }
3417 
3418   /* Declare the function.  */
3419   fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);
3420 
3421   /* [class.copy]/8 If the class definition declares a move constructor or
3422      move assignment operator, the implicitly declared copy constructor is
3423      defined as deleted.... */
3424   if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
3425       && cxx_dialect >= cxx11)
3426     {
3427       if (classtype_has_move_assign_or_move_ctor_p (type, true))
3428           DECL_DELETED_FN (fn) = true;
3429       else if (classtype_has_depr_implicit_copy (type))
3430           /* The implicit definition of a copy constructor as defaulted is
3431              deprecated if the class has a user-declared copy assignment operator
3432              or a user-declared destructor. The implicit definition of a copy
3433              assignment operator as defaulted is deprecated if the class has a
3434              user-declared copy constructor or a user-declared destructor (15.4,
3435              15.8).  */
3436           TREE_DEPRECATED (fn) = true;
3437     }
3438 
3439   /* Destructors and assignment operators may be virtual.  */
3440   if (sfk == sfk_destructor
3441       || sfk == sfk_move_assignment
3442       || sfk == sfk_copy_assignment)
3443     check_for_override (fn, type);
3444 
3445   /* Add it to the class  */
3446   bool added = add_method (type, fn, false);
3447   gcc_assert (added || errorcount);
3448 
3449   /* Add it to TYPE_FIELDS.  */
3450   if (sfk == sfk_destructor
3451       && DECL_VIRTUAL_P (fn))
3452     /* The ABI requires that a virtual destructor go at the end of the
3453        vtable.  */
3454     TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
3455   else
3456     {
3457       DECL_CHAIN (fn) = TYPE_FIELDS (type);
3458       TYPE_FIELDS (type) = fn;
3459     }
3460   /* Propagate TYPE_FIELDS.  */
3461   fixup_type_variants (type);
3462 
3463   maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
3464   if (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
3465     /* Create appropriate clones.  */
3466     clone_cdtor (fn, /*update_methods=*/true);
3467 
3468   return fn;
3469 }
3470 
3471 /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
3472    as there are artificial parms in FN.  */
3473 
3474 tree
skip_artificial_parms_for(const_tree fn,tree list)3475 skip_artificial_parms_for (const_tree fn, tree list)
3476 {
3477   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
3478     list = TREE_CHAIN (list);
3479   else
3480     return list;
3481 
3482   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
3483     list = TREE_CHAIN (list);
3484   if (DECL_HAS_VTT_PARM_P (fn))
3485     list = TREE_CHAIN (list);
3486   return list;
3487 }
3488 
3489 /* Given a FUNCTION_DECL FN and a chain LIST, return the number of
3490    artificial parms in FN.  */
3491 
3492 int
num_artificial_parms_for(const_tree fn)3493 num_artificial_parms_for (const_tree fn)
3494 {
3495   int count = 0;
3496 
3497   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
3498     count++;
3499   else
3500     return 0;
3501 
3502   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
3503     count++;
3504   if (DECL_HAS_VTT_PARM_P (fn))
3505     count++;
3506   return count;
3507 }
3508 
3509 
3510 #include "gt-cp-method.h"
3511