1/* Handle the hair of processing (but not expanding) inline functions.
2 Also manage function and variable name overloading.
3 Copyright (C) 1987-2024 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann (tiemann@cygnus.com)
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along 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
36static void do_build_copy_assign (tree);
37static void do_build_copy_constructor (tree);
38static tree make_alias_for_thunk (tree);
39
40/* Called once to initialize method.cc. */
41
42void
43init_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
57tree
58make_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
145void
146finish_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
183static GTY (()) int thunk_labelno;
184
185/* Create a static alias to target. */
186
187tree
188make_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
226static tree
227make_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 (target: function, get_identifier (buf));
236
237 if (!flag_syntax_only)
238 {
239 struct cgraph_node *funcn, *aliasn;
240 funcn = cgraph_node::get (decl: function);
241 gcc_checking_assert (funcn);
242 aliasn = cgraph_node::create_same_body_alias (alias, decl: 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
254void
255use_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 (thunk_fndecl: 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 (decl: function))
340 && symbol->alias)
341 {
342 if (symbol->analyzed)
343 fn = symtab_node::get (decl: function)->ultimate_alias_target ()->decl;
344 else
345 fn = symtab_node::get (decl: 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 (decl: thunk_fndecl)->implicit_section
356 = symtab_node::get (decl: 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 (decl: function);
376 gcc_checking_assert (funcn);
377 thunk_node = funcn->create_thunk (alias: thunk_fndecl, function,
378 this_adjusting, fixed_offset, virtual_value,
379 indirect_offset: 0, virtual_offset, real_alias: alias);
380 if (DECL_ONE_ONLY (function))
381 thunk_node->add_to_same_comdat_group (old_node: 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
390static bool
391type_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
419static void
420type_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
450bool
451trivial_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), sfk: 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
467tree
468forward_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
487tree
488strip_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
505static tree inherited_ctor_binfo (tree, tree);
506static tree
507inherited_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
522static tree
523inherited_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, fndecl: *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
545tree
546inherited_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
559bool
560base_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 (fndecl: 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
588bool
589ctor_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
603static bool
604binfo_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 (binfo: 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
629static tree
630add_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), init_binfo: 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
664static void
665do_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 (fn: 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 = cp_build_init_expr (current_class_ref, i: 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 = cp_build_init_expr (t: lhs, i: 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 (v: vbases, ix: i, ptr: &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 (binfo: 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
786static void
787do_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 (fn: 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 we are building a defaulted xobj copy/move assignment operator then
799 current_class_ref will not have been set up.
800 Kind of an icky hack, but what can ya do? */
801 tree const class_ref = DECL_XOBJ_MEMBER_FUNCTION_P (fndecl)
802 ? cp_build_fold_indirect_ref (DECL_ARGUMENTS (fndecl)) : current_class_ref;
803
804 if (trivial
805 && is_empty_class (current_class_type))
806 /* Don't copy the padding byte; it might not have been allocated
807 if *this is a base subobject. */;
808 else if (trivial)
809 {
810 tree t = build2 (MODIFY_EXPR, void_type_node, class_ref, parm);
811 finish_expr_stmt (t);
812 }
813 else
814 {
815 tree fields;
816 int cvquals = cp_type_quals (TREE_TYPE (parm));
817 int i;
818 tree binfo, base_binfo;
819
820 /* Assign to each of the direct base classes. */
821 for (binfo = TYPE_BINFO (current_class_type), i = 0;
822 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
823 {
824 tree converted_parm;
825
826 /* We must convert PARM directly to the base class
827 explicitly since the base class may be ambiguous. */
828 converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
829 tf_warning_or_error);
830 if (move_p)
831 converted_parm = move (converted_parm);
832 /* Call the base class assignment operator. */
833 releasing_vec parmvec (make_tree_vector_single (converted_parm));
834 finish_expr_stmt
835 (build_special_member_call (class_ref,
836 assign_op_identifier,
837 &parmvec,
838 base_binfo,
839 flags,
840 tf_warning_or_error));
841 }
842
843 /* Assign to each of the non-static data members. */
844 for (fields = TYPE_FIELDS (current_class_type);
845 fields;
846 fields = DECL_CHAIN (fields))
847 {
848 tree comp = class_ref;
849 tree init = parm;
850 tree field = fields;
851 tree expr_type;
852 int quals;
853
854 if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
855 continue;
856
857 expr_type = TREE_TYPE (field);
858
859 if (CP_TYPE_CONST_P (expr_type))
860 {
861 error ("non-static const member %q#D, cannot use default "
862 "assignment operator", field);
863 continue;
864 }
865 else if (TYPE_REF_P (expr_type))
866 {
867 error ("non-static reference member %q#D, cannot use "
868 "default assignment operator", field);
869 continue;
870 }
871
872 if (DECL_NAME (field))
873 {
874 if (VFIELD_NAME_P (DECL_NAME (field)))
875 continue;
876 }
877 else if (ANON_AGGR_TYPE_P (expr_type)
878 && TYPE_FIELDS (expr_type) != NULL_TREE)
879 /* Just use the field; anonymous types can't have
880 nontrivial copy ctors or assignment ops or this
881 function would be deleted. */;
882 else
883 continue;
884
885 comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);
886
887 /* Compute the type of init->field */
888 quals = cvquals;
889 if (DECL_MUTABLE_P (field))
890 quals &= ~TYPE_QUAL_CONST;
891 expr_type = cp_build_qualified_type (expr_type, quals);
892
893 init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
894 if (move_p && !TYPE_REF_P (expr_type)
895 /* 'move' breaks bit-fields, and has no effect for scalars. */
896 && !scalarish_type_p (expr_type))
897 init = move (init);
898
899 if (DECL_NAME (field))
900 init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
901 tf_warning_or_error);
902 else
903 init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
904 finish_expr_stmt (init);
905 }
906 }
907 finish_return_stmt (class_ref);
908 finish_compound_stmt (compound_stmt);
909}
910
911/* C++20 <compare> comparison category types. */
912
913enum comp_cat_tag
914{
915 cc_partial_ordering,
916 cc_weak_ordering,
917 cc_strong_ordering,
918 cc_last
919};
920
921/* Names of the comparison categories and their value members, to be indexed by
922 comp_cat_tag enumerators. genericize_spaceship below relies on the ordering
923 of the members. */
924
925struct comp_cat_info_t
926{
927 const char *name;
928 const char *members[4];
929};
930static const comp_cat_info_t comp_cat_info[cc_last]
931= {
932 { .name: "partial_ordering", .members: { "equivalent", "greater", "less", "unordered" } },
933 { .name: "weak_ordering", .members: { "equivalent", "greater", "less" } },
934 { .name: "strong_ordering", .members: { "equal", "greater", "less" } }
935};
936
937/* A cache of the category types to speed repeated lookups. */
938
939static GTY((deletable)) tree comp_cat_cache[cc_last];
940
941/* Look up one of the result variables in the comparison category type. */
942
943static tree
944lookup_comparison_result (tree type, const char *name_str,
945 tsubst_flags_t complain = tf_warning_or_error)
946{
947 tree name = get_identifier (name_str);
948 tree decl = lookup_qualified_name (scope: type, name);
949 if (TREE_CODE (decl) != VAR_DECL)
950 {
951 if (complain & tf_error)
952 {
953 auto_diagnostic_group d;
954 if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
955 qualified_name_lookup_error (type, name, decl, input_location);
956 else
957 error ("%qD is not a static data member", decl);
958 inform (input_location, "determining value of %qs", "operator<=>");
959 }
960 return error_mark_node;
961 }
962 return decl;
963}
964
965/* Look up a <compare> comparison category type in std. */
966
967static tree
968lookup_comparison_category (comp_cat_tag tag,
969 tsubst_flags_t complain = tf_warning_or_error)
970{
971 if (tree cached = comp_cat_cache[tag])
972 return cached;
973
974 tree name = get_identifier (comp_cat_info[tag].name);
975 tree decl = lookup_qualified_name (std_node, name);
976 if (TREE_CODE (decl) != TYPE_DECL)
977 {
978 if (complain & tf_error)
979 {
980 auto_diagnostic_group d;
981 if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
982 qualified_name_lookup_error (std_node, name, decl, input_location);
983 else
984 error ("%qD is not a type", decl);
985 inform (input_location, "forming type of %qs", "operator<=>");
986 }
987 return error_mark_node;
988 }
989 /* Also make sure we can look up the value members now, since we won't
990 really use them until genericize time. */
991 tree type = TREE_TYPE (decl);
992 for (int i = 0; i < 4; ++i)
993 {
994 const char *p = comp_cat_info[tag].members[i];
995 if (!p) break;
996 if (lookup_comparison_result (type, name_str: p, complain)
997 == error_mark_node)
998 return error_mark_node;
999 }
1000 return comp_cat_cache[tag] = type;
1001}
1002
1003/* Wrapper that takes the tag rather than the type. */
1004
1005static tree
1006lookup_comparison_result (comp_cat_tag tag, const char *name_str,
1007 tsubst_flags_t complain = tf_warning_or_error)
1008{
1009 tree type = lookup_comparison_category (tag, complain);
1010 return lookup_comparison_result (type, name_str, complain);
1011}
1012
1013/* Wrapper that takes the index into the members array instead of the name. */
1014
1015static tree
1016lookup_comparison_result (comp_cat_tag tag, tree type, int idx)
1017{
1018 const char *name_str = comp_cat_info[tag].members[idx];
1019 if (!name_str)
1020 return NULL_TREE;
1021 return lookup_comparison_result (type, name_str);
1022}
1023
1024/* Does TYPE correspond to TAG? */
1025
1026static bool
1027is_cat (tree type, comp_cat_tag tag)
1028{
1029 tree name = TYPE_LINKAGE_IDENTIFIER (type);
1030 return id_equal (id: name, str: comp_cat_info[tag].name);
1031}
1032
1033/* Return the comp_cat_tag for TYPE. */
1034
1035static comp_cat_tag
1036cat_tag_for (tree type)
1037{
1038 if (!CLASS_TYPE_P (type) || !decl_in_std_namespace_p (TYPE_MAIN_DECL (type)))
1039 return cc_last;
1040 for (int i = 0; i < cc_last; ++i)
1041 {
1042 comp_cat_tag tag = (comp_cat_tag)i;
1043 if (is_cat (type, tag))
1044 return tag;
1045 }
1046 return cc_last;
1047}
1048
1049/* Return the comparison category tag of a <=> expression with non-class type
1050 OPTYPE. */
1051
1052static comp_cat_tag
1053spaceship_comp_cat (tree optype)
1054{
1055 if (INTEGRAL_OR_ENUMERATION_TYPE_P (optype) || TYPE_PTROBV_P (optype))
1056 return cc_strong_ordering;
1057 else if (SCALAR_FLOAT_TYPE_P (optype))
1058 return cc_partial_ordering;
1059
1060 /* ??? should vector <=> produce a vector of one of the above? */
1061 gcc_unreachable ();
1062}
1063
1064/* Return the comparison category type of a <=> expression with non-class type
1065 OPTYPE. */
1066
1067tree
1068spaceship_type (tree optype, tsubst_flags_t complain)
1069{
1070 comp_cat_tag tag = spaceship_comp_cat (optype);
1071 return lookup_comparison_category (tag, complain);
1072}
1073
1074/* Turn <=> with type TYPE and operands OP0 and OP1 into GENERIC.
1075 This is also used by build_comparison_op for fallback to op< and op==
1076 in a defaulted op<=>. */
1077
1078tree
1079genericize_spaceship (location_t loc, tree type, tree op0, tree op1)
1080{
1081 /* ??? maybe optimize based on knowledge of representation? */
1082 comp_cat_tag tag = cat_tag_for (type);
1083
1084 if (tag == cc_last && is_auto (type))
1085 {
1086 /* build_comparison_op is checking to see if we want to suggest changing
1087 the op<=> return type from auto to a specific comparison category; any
1088 category will do for now. */
1089 tag = cc_strong_ordering;
1090 type = lookup_comparison_category (tag, complain: tf_none);
1091 if (type == error_mark_node)
1092 return error_mark_node;
1093 }
1094
1095 gcc_checking_assert (tag < cc_last);
1096
1097 tree r;
1098 bool scalar = SCALAR_TYPE_P (TREE_TYPE (op0));
1099 if (scalar)
1100 {
1101 op0 = save_expr (op0);
1102 op1 = save_expr (op1);
1103 }
1104
1105 tree gt = lookup_comparison_result (tag, type, idx: 1);
1106
1107 int flags = LOOKUP_NORMAL;
1108 tsubst_flags_t complain = tf_none;
1109 tree comp;
1110
1111 if (tag == cc_partial_ordering)
1112 {
1113 /* op0 == op1 ? equivalent : op0 < op1 ? less :
1114 op1 < op0 ? greater : unordered */
1115 tree uo = lookup_comparison_result (tag, type, idx: 3);
1116 if (scalar)
1117 {
1118 /* For scalars use the low level operations; using build_new_op causes
1119 trouble with constexpr eval in the middle of genericize (100367). */
1120 comp = fold_build2 (LT_EXPR, boolean_type_node, op1, op0);
1121 r = fold_build3 (COND_EXPR, type, comp, gt, uo);
1122 }
1123 else
1124 {
1125 comp = build_new_op (loc, code: LT_EXPR, flags, arg1: op1, arg2: op0, complain);
1126 r = build_conditional_expr (loc, comp, gt, uo, complain);
1127 }
1128 }
1129 else
1130 /* op0 == op1 ? equal : op0 < op1 ? less : greater */
1131 r = gt;
1132
1133 tree lt = lookup_comparison_result (tag, type, idx: 2);
1134 if (scalar)
1135 {
1136 comp = fold_build2 (LT_EXPR, boolean_type_node, op0, op1);
1137 r = fold_build3 (COND_EXPR, type, comp, lt, r);
1138 }
1139 else
1140 {
1141 comp = build_new_op (loc, code: LT_EXPR, flags, arg1: op0, arg2: op1, complain);
1142 r = build_conditional_expr (loc, comp, lt, r, complain);
1143 }
1144
1145 tree eq = lookup_comparison_result (tag, type, idx: 0);
1146 if (scalar)
1147 {
1148 comp = fold_build2 (EQ_EXPR, boolean_type_node, op0, op1);
1149 r = fold_build3 (COND_EXPR, type, comp, eq, r);
1150 }
1151 else
1152 {
1153 comp = build_new_op (loc, code: EQ_EXPR, flags, arg1: op0, arg2: op1, complain);
1154 r = build_conditional_expr (loc, comp, eq, r, complain);
1155 }
1156
1157 return r;
1158}
1159
1160/* Check that the signature of a defaulted comparison operator is
1161 well-formed. */
1162
1163static bool
1164early_check_defaulted_comparison (tree fn)
1165{
1166 location_t loc = DECL_SOURCE_LOCATION (fn);
1167 tree ctx;
1168 if (DECL_CLASS_SCOPE_P (fn))
1169 ctx = DECL_CONTEXT (fn);
1170 else
1171 ctx = DECL_FRIEND_CONTEXT (fn);
1172 bool ok = true;
1173
1174 if (cxx_dialect < cxx20)
1175 {
1176 error_at (loc, "defaulted %qD only available with %<-std=c++20%> or "
1177 "%<-std=gnu++20%>", fn);
1178 return false;
1179 }
1180
1181 if (!DECL_OVERLOADED_OPERATOR_IS (fn, SPACESHIP_EXPR)
1182 && !same_type_p (TREE_TYPE (TREE_TYPE (fn)), boolean_type_node))
1183 {
1184 diagnostic_t kind = DK_UNSPECIFIED;
1185 int opt = 0;
1186 if (is_auto (TREE_TYPE (fn)))
1187 kind = DK_PEDWARN;
1188 else
1189 kind = DK_ERROR;
1190 emit_diagnostic (kind, loc, opt,
1191 "defaulted %qD must return %<bool%>", fn);
1192 if (kind == DK_ERROR)
1193 ok = false;
1194 }
1195
1196 bool mem = DECL_IOBJ_MEMBER_FUNCTION_P (fn);
1197 if (mem && type_memfn_quals (TREE_TYPE (fn)) != TYPE_QUAL_CONST)
1198 {
1199 error_at (loc, "defaulted %qD must be %<const%>", fn);
1200 ok = false;
1201 }
1202 if (mem && type_memfn_rqual (TREE_TYPE (fn)) == REF_QUAL_RVALUE)
1203 {
1204 error_at (loc, "defaulted %qD must not have %<&&%> ref-qualifier", fn);
1205 ok = false;
1206 }
1207 tree parmnode = FUNCTION_FIRST_USER_PARMTYPE (fn);
1208 bool saw_byval = false;
1209 bool saw_byref = mem;
1210 bool saw_bad = false;
1211 for (; parmnode != void_list_node; parmnode = TREE_CHAIN (parmnode))
1212 {
1213 tree parmtype = TREE_VALUE (parmnode);
1214 if (CLASS_TYPE_P (parmtype))
1215 saw_byval = true;
1216 else if (TREE_CODE (parmtype) == REFERENCE_TYPE
1217 && !TYPE_REF_IS_RVALUE (parmtype)
1218 && TYPE_QUALS (TREE_TYPE (parmtype)) == TYPE_QUAL_CONST)
1219 {
1220 saw_byref = true;
1221 parmtype = TREE_TYPE (parmtype);
1222 }
1223 else
1224 saw_bad = true;
1225
1226 if (!saw_bad && !ctx)
1227 {
1228 /* Defaulted outside the class body. */
1229 ctx = TYPE_MAIN_VARIANT (parmtype);
1230 if (!is_friend (ctx, fn))
1231 {
1232 auto_diagnostic_group d;
1233 error_at (loc, "defaulted %qD is not a friend of %qT", fn, ctx);
1234 inform (location_of (ctx), "declared here");
1235 ok = false;
1236 }
1237 }
1238 else if (!same_type_ignoring_top_level_qualifiers_p (parmtype, ctx))
1239 saw_bad = true;
1240 }
1241
1242 if (saw_bad || (saw_byval && saw_byref))
1243 {
1244 if (DECL_IOBJ_MEMBER_FUNCTION_P (fn))
1245 error_at (loc, "defaulted member %qD must have parameter type "
1246 "%<const %T&%>", fn, ctx);
1247 else if (saw_bad)
1248 error_at (loc, "defaulted %qD must have parameters of either type "
1249 "%<const %T&%> or %qT", fn, ctx, ctx);
1250 else
1251 error_at (loc, "defaulted %qD must have parameters of either type "
1252 "%<const %T&%> or %qT, not both", fn, ctx, ctx);
1253 ok = false;
1254 }
1255
1256 /* We still need to deduce deleted/constexpr/noexcept and maybe return. */
1257 DECL_MAYBE_DELETED (fn) = ok;
1258
1259 return ok;
1260}
1261
1262/* Subroutine of build_comparison_op. Given the vec of memberwise
1263 comparisons COMPS, calculate the overall comparison category for
1264 operator<=>. */
1265
1266static tree
1267common_comparison_type (vec<tree> &comps)
1268{
1269 tree seen[cc_last] = {};
1270
1271 for (unsigned i = 0; i < comps.length(); ++i)
1272 {
1273 tree comp = comps[i];
1274 if (TREE_CODE (comp) == TREE_LIST)
1275 comp = TREE_VALUE (comp);
1276 tree ctype = TREE_TYPE (comp);
1277 comp_cat_tag tag = cat_tag_for (type: ctype);
1278 /* build_comparison_op already checked this. */
1279 gcc_checking_assert (tag < cc_last);
1280 seen[tag] = ctype;
1281 }
1282
1283 /* Otherwise, if at least one T i is std::partial_ordering, U is
1284 std::partial_ordering. */
1285 if (tree t = seen[cc_partial_ordering]) return t;
1286
1287 /* Otherwise, if at least one T i is std::weak_ordering, U is
1288 std::weak_ordering. */
1289 if (tree t = seen[cc_weak_ordering]) return t;
1290
1291 /* Otherwise, U is std::strong_ordering. */
1292 if (tree t = seen[cc_strong_ordering]) return t;
1293 return lookup_comparison_category (tag: cc_strong_ordering);
1294}
1295
1296/* Data structure for build_comparison_op. */
1297
1298struct comp_info
1299{
1300 tree fndecl;
1301 location_t loc;
1302 tsubst_flags_t complain;
1303 tree_code code;
1304 comp_cat_tag retcat;
1305 bool first_time;
1306 bool constexp;
1307 bool was_constexp;
1308 bool noex;
1309
1310 comp_info (tree fndecl, tsubst_flags_t complain)
1311 : fndecl (fndecl), complain (complain)
1312 {
1313 loc = DECL_SOURCE_LOCATION (fndecl);
1314
1315 first_time = DECL_MAYBE_DELETED (fndecl);
1316 DECL_MAYBE_DELETED (fndecl) = false;
1317
1318 /* Do we want to try to set constexpr? */
1319 was_constexp = DECL_DECLARED_CONSTEXPR_P (fndecl);
1320 constexp = first_time;
1321 if (constexp)
1322 /* Set this for var_in_constexpr_fn. */
1323 DECL_DECLARED_CONSTEXPR_P (fndecl) = true;
1324
1325 /* Do we want to try to set noexcept? */
1326 noex = first_time;
1327 if (noex)
1328 {
1329 tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
1330 if (raises && !UNEVALUATED_NOEXCEPT_SPEC_P (raises))
1331 /* There was an explicit exception-specification. */
1332 noex = false;
1333 }
1334 }
1335
1336 /* EXPR is an expression built as part of the function body.
1337 Adjust the properties appropriately. */
1338 void check (tree expr)
1339 {
1340 if (expr == error_mark_node)
1341 DECL_DELETED_FN (fndecl) = true;
1342 if ((constexp || was_constexp)
1343 && !potential_rvalue_constant_expression (expr))
1344 {
1345 if (was_constexp)
1346 require_potential_rvalue_constant_expression_fncheck (expr);
1347 else
1348 constexp = false;
1349 }
1350 if (noex && !expr_noexcept_p (expr, tf_none))
1351 noex = false;
1352 }
1353
1354 ~comp_info ()
1355 {
1356 if (first_time)
1357 {
1358 DECL_DECLARED_CONSTEXPR_P (fndecl) = constexp || was_constexp;
1359 tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fndecl));
1360 if (!raises || UNEVALUATED_NOEXCEPT_SPEC_P (raises))
1361 {
1362 raises = noex ? noexcept_true_spec : noexcept_false_spec;
1363 TREE_TYPE (fndecl) = build_exception_variant (TREE_TYPE (fndecl),
1364 raises);
1365 }
1366 }
1367 }
1368};
1369
1370/* Subroutine of build_comparison_op, to compare a single subobject. */
1371
1372static tree
1373do_one_comp (location_t loc, const comp_info &info, tree sub, tree lhs, tree rhs)
1374{
1375 const tree_code code = info.code;
1376 const tree fndecl = info.fndecl;
1377 const comp_cat_tag retcat = info.retcat;
1378 const tsubst_flags_t complain = info.complain;
1379
1380 tree overload = NULL_TREE;
1381 int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
1382 /* If we have an explicit comparison category return type we can fall back
1383 to </=, so don't give an error yet if <=> lookup fails. */
1384 bool tentative = retcat != cc_last;
1385 tree comp = build_new_op (loc, code, flags, lhs, rhs,
1386 NULL_TREE, NULL_TREE, &overload,
1387 tentative ? tf_none : complain);
1388
1389 if (code != SPACESHIP_EXPR)
1390 return comp;
1391
1392 tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
1393
1394 if (comp == error_mark_node)
1395 {
1396 if (overload == NULL_TREE && (tentative || complain))
1397 {
1398 /* No viable <=>, try using op< and op==. */
1399 tree lteq = genericize_spaceship (loc, type: rettype, op0: lhs, op1: rhs);
1400 if (lteq != error_mark_node)
1401 {
1402 /* We found usable < and ==. */
1403 if (retcat != cc_last)
1404 /* Return type is a comparison category, use them. */
1405 comp = lteq;
1406 else if (complain & tf_error)
1407 /* Return type is auto, suggest changing it. */
1408 inform (info.loc, "changing the return type from %qs "
1409 "to a comparison category type will allow the "
1410 "comparison to use %qs and %qs", "auto",
1411 "operator<", "operator==");
1412 }
1413 else if (tentative && complain)
1414 /* No usable < and ==, give an error for op<=>. */
1415 build_new_op (loc, code, flags, arg1: lhs, arg2: rhs, complain);
1416 }
1417 if (comp == error_mark_node)
1418 return error_mark_node;
1419 }
1420
1421 if (FNDECL_USED_AUTO (fndecl)
1422 && cat_tag_for (TREE_TYPE (comp)) == cc_last)
1423 {
1424 /* The operator function is defined as deleted if ... Ri is not a
1425 comparison category type. */
1426 if (complain & tf_error)
1427 inform (loc,
1428 "three-way comparison of %qD has type %qT, not a "
1429 "comparison category type", sub, TREE_TYPE (comp));
1430 return error_mark_node;
1431 }
1432 else if (!FNDECL_USED_AUTO (fndecl)
1433 && !can_convert (rettype, TREE_TYPE (comp), complain))
1434 {
1435 if (complain & tf_error)
1436 error_at (loc,
1437 "three-way comparison of %qD has type %qT, which "
1438 "does not convert to %qT",
1439 sub, TREE_TYPE (comp), rettype);
1440 return error_mark_node;
1441 }
1442
1443 return comp;
1444}
1445
1446/* Build up the definition of a defaulted comparison operator. Unlike other
1447 defaulted functions that use synthesized_method_walk to determine whether
1448 the function is e.g. deleted, for comparisons we use the same code. We try
1449 to use synthesize_method at the earliest opportunity and bail out if the
1450 function ends up being deleted. */
1451
1452void
1453build_comparison_op (tree fndecl, bool defining, tsubst_flags_t complain)
1454{
1455 comp_info info (fndecl, complain);
1456
1457 if (!defining && !(complain & tf_error) && !DECL_MAYBE_DELETED (fndecl))
1458 return;
1459
1460 int flags = LOOKUP_NORMAL;
1461 const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (DECL_NAME (fndecl));
1462 tree_code code = info.code = op->tree_code;
1463
1464 tree lhs = DECL_ARGUMENTS (fndecl);
1465 tree rhs = DECL_CHAIN (lhs);
1466 if (is_this_parameter (lhs))
1467 lhs = cp_build_fold_indirect_ref (lhs);
1468 else
1469 lhs = convert_from_reference (lhs);
1470 rhs = convert_from_reference (rhs);
1471 tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
1472 gcc_assert (!defining || COMPLETE_TYPE_P (ctype));
1473
1474 iloc_sentinel ils (info.loc);
1475
1476 /* A defaulted comparison operator function for class C is defined as
1477 deleted if ... C has variant members. */
1478 if (TREE_CODE (ctype) == UNION_TYPE
1479 && next_aggregate_field (TYPE_FIELDS (ctype)))
1480 {
1481 if (complain & tf_error)
1482 inform (info.loc, "cannot default compare union %qT", ctype);
1483 DECL_DELETED_FN (fndecl) = true;
1484 return;
1485 }
1486
1487 tree compound_stmt = NULL_TREE;
1488 if (defining)
1489 compound_stmt = begin_compound_stmt (0);
1490 else
1491 ++cp_unevaluated_operand;
1492
1493 tree rettype = TREE_TYPE (TREE_TYPE (fndecl));
1494 if (code != SPACESHIP_EXPR && is_auto (rettype))
1495 {
1496 rettype = boolean_type_node;
1497 apply_deduced_return_type (fndecl, rettype);
1498 }
1499
1500 if (code == EQ_EXPR || code == SPACESHIP_EXPR)
1501 {
1502 comp_cat_tag &retcat = (info.retcat = cc_last);
1503 if (code == SPACESHIP_EXPR && !FNDECL_USED_AUTO (fndecl))
1504 retcat = cat_tag_for (type: rettype);
1505
1506 bool bad = false;
1507 auto_vec<tree> comps;
1508
1509 /* Compare the base subobjects. We handle them this way, rather than in
1510 the field loop below, because maybe_instantiate_noexcept might bring
1511 us here before we've built the base fields. */
1512 for (tree base_binfo : BINFO_BASE_BINFOS (TYPE_BINFO (ctype)))
1513 {
1514 tree lhs_base
1515 = build_base_path (PLUS_EXPR, lhs, base_binfo, 0, complain);
1516 tree rhs_base
1517 = build_base_path (PLUS_EXPR, rhs, base_binfo, 0, complain);
1518
1519 location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (ctype));
1520 tree comp = do_one_comp (loc, info, BINFO_TYPE (base_binfo),
1521 lhs: lhs_base, rhs: rhs_base);
1522 if (comp == error_mark_node)
1523 {
1524 bad = true;
1525 continue;
1526 }
1527
1528 comps.safe_push (obj: comp);
1529 }
1530
1531 /* Now compare the field subobjects. */
1532 for (tree field = next_aggregate_field (TYPE_FIELDS (ctype));
1533 field;
1534 field = next_aggregate_field (DECL_CHAIN (field)))
1535 {
1536 if (DECL_VIRTUAL_P (field) || DECL_FIELD_IS_BASE (field))
1537 /* We ignore the vptr, and we already handled bases. */
1538 continue;
1539
1540 tree expr_type = TREE_TYPE (field);
1541
1542 location_t field_loc = DECL_SOURCE_LOCATION (field);
1543
1544 /* A defaulted comparison operator function for class C is defined as
1545 deleted if any non-static data member of C is of reference type or
1546 C has variant members. */
1547 if (TREE_CODE (expr_type) == REFERENCE_TYPE)
1548 {
1549 if (complain & tf_error)
1550 inform (field_loc, "cannot default compare "
1551 "reference member %qD", field);
1552 bad = true;
1553 continue;
1554 }
1555 else if (ANON_UNION_TYPE_P (expr_type)
1556 && next_aggregate_field (TYPE_FIELDS (expr_type)))
1557 {
1558 if (complain & tf_error)
1559 inform (field_loc, "cannot default compare "
1560 "anonymous union member");
1561 bad = true;
1562 continue;
1563 }
1564
1565 tree lhs_mem = build3_loc (loc: field_loc, code: COMPONENT_REF, type: expr_type, arg0: lhs,
1566 arg1: field, NULL_TREE);
1567 tree rhs_mem = build3_loc (loc: field_loc, code: COMPONENT_REF, type: expr_type, arg0: rhs,
1568 arg1: field, NULL_TREE);
1569 tree loop_indexes = NULL_TREE;
1570 while (TREE_CODE (expr_type) == ARRAY_TYPE)
1571 {
1572 /* Flexible array member. */
1573 if (TYPE_DOMAIN (expr_type) == NULL_TREE
1574 || TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type)) == NULL_TREE)
1575 {
1576 if (complain & tf_error)
1577 inform (field_loc, "cannot default compare "
1578 "flexible array member");
1579 bad = true;
1580 break;
1581 }
1582 tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (expr_type));
1583 /* [0] array. No subobjects to compare, just skip it. */
1584 if (integer_all_onesp (maxval))
1585 break;
1586 tree idx;
1587 /* [1] array, no loop needed, just add [0] ARRAY_REF.
1588 Similarly if !defining. */
1589 if (integer_zerop (maxval) || !defining)
1590 idx = size_zero_node;
1591 /* Some other array, will need runtime loop. */
1592 else
1593 {
1594 idx = force_target_expr (sizetype, maxval, complain);
1595 loop_indexes = tree_cons (idx, NULL_TREE, loop_indexes);
1596 }
1597 expr_type = TREE_TYPE (expr_type);
1598 lhs_mem = build4_loc (loc: field_loc, code: ARRAY_REF, type: expr_type, arg0: lhs_mem,
1599 arg1: idx, NULL_TREE, NULL_TREE);
1600 rhs_mem = build4_loc (loc: field_loc, code: ARRAY_REF, type: expr_type, arg0: rhs_mem,
1601 arg1: idx, NULL_TREE, NULL_TREE);
1602 }
1603 if (TREE_CODE (expr_type) == ARRAY_TYPE)
1604 continue;
1605
1606 tree comp = do_one_comp (loc: field_loc, info, sub: field, lhs: lhs_mem, rhs: rhs_mem);
1607 if (comp == error_mark_node)
1608 {
1609 bad = true;
1610 continue;
1611 }
1612
1613 /* Most of the time, comp is the expression that should be evaluated
1614 to compare the two members. If the expression needs to be
1615 evaluated more than once in a loop, it will be a TREE_LIST
1616 instead, whose TREE_VALUE is the expression for one array element,
1617 TREE_PURPOSE is innermost iterator temporary and if the array
1618 is multidimensional, TREE_CHAIN will contain another TREE_LIST
1619 with second innermost iterator in its TREE_PURPOSE and so on. */
1620 if (loop_indexes)
1621 {
1622 TREE_VALUE (loop_indexes) = comp;
1623 comp = loop_indexes;
1624 }
1625 comps.safe_push (obj: comp);
1626 }
1627 if (code == SPACESHIP_EXPR && is_auto (rettype))
1628 {
1629 rettype = common_comparison_type (comps);
1630 apply_deduced_return_type (fndecl, rettype);
1631 }
1632 if (bad)
1633 {
1634 DECL_DELETED_FN (fndecl) = true;
1635 goto out;
1636 }
1637 for (unsigned i = 0; i < comps.length(); ++i)
1638 {
1639 tree comp = comps[i];
1640 tree eq, retval = NULL_TREE, if_ = NULL_TREE;
1641 tree loop_indexes = NULL_TREE;
1642 if (defining)
1643 {
1644 if (TREE_CODE (comp) == TREE_LIST)
1645 {
1646 loop_indexes = comp;
1647 comp = TREE_VALUE (comp);
1648 loop_indexes = nreverse (loop_indexes);
1649 for (tree loop_index = loop_indexes; loop_index;
1650 loop_index = TREE_CHAIN (loop_index))
1651 {
1652 tree for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
1653 tree idx = TREE_PURPOSE (loop_index);
1654 tree maxval = TARGET_EXPR_INITIAL (idx);
1655 TARGET_EXPR_INITIAL (idx) = size_zero_node;
1656 add_stmt (idx);
1657 finish_init_stmt (for_stmt);
1658 finish_for_cond (build2 (LE_EXPR, boolean_type_node, idx,
1659 maxval), for_stmt, false, 0,
1660 false);
1661 finish_for_expr (cp_build_unary_op (PREINCREMENT_EXPR,
1662 TARGET_EXPR_SLOT (idx),
1663 false, complain),
1664 for_stmt);
1665 /* Store in TREE_VALUE the for_stmt tree, so that we can
1666 later on call finish_for_stmt on it (in the reverse
1667 order). */
1668 TREE_VALUE (loop_index) = for_stmt;
1669 }
1670 loop_indexes = nreverse (loop_indexes);
1671 }
1672 if_ = begin_if_stmt ();
1673 }
1674 /* Spaceship is specified to use !=, but for the comparison category
1675 types, != is equivalent to !(==), so let's use == directly. */
1676 if (code == EQ_EXPR)
1677 {
1678 /* if (x==y); else return false; */
1679 eq = comp;
1680 retval = boolean_false_node;
1681 }
1682 else
1683 {
1684 /* if (auto v = x<=>y, v == 0); else return v; */
1685 if (TREE_CODE (comp) == SPACESHIP_EXPR)
1686 TREE_TYPE (comp) = rettype;
1687 else
1688 comp = build_static_cast (input_location, rettype, comp,
1689 complain);
1690 info.check (expr: comp);
1691 if (defining)
1692 {
1693 tree var = create_temporary_var (rettype);
1694 DECL_NAME (var) = get_identifier ("retval");
1695 pushdecl (var);
1696 cp_finish_decl (var, comp, false, NULL_TREE, flags);
1697 comp = retval = var;
1698 }
1699 eq = build_new_op (info.loc, EQ_EXPR, flags, comp,
1700 integer_zero_node, NULL_TREE, NULL_TREE,
1701 NULL, complain);
1702 }
1703 tree ceq = contextual_conv_bool (eq, complain);
1704 info.check (expr: ceq);
1705 if (defining)
1706 {
1707 finish_if_stmt_cond (ceq, if_);
1708 finish_then_clause (if_);
1709 begin_else_clause (if_);
1710 finish_return_stmt (retval);
1711 finish_else_clause (if_);
1712 finish_if_stmt (if_);
1713 for (tree loop_index = loop_indexes; loop_index;
1714 loop_index = TREE_CHAIN (loop_index))
1715 finish_for_stmt (TREE_VALUE (loop_index));
1716 }
1717 }
1718 if (defining)
1719 {
1720 tree val;
1721 if (code == EQ_EXPR)
1722 val = boolean_true_node;
1723 else
1724 {
1725 tree seql = lookup_comparison_result (tag: cc_strong_ordering,
1726 name_str: "equal", complain);
1727 val = build_static_cast (input_location, rettype, seql,
1728 complain);
1729 }
1730 finish_return_stmt (val);
1731 }
1732 }
1733 else if (code == NE_EXPR)
1734 {
1735 tree comp = build_new_op (info.loc, EQ_EXPR, flags, lhs, rhs,
1736 NULL_TREE, NULL_TREE, NULL, complain);
1737 comp = contextual_conv_bool (comp, complain);
1738 info.check (expr: comp);
1739 if (defining)
1740 {
1741 tree neg = build1 (TRUTH_NOT_EXPR, boolean_type_node, comp);
1742 finish_return_stmt (neg);
1743 }
1744 }
1745 else
1746 {
1747 tree comp = build_new_op (info.loc, SPACESHIP_EXPR, flags, lhs, rhs,
1748 NULL_TREE, NULL_TREE, NULL, complain);
1749 tree comp2 = build_new_op (info.loc, code, flags, comp, integer_zero_node,
1750 NULL_TREE, NULL_TREE, NULL, complain);
1751 info.check (expr: comp2);
1752 if (defining)
1753 finish_return_stmt (comp2);
1754 }
1755
1756 out:
1757 if (defining)
1758 finish_compound_stmt (compound_stmt);
1759 else
1760 --cp_unevaluated_operand;
1761}
1762
1763/* True iff DECL is an implicitly-declared special member function with no real
1764 source location, so we can use its DECL_SOURCE_LOCATION to remember where we
1765 triggered its synthesis. */
1766
1767bool
1768decl_remember_implicit_trigger_p (tree decl)
1769{
1770 if (!DECL_ARTIFICIAL (decl))
1771 return false;
1772 special_function_kind sfk = special_function_p (decl);
1773 /* Inherited constructors have the location of their using-declaration, and
1774 operator== has the location of the corresponding operator<=>. */
1775 return (sfk != sfk_inheriting_constructor
1776 && sfk != sfk_comparison);
1777}
1778
1779/* Synthesize FNDECL, a non-static member function. */
1780
1781void
1782synthesize_method (tree fndecl)
1783{
1784 bool need_body = true;
1785 tree stmt;
1786 location_t save_input_location = input_location;
1787 int error_count = errorcount;
1788 int warning_count = warningcount + werrorcount;
1789 special_function_kind sfk = special_function_p (fndecl);
1790
1791 /* Reset the source location, we might have been previously
1792 deferred, and thus have saved where we were first needed. */
1793 if (decl_remember_implicit_trigger_p (decl: fndecl))
1794 DECL_SOURCE_LOCATION (fndecl)
1795 = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
1796
1797 /* If we've been asked to synthesize a clone, just synthesize the
1798 cloned function instead. Doing so will automatically fill in the
1799 body for the clone. */
1800 if (DECL_CLONED_FUNCTION_P (fndecl))
1801 fndecl = DECL_CLONED_FUNCTION (fndecl);
1802
1803 /* We may be in the middle of deferred access check. Disable
1804 it now. */
1805 push_deferring_access_checks (dk_no_deferred);
1806
1807 bool push_to_top = maybe_push_to_top_level (fndecl);
1808
1809 input_location = DECL_SOURCE_LOCATION (fndecl);
1810
1811 start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
1812 stmt = begin_function_body ();
1813
1814 if (DECL_ASSIGNMENT_OPERATOR_P (fndecl)
1815 && DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR))
1816 {
1817 do_build_copy_assign (fndecl);
1818 need_body = false;
1819 }
1820 else if (DECL_CONSTRUCTOR_P (fndecl))
1821 {
1822 tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
1823 if (arg_chain != void_list_node)
1824 do_build_copy_constructor (fndecl);
1825 else
1826 finish_mem_initializers (NULL_TREE);
1827 }
1828 else if (sfk == sfk_comparison)
1829 {
1830 /* Pass tf_none so the function is just deleted if there's a problem. */
1831 build_comparison_op (fndecl, defining: true, complain: tf_none);
1832 need_body = false;
1833 }
1834
1835 /* If we haven't yet generated the body of the function, just
1836 generate an empty compound statement. */
1837 if (need_body)
1838 {
1839 tree compound_stmt;
1840 compound_stmt = begin_compound_stmt (BCS_FN_BODY);
1841 finish_compound_stmt (compound_stmt);
1842 }
1843
1844 finish_function_body (stmt);
1845 finish_function (/*inline_p=*/false);
1846
1847 if (!DECL_DELETED_FN (fndecl))
1848 expand_or_defer_fn (fndecl);
1849
1850 input_location = save_input_location;
1851
1852 maybe_pop_from_top_level (push_to_top);
1853
1854 pop_deferring_access_checks ();
1855
1856 if (error_count != errorcount || warning_count != warningcount + werrorcount)
1857 if (DECL_ARTIFICIAL (fndecl))
1858 inform (input_location, "synthesized method %qD first required here",
1859 fndecl);
1860}
1861
1862/* Like synthesize_method, but don't actually synthesize defaulted comparison
1863 methods if their class is still incomplete. Just deduce the return
1864 type in that case. */
1865
1866void
1867maybe_synthesize_method (tree fndecl)
1868{
1869 if (special_function_p (fndecl) == sfk_comparison)
1870 {
1871 tree lhs = DECL_ARGUMENTS (fndecl);
1872 if (is_this_parameter (lhs))
1873 lhs = cp_build_fold_indirect_ref (lhs);
1874 else
1875 lhs = convert_from_reference (lhs);
1876 tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (lhs));
1877 if (!COMPLETE_TYPE_P (ctype))
1878 {
1879 push_deferring_access_checks (dk_no_deferred);
1880 build_comparison_op (fndecl, defining: false, complain: tf_none);
1881 pop_deferring_access_checks ();
1882 return;
1883 }
1884 }
1885 return synthesize_method (fndecl);
1886}
1887
1888/* Build a reference to type TYPE with cv-quals QUALS, which is an
1889 rvalue if RVALUE is true. */
1890
1891static tree
1892build_stub_type (tree type, int quals, bool rvalue)
1893{
1894 tree argtype = cp_build_qualified_type (type, quals);
1895 return cp_build_reference_type (argtype, rvalue);
1896}
1897
1898/* Build a dummy glvalue from dereferencing a dummy reference of type
1899 REFTYPE. */
1900
1901tree
1902build_stub_object (tree reftype)
1903{
1904 if (!TYPE_REF_P (reftype))
1905 reftype = cp_build_reference_type (reftype, /*rval*/true);
1906 tree stub = build1 (CONVERT_EXPR, reftype, integer_one_node);
1907 return convert_from_reference (stub);
1908}
1909
1910/* Build a std::declval<TYPE>() expression and return it. */
1911
1912tree
1913build_trait_object (tree type)
1914{
1915 /* TYPE can't be a function with cv-/ref-qualifiers: std::declval is
1916 defined as
1917
1918 template<class T>
1919 typename std::add_rvalue_reference<T>::type declval() noexcept;
1920
1921 and std::add_rvalue_reference yields T when T is a function with
1922 cv- or ref-qualifiers, making the definition ill-formed. */
1923 if (FUNC_OR_METHOD_TYPE_P (type)
1924 && (type_memfn_quals (type) != TYPE_UNQUALIFIED
1925 || type_memfn_rqual (type) != REF_QUAL_NONE))
1926 return error_mark_node;
1927
1928 return build_stub_object (reftype: type);
1929}
1930
1931/* Determine which function will be called when looking up NAME in TYPE,
1932 called with a single ARGTYPE argument, or no argument if ARGTYPE is
1933 null. FLAGS and COMPLAIN are as for build_new_method_call.
1934
1935 Returns a FUNCTION_DECL if all is well.
1936 Returns NULL_TREE if overload resolution failed.
1937 Returns error_mark_node if the chosen function cannot be called. */
1938
1939static tree
1940locate_fn_flags (tree type, tree name, tree argtype, int flags,
1941 tsubst_flags_t complain)
1942{
1943 tree ob, fn, fns, binfo, rval;
1944
1945 if (TYPE_P (type))
1946 binfo = TYPE_BINFO (type);
1947 else
1948 {
1949 binfo = type;
1950 type = BINFO_TYPE (binfo);
1951 }
1952
1953 ob = build_stub_object (reftype: cp_build_reference_type (type, false));
1954 releasing_vec args;
1955 if (argtype)
1956 {
1957 if (TREE_CODE (argtype) == TREE_LIST)
1958 {
1959 for (tree elt = argtype; elt && elt != void_list_node;
1960 elt = TREE_CHAIN (elt))
1961 {
1962 tree type = TREE_VALUE (elt);
1963 tree arg = build_stub_object (reftype: type);
1964 vec_safe_push (r&: args, t: arg);
1965 }
1966 }
1967 else
1968 {
1969 tree arg = build_stub_object (reftype: argtype);
1970 args->quick_push (obj: arg);
1971 }
1972 }
1973
1974 fns = lookup_fnfields (binfo, name, 0, complain);
1975 rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);
1976
1977 if (fn && rval == error_mark_node)
1978 return rval;
1979 else
1980 return fn;
1981}
1982
1983/* Locate the dtor of TYPE. */
1984
1985tree
1986get_dtor (tree type, tsubst_flags_t complain)
1987{
1988 tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
1989 LOOKUP_NORMAL, complain);
1990 if (fn == error_mark_node)
1991 return NULL_TREE;
1992 return fn;
1993}
1994
1995/* Locate the default ctor of TYPE. */
1996
1997tree
1998locate_ctor (tree type)
1999{
2000 tree fn;
2001
2002 push_deferring_access_checks (dk_no_check);
2003 fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
2004 LOOKUP_SPECULATIVE, complain: tf_none);
2005 pop_deferring_access_checks ();
2006 if (fn == error_mark_node)
2007 return NULL_TREE;
2008 return fn;
2009}
2010
2011/* Likewise, but give any appropriate errors. */
2012
2013tree
2014get_default_ctor (tree type)
2015{
2016 tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
2017 LOOKUP_NORMAL, complain: tf_warning_or_error);
2018 if (fn == error_mark_node)
2019 return NULL_TREE;
2020 return fn;
2021}
2022
2023/* Locate the copy ctor of TYPE. */
2024
2025tree
2026get_copy_ctor (tree type, tsubst_flags_t complain)
2027{
2028 int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
2029 ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
2030 tree argtype = build_stub_type (type, quals, rvalue: false);
2031 tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
2032 LOOKUP_NORMAL, complain);
2033 if (fn == error_mark_node)
2034 return NULL_TREE;
2035 return fn;
2036}
2037
2038/* Locate the copy assignment operator of TYPE. */
2039
2040tree
2041get_copy_assign (tree type)
2042{
2043 int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
2044 ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
2045 tree argtype = build_stub_type (type, quals, rvalue: false);
2046 tree fn = locate_fn_flags (type, assign_op_identifier, argtype,
2047 LOOKUP_NORMAL, complain: tf_warning_or_error);
2048 if (fn == error_mark_node)
2049 return NULL_TREE;
2050 return fn;
2051}
2052
2053/* walk_tree helper function for is_trivially_xible. If *TP is a call,
2054 return it if it calls something other than a trivial special member
2055 function. */
2056
2057static tree
2058check_nontriv (tree *tp, int *, void *)
2059{
2060 tree fn = cp_get_callee (*tp);
2061 if (fn == NULL_TREE)
2062 return NULL_TREE;
2063
2064 if (TREE_CODE (fn) == ADDR_EXPR)
2065 fn = TREE_OPERAND (fn, 0);
2066
2067 if (TREE_CODE (fn) != FUNCTION_DECL
2068 || !trivial_fn_p (fn))
2069 return fn;
2070 return NULL_TREE;
2071}
2072
2073/* Return declval<T>() = declval<U>() treated as an unevaluated operand. */
2074
2075static tree
2076assignable_expr (tree to, tree from)
2077{
2078 cp_unevaluated cp_uneval_guard;
2079 to = build_trait_object (type: to);
2080 from = build_trait_object (type: from);
2081 tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
2082 return r;
2083}
2084
2085/* The predicate condition for a template specialization
2086 is_constructible<T, Args...> shall be satisfied if and only if the
2087 following variable definition would be well-formed for some invented
2088 variable t: T t(create<Args>()...);
2089
2090 Return something equivalent in well-formedness and triviality. */
2091
2092static tree
2093constructible_expr (tree to, tree from)
2094{
2095 tree expr;
2096 cp_unevaluated cp_uneval_guard;
2097 const int len = TREE_VEC_LENGTH (from);
2098 if (CLASS_TYPE_P (to))
2099 {
2100 tree ctype = to;
2101 vec<tree, va_gc> *args = NULL;
2102 if (!TYPE_REF_P (to))
2103 to = cp_build_reference_type (to, /*rval*/false);
2104 tree ob = build_stub_object (reftype: to);
2105 if (len == 0)
2106 expr = build_value_init (ctype, tf_none);
2107 else
2108 {
2109 vec_alloc (v&: args, nelems: len);
2110 for (tree arg : tree_vec_range (from))
2111 args->quick_push (obj: build_stub_object (reftype: arg));
2112 expr = build_special_member_call (ob, complete_ctor_identifier, &args,
2113 ctype, LOOKUP_NORMAL, tf_none);
2114 }
2115 if (expr == error_mark_node)
2116 return error_mark_node;
2117 /* The current state of the standard vis-a-vis LWG 2116 is that
2118 is_*constructible involves destruction as well. */
2119 if (type_build_dtor_call (ctype))
2120 {
2121 tree dtor = build_special_member_call (ob, complete_dtor_identifier,
2122 NULL, ctype, LOOKUP_NORMAL,
2123 tf_none);
2124 if (dtor == error_mark_node)
2125 return error_mark_node;
2126 if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (ctype))
2127 expr = build2 (COMPOUND_EXPR, void_type_node, expr, dtor);
2128 }
2129 }
2130 else
2131 {
2132 if (len == 0)
2133 return build_value_init (strip_array_types (type: to), tf_none);
2134 if (len > 1)
2135 {
2136 if (cxx_dialect < cxx20)
2137 /* Too many initializers. */
2138 return error_mark_node;
2139
2140 /* In C++20 this is well-formed:
2141 using T = int[2];
2142 T t(1, 2);
2143 which means that std::is_constructible_v<int[2], int, int>
2144 should be true. */
2145 vec<constructor_elt, va_gc> *v;
2146 vec_alloc (v, nelems: len);
2147 for (tree arg : tree_vec_range (from))
2148 {
2149 tree stub = build_stub_object (reftype: arg);
2150 constructor_elt elt = { NULL_TREE, .value: stub };
2151 v->quick_push (obj: elt);
2152 }
2153 from = build_constructor (init_list_type_node, v);
2154 CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
2155 CONSTRUCTOR_IS_PAREN_INIT (from) = true;
2156 }
2157 else
2158 from = build_stub_object (TREE_VEC_ELT (from, 0));
2159 expr = perform_direct_initialization_if_possible (to, from,
2160 /*cast*/false,
2161 tf_none);
2162 /* If t(e) didn't work, maybe t{e} will. */
2163 if (expr == NULL_TREE
2164 && len == 1
2165 && cxx_dialect >= cxx20)
2166 {
2167 from = build_constructor_single (init_list_type_node, NULL_TREE,
2168 from);
2169 CONSTRUCTOR_IS_DIRECT_INIT (from) = true;
2170 CONSTRUCTOR_IS_PAREN_INIT (from) = true;
2171 expr = perform_direct_initialization_if_possible (to, from,
2172 /*cast*/false,
2173 tf_none);
2174 }
2175 }
2176 return expr;
2177}
2178
2179/* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or
2180 constructible (otherwise) from FROM, which is a single type for
2181 assignment or a list of types for construction. */
2182
2183static tree
2184is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
2185{
2186 to = complete_type (to);
2187 deferring_access_check_sentinel acs (dk_no_deferred);
2188 if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to)
2189 || (from && FUNC_OR_METHOD_TYPE_P (from)
2190 && (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from))))
2191 return error_mark_node;
2192 tree expr;
2193 if (code == MODIFY_EXPR)
2194 expr = assignable_expr (to, from);
2195 else if (trivial && TREE_VEC_LENGTH (from) > 1
2196 && cxx_dialect < cxx20)
2197 return error_mark_node; // only 0- and 1-argument ctors can be trivial
2198 // before C++20 aggregate paren init
2199 else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
2200 return error_mark_node; // can't construct an array of unknown bound
2201 else
2202 expr = constructible_expr (to, from);
2203 return expr;
2204}
2205
2206/* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or
2207 constructible (otherwise) from FROM, which is a single type for
2208 assignment or a list of types for construction. */
2209
2210bool
2211is_trivially_xible (enum tree_code code, tree to, tree from)
2212{
2213 tree expr = is_xible_helper (code, to, from, /*trivial*/true);
2214 if (expr == NULL_TREE || expr == error_mark_node)
2215 return false;
2216 tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
2217 return !nt;
2218}
2219
2220/* Returns true iff TO is nothrow assignable (if CODE is MODIFY_EXPR) or
2221 constructible (otherwise) from FROM, which is a single type for
2222 assignment or a list of types for construction. */
2223
2224bool
2225is_nothrow_xible (enum tree_code code, tree to, tree from)
2226{
2227 ++cp_noexcept_operand;
2228 tree expr = is_xible_helper (code, to, from, /*trivial*/false);
2229 --cp_noexcept_operand;
2230 if (expr == NULL_TREE || expr == error_mark_node)
2231 return false;
2232 return expr_noexcept_p (expr, tf_none);
2233}
2234
2235/* Returns true iff TO is assignable (if CODE is MODIFY_EXPR) or
2236 constructible (otherwise) from FROM, which is a single type for
2237 assignment or a list of types for construction. */
2238
2239bool
2240is_xible (enum tree_code code, tree to, tree from)
2241{
2242 tree expr = is_xible_helper (code, to, from, /*trivial*/false);
2243 if (expr == error_mark_node)
2244 return false;
2245 return !!expr;
2246}
2247
2248/* Return true iff conjunction_v<is_reference<T>, is_constructible<T, U>> is
2249 true, and the initialization
2250 T t(VAL<U>); // DIRECT_INIT_P
2251 or
2252 T t = VAL<U>; // !DIRECT_INIT_P
2253 binds t to a temporary object whose lifetime is extended.
2254 VAL<T> is defined in [meta.unary.prop]:
2255 -- If T is a reference or function type, VAL<T> is an expression with the
2256 same type and value category as declval<T>().
2257 -- Otherwise, VAL<T> is a prvalue that initially has type T. */
2258
2259bool
2260ref_xes_from_temporary (tree to, tree from, bool direct_init_p)
2261{
2262 /* Check is_reference<T>. */
2263 if (!TYPE_REF_P (to))
2264 return false;
2265 /* We don't check is_constructible<T, U>: if T isn't constructible
2266 from U, we won't be able to create a conversion. */
2267 tree val = build_trait_object (type: from);
2268 if (val == error_mark_node)
2269 return false;
2270 if (!TYPE_REF_P (from) && TREE_CODE (from) != FUNCTION_TYPE)
2271 val = CLASS_TYPE_P (from) ? force_rvalue (val, tf_none) : rvalue (val);
2272 return ref_conv_binds_to_temporary (to, val, direct_init_p).is_true ();
2273}
2274
2275/* Worker for is_{,nothrow_}convertible. Attempt to perform an implicit
2276 conversion from FROM to TO and return the result. */
2277
2278static tree
2279is_convertible_helper (tree from, tree to)
2280{
2281 if (VOID_TYPE_P (from) && VOID_TYPE_P (to))
2282 return integer_one_node;
2283 cp_unevaluated u;
2284 tree expr = build_trait_object (type: from);
2285 /* std::is_{,nothrow_}convertible test whether the imaginary function
2286 definition
2287
2288 To test() { return std::declval<From>(); }
2289
2290 is well-formed. A function can't return a function. */
2291 if (FUNC_OR_METHOD_TYPE_P (to) || expr == error_mark_node)
2292 return error_mark_node;
2293 deferring_access_check_sentinel acs (dk_no_deferred);
2294 return perform_implicit_conversion (to, expr, tf_none);
2295}
2296
2297/* Return true if FROM can be converted to TO using implicit conversions,
2298 or both FROM and TO are possibly cv-qualified void. NB: This doesn't
2299 implement the "Access checks are performed as if from a context unrelated
2300 to either type" restriction. */
2301
2302bool
2303is_convertible (tree from, tree to)
2304{
2305 tree expr = is_convertible_helper (from, to);
2306 if (expr == error_mark_node)
2307 return false;
2308 return !!expr;
2309}
2310
2311/* Like is_convertible, but the conversion is also noexcept. */
2312
2313bool
2314is_nothrow_convertible (tree from, tree to)
2315{
2316 tree expr = is_convertible_helper (from, to);
2317 if (expr == NULL_TREE || expr == error_mark_node)
2318 return false;
2319 return expr_noexcept_p (expr, tf_none);
2320}
2321
2322/* Categorize various special_function_kinds. */
2323#define SFK_CTOR_P(sfk) \
2324 ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
2325#define SFK_DTOR_P(sfk) \
2326 ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
2327#define SFK_ASSIGN_P(sfk) \
2328 ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
2329#define SFK_COPY_P(sfk) \
2330 ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
2331#define SFK_MOVE_P(sfk) \
2332 ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)
2333
2334/* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and
2335 DELETED_P or give an error message MSG with argument ARG. */
2336
2337static void
2338process_subob_fn (tree fn, special_function_kind sfk, tree *spec_p,
2339 bool *trivial_p, bool *deleted_p, bool *constexpr_p,
2340 bool diag, tree arg, bool dtor_from_ctor = false)
2341{
2342 if (!fn || fn == error_mark_node)
2343 {
2344 if (deleted_p)
2345 *deleted_p = true;
2346 return;
2347 }
2348
2349 if (spec_p)
2350 {
2351 if (!maybe_instantiate_noexcept (fn))
2352 *spec_p = error_mark_node;
2353 else
2354 {
2355 tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
2356 *spec_p = merge_exception_specifiers (*spec_p, raises);
2357 }
2358 }
2359
2360 if (!trivial_fn_p (fn) && !dtor_from_ctor)
2361 {
2362 if (trivial_p)
2363 *trivial_p = false;
2364 if (TREE_CODE (arg) == FIELD_DECL
2365 && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
2366 {
2367 if (deleted_p)
2368 *deleted_p = true;
2369 if (diag)
2370 error ("union member %q+D with non-trivial %qD", arg, fn);
2371 }
2372 }
2373
2374 if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
2375 {
2376 *constexpr_p = false;
2377 if (diag)
2378 {
2379 inform (DECL_SOURCE_LOCATION (fn),
2380 SFK_DTOR_P (sfk)
2381 ? G_("defaulted destructor calls non-%<constexpr%> %qD")
2382 : G_("defaulted constructor calls non-%<constexpr%> %qD"),
2383 fn);
2384 explain_invalid_constexpr_fn (fn);
2385 }
2386 }
2387}
2388
2389/* Subroutine of synthesized_method_walk to allow recursion into anonymous
2390 aggregates. If DTOR_FROM_CTOR is true, we're walking subobject destructors
2391 called from a synthesized constructor, in which case we don't consider
2392 the triviality of the subobject destructor. */
2393
2394static void
2395walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
2396 int quals, tree *spec_p, bool *trivial_p,
2397 bool *deleted_p, bool *constexpr_p,
2398 bool diag, int flags, tsubst_flags_t complain,
2399 bool dtor_from_ctor)
2400{
2401 if (!fields)
2402 return;
2403
2404 tree ctx = DECL_CONTEXT (fields);
2405
2406 /* CWG2084: A defaulted default ctor for a union with a DMI only initializes
2407 that member, so don't check other members. */
2408 enum { unknown, no, yes }
2409 only_dmi_mem = (sfk == sfk_constructor && TREE_CODE (ctx) == UNION_TYPE
2410 ? unknown : no);
2411
2412 again:
2413 for (tree field = fields; field; field = DECL_CHAIN (field))
2414 {
2415 tree mem_type, argtype, rval;
2416
2417 if (TREE_CODE (field) != FIELD_DECL
2418 || DECL_ARTIFICIAL (field)
2419 || DECL_UNNAMED_BIT_FIELD (field))
2420 continue;
2421
2422 /* Variant members only affect deletedness. In particular, they don't
2423 affect the exception-specification of a user-provided destructor,
2424 which we're figuring out via get_defaulted_eh_spec. So if we aren't
2425 asking if this is deleted, don't even look up the function; we don't
2426 want an error about a deleted function we aren't actually calling. */
2427 if (sfk == sfk_destructor && deleted_p == NULL
2428 && TREE_CODE (ctx) == UNION_TYPE)
2429 break;
2430
2431 if (only_dmi_mem != no)
2432 {
2433 if (DECL_INITIAL (field))
2434 only_dmi_mem = yes;
2435 else
2436 /* Don't check this until we know there's no DMI. */
2437 continue;
2438 }
2439
2440 mem_type = strip_array_types (TREE_TYPE (field));
2441 if (SFK_ASSIGN_P (sfk))
2442 {
2443 bool bad = true;
2444 if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
2445 {
2446 if (diag)
2447 error ("non-static const member %q#D, cannot use default "
2448 "assignment operator", field);
2449 }
2450 else if (TYPE_REF_P (mem_type))
2451 {
2452 if (diag)
2453 error ("non-static reference member %q#D, cannot use "
2454 "default assignment operator", field);
2455 }
2456 else
2457 bad = false;
2458
2459 if (bad && deleted_p)
2460 *deleted_p = true;
2461 }
2462 else if (sfk == sfk_constructor || sfk == sfk_inheriting_constructor)
2463 {
2464 bool bad;
2465
2466 if (DECL_INITIAL (field))
2467 {
2468 if (diag && DECL_INITIAL (field) == error_mark_node)
2469 inform (DECL_SOURCE_LOCATION (field),
2470 "initializer for %q#D is invalid", field);
2471 if (trivial_p)
2472 *trivial_p = false;
2473 /* Core 1351: If the field has an NSDMI that could throw, the
2474 default constructor is noexcept(false). */
2475 if (spec_p)
2476 {
2477 tree nsdmi = get_nsdmi (field, /*ctor*/false, complain);
2478 if (nsdmi == error_mark_node)
2479 *spec_p = error_mark_node;
2480 else if (*spec_p != error_mark_node
2481 && !expr_noexcept_p (nsdmi, tf_none))
2482 *spec_p = noexcept_false_spec;
2483 }
2484 /* Don't do the normal processing. */
2485 continue;
2486 }
2487
2488 bad = false;
2489 if (CP_TYPE_CONST_P (mem_type)
2490 && default_init_uninitialized_part (mem_type))
2491 {
2492 if (diag)
2493 {
2494 error ("uninitialized const member in %q#T",
2495 current_class_type);
2496 inform (DECL_SOURCE_LOCATION (field),
2497 "%q#D should be initialized", field);
2498 }
2499 bad = true;
2500 }
2501 else if (TYPE_REF_P (mem_type))
2502 {
2503 if (diag)
2504 {
2505 error ("uninitialized reference member in %q#T",
2506 current_class_type);
2507 inform (DECL_SOURCE_LOCATION (field),
2508 "%q#D should be initialized", field);
2509 }
2510 bad = true;
2511 }
2512
2513 if (bad && deleted_p)
2514 *deleted_p = true;
2515
2516 /* Before C++20, for an implicitly-defined default constructor to
2517 be constexpr, every member must have a user-provided default
2518 constructor or an explicit initializer. */
2519 if (constexpr_p
2520 && cxx_dialect < cxx20
2521 && !CLASS_TYPE_P (mem_type)
2522 && TREE_CODE (ctx) != UNION_TYPE)
2523 {
2524 *constexpr_p = false;
2525 if (diag)
2526 inform (DECL_SOURCE_LOCATION (field),
2527 "defaulted default constructor does not "
2528 "initialize %q#D", field);
2529 }
2530 }
2531 else if (sfk == sfk_copy_constructor)
2532 {
2533 /* 12.8p11b5 */
2534 if (TYPE_REF_P (mem_type)
2535 && TYPE_REF_IS_RVALUE (mem_type))
2536 {
2537 if (diag)
2538 error ("copying non-static data member %q#D of rvalue "
2539 "reference type", field);
2540 if (deleted_p)
2541 *deleted_p = true;
2542 }
2543 }
2544
2545 if (!CLASS_TYPE_P (mem_type))
2546 continue;
2547
2548 if (ANON_AGGR_TYPE_P (mem_type))
2549 {
2550 walk_field_subobs (TYPE_FIELDS (mem_type), sfk, fnname, quals,
2551 spec_p, trivial_p, deleted_p, constexpr_p,
2552 diag, flags, complain, dtor_from_ctor);
2553 continue;
2554 }
2555
2556 if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
2557 {
2558 int mem_quals = cp_type_quals (mem_type) | quals;
2559 if (DECL_MUTABLE_P (field))
2560 mem_quals &= ~TYPE_QUAL_CONST;
2561 argtype = build_stub_type (type: mem_type, quals: mem_quals, SFK_MOVE_P (sfk));
2562 }
2563 else
2564 argtype = NULL_TREE;
2565
2566 rval = locate_fn_flags (type: mem_type, name: fnname, argtype, flags, complain);
2567
2568 process_subob_fn (fn: rval, sfk, spec_p, trivial_p, deleted_p,
2569 constexpr_p, diag, arg: field, dtor_from_ctor);
2570 }
2571
2572 /* We didn't find a DMI in this union, now check all the members. */
2573 if (only_dmi_mem == unknown)
2574 {
2575 only_dmi_mem = no;
2576 goto again;
2577 }
2578}
2579
2580/* Base walker helper for synthesized_method_walk. Inspect a direct
2581 or virtual base. BINFO is the parent type's binfo. BASE_BINFO is
2582 the base binfo of interests. All other parms are as for
2583 synthesized_method_walk, or its local vars. */
2584
2585static tree
2586synthesized_method_base_walk (tree binfo, tree base_binfo,
2587 special_function_kind sfk, tree fnname, int quals,
2588 tree *inheriting_ctor, tree inherited_parms,
2589 int flags, bool diag,
2590 tree *spec_p, bool *trivial_p,
2591 bool *deleted_p, bool *constexpr_p)
2592{
2593 bool inherited_binfo = false;
2594 tree argtype = NULL_TREE;
2595 deferring_kind defer = dk_no_deferred;
2596
2597 if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
2598 argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, SFK_MOVE_P (sfk));
2599 else if (inheriting_ctor
2600 && (inherited_binfo
2601 = binfo_inherited_from (binfo, init_binfo: base_binfo, inh: *inheriting_ctor)))
2602 {
2603 argtype = inherited_parms;
2604 /* Don't check access on the inherited constructor. */
2605 if (flag_new_inheriting_ctors)
2606 defer = dk_deferred;
2607 }
2608 else if (cxx_dialect >= cxx14 && sfk == sfk_virtual_destructor
2609 && BINFO_VIRTUAL_P (base_binfo)
2610 && ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo)))
2611 /* Don't check access when looking at vbases of abstract class's
2612 virtual destructor. */
2613 defer = dk_no_check;
2614
2615 if (defer != dk_no_deferred)
2616 push_deferring_access_checks (defer);
2617 tree rval = locate_fn_flags (type: base_binfo, name: fnname, argtype, flags,
2618 complain: diag ? tf_warning_or_error : tf_none);
2619 if (defer != dk_no_deferred)
2620 pop_deferring_access_checks ();
2621
2622 /* Replace an inherited template with the appropriate specialization. */
2623 if (inherited_binfo && rval
2624 && DECL_P (*inheriting_ctor) && DECL_P (rval)
2625 && DECL_CONTEXT (*inheriting_ctor) == DECL_CONTEXT (rval))
2626 *inheriting_ctor = DECL_CLONED_FUNCTION (rval);
2627
2628 process_subob_fn (fn: rval, sfk, spec_p, trivial_p, deleted_p,
2629 constexpr_p, diag, BINFO_TYPE (base_binfo));
2630 if (SFK_CTOR_P (sfk)
2631 && (!BINFO_VIRTUAL_P (base_binfo)
2632 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
2633 {
2634 /* In a constructor we also need to check the subobject
2635 destructors for cleanup of partially constructed objects. */
2636 tree dtor = locate_fn_flags (type: base_binfo, complete_dtor_identifier,
2637 NULL_TREE, flags,
2638 complain: diag ? tf_warning_or_error : tf_none);
2639 /* Note that we don't pass down trivial_p; the subobject
2640 destructors don't affect triviality of the constructor. Nor
2641 do they affect constexpr-ness (a constant expression doesn't
2642 throw) or exception-specification (a throw from one of the
2643 dtors would be a double-fault). */
2644 process_subob_fn (fn: dtor, sfk, NULL, NULL, deleted_p, NULL, diag: false,
2645 BINFO_TYPE (base_binfo), /*dtor_from_ctor*/true);
2646 }
2647
2648 return rval;
2649}
2650
2651/* The caller wants to generate an implicit declaration of SFK for
2652 CTYPE which is const if relevant and CONST_P is set. If SPEC_P,
2653 TRIVIAL_P, DELETED_P or CONSTEXPR_P are non-null, set their
2654 referent appropriately. If DIAG is true, we're either being called
2655 from maybe_explain_implicit_delete to give errors, or if
2656 CONSTEXPR_P is non-null, from explain_invalid_constexpr_fn. */
2657
2658static void
2659synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
2660 tree *spec_p, bool *trivial_p, bool *deleted_p,
2661 bool *constexpr_p, bool diag,
2662 tree *inheriting_ctor, tree inherited_parms)
2663{
2664 tree binfo, base_binfo;
2665 int i;
2666
2667 /* SFK must be exactly one category. */
2668 gcc_checking_assert (SFK_DTOR_P(sfk) + SFK_CTOR_P(sfk)
2669 + SFK_ASSIGN_P(sfk) == 1);
2670
2671 if (spec_p)
2672 *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec);
2673
2674 if (deleted_p)
2675 {
2676 /* "The closure type associated with a lambda-expression has a deleted
2677 default constructor and a deleted copy assignment operator."
2678 This is diagnosed in maybe_explain_implicit_delete.
2679 In C++20, only lambda-expressions with lambda-captures have those
2680 deleted. */
2681 if (LAMBDA_TYPE_P (ctype)
2682 && (sfk == sfk_constructor || sfk == sfk_copy_assignment)
2683 && (cxx_dialect < cxx20
2684 || LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (ctype))
2685 || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE
2686 (CLASSTYPE_LAMBDA_EXPR (ctype)) != CPLD_NONE))
2687 {
2688 *deleted_p = true;
2689 return;
2690 }
2691
2692 *deleted_p = false;
2693 }
2694
2695 bool check_vdtor = false;
2696 tree fnname;
2697
2698 if (SFK_DTOR_P (sfk))
2699 {
2700 check_vdtor = true;
2701 /* The synthesized method will call base dtors, but check complete
2702 here to avoid having to deal with VTT. */
2703 fnname = complete_dtor_identifier;
2704 }
2705 else if (SFK_ASSIGN_P (sfk))
2706 fnname = assign_op_identifier;
2707 else
2708 fnname = complete_ctor_identifier;
2709
2710 gcc_assert ((sfk == sfk_inheriting_constructor)
2711 == (inheriting_ctor && *inheriting_ctor != NULL_TREE));
2712
2713 /* If that user-written default constructor would satisfy the
2714 requirements of a constexpr constructor (7.1.5), the
2715 implicitly-defined default constructor is constexpr.
2716
2717 C++20:
2718 The implicitly-defined copy/move assignment operator is constexpr if
2719 - X is a literal type, and
2720 - the assignment operator selected to copy/move each direct base class
2721 subobject is a constexpr function, and
2722 - for each non-static data member of X that is of class type (or array
2723 thereof), the assignment operator selected to copy/move that
2724 member is a constexpr function.
2725
2726 C++23:
2727 The implicitly-defined copy/move assignment operator is constexpr. */
2728 if (constexpr_p)
2729 *constexpr_p = (SFK_CTOR_P (sfk)
2730 || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14)
2731 || (SFK_DTOR_P (sfk) && cxx_dialect >= cxx20));
2732
2733 bool expected_trivial = type_has_trivial_fn (ctype, sfk);
2734 if (trivial_p)
2735 *trivial_p = expected_trivial;
2736
2737 /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
2738 class versions and other properties of the type. But a subobject
2739 class can be trivially copyable and yet have overload resolution
2740 choose a template constructor for initialization, depending on
2741 rvalueness and cv-quals. And furthermore, a member in a base might
2742 be trivial but deleted or otherwise not callable. So we can't exit
2743 early in C++0x. The same considerations apply in C++98/03, but
2744 there the definition of triviality does not consider overload
2745 resolution, so a constructor can be trivial even if it would otherwise
2746 call a non-trivial constructor. */
2747 if (expected_trivial
2748 && (!(SFK_COPY_P (sfk) || SFK_MOVE_P (sfk)) || cxx_dialect < cxx11))
2749 {
2750 if (constexpr_p && sfk == sfk_constructor)
2751 {
2752 bool cx = trivial_default_constructor_is_constexpr (ctype);
2753 *constexpr_p = cx;
2754 if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
2755 /* A trivial constructor doesn't have any NSDMI. */
2756 inform (input_location, "defaulted default constructor does "
2757 "not initialize any non-static data member");
2758 }
2759 if (!diag && cxx_dialect < cxx11)
2760 return;
2761 }
2762
2763 bool push_to_top = maybe_push_to_top_level (TYPE_NAME (ctype));
2764 ++cp_unevaluated_operand;
2765 ++c_inhibit_evaluation_warnings;
2766 push_deferring_access_checks (dk_no_deferred);
2767
2768 tree scope = push_scope (ctype);
2769
2770 int flags = LOOKUP_NORMAL | LOOKUP_SPECULATIVE;
2771 if (sfk != sfk_inheriting_constructor)
2772 flags |= LOOKUP_DEFAULTED;
2773
2774 tsubst_flags_t complain = diag ? tf_warning_or_error : tf_none;
2775 if (diag && spec_p)
2776 /* We're in get_defaulted_eh_spec; we don't actually want any walking
2777 diagnostics, we just want complain set. */
2778 diag = false;
2779 int quals = const_p ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED;
2780
2781 for (binfo = TYPE_BINFO (ctype), i = 0;
2782 BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
2783 {
2784 if (!SFK_ASSIGN_P (sfk) && BINFO_VIRTUAL_P (base_binfo))
2785 /* We'll handle virtual bases below. */
2786 continue;
2787
2788 tree fn = synthesized_method_base_walk (binfo, base_binfo,
2789 sfk, fnname, quals,
2790 inheriting_ctor, inherited_parms,
2791 flags, diag, spec_p, trivial_p,
2792 deleted_p, constexpr_p);
2793
2794 if (diag && SFK_ASSIGN_P (sfk) && SFK_MOVE_P (sfk)
2795 && BINFO_VIRTUAL_P (base_binfo)
2796 && fn && TREE_CODE (fn) == FUNCTION_DECL
2797 && move_fn_p (fn) && !trivial_fn_p (fn)
2798 && vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
2799 warning (OPT_Wvirtual_move_assign,
2800 "defaulted move assignment for %qT calls a non-trivial "
2801 "move assignment operator for virtual base %qT",
2802 ctype, BINFO_TYPE (base_binfo));
2803
2804 if (check_vdtor && type_has_virtual_destructor (BINFO_TYPE (base_binfo)))
2805 {
2806 /* Unlike for base ctor/op=/dtor, for operator delete it's fine
2807 to have a null fn (no class-specific op delete). */
2808 fn = locate_fn_flags (type: ctype, name: ovl_op_identifier (isass: false, code: DELETE_EXPR),
2809 ptr_type_node, flags, complain: tf_none);
2810 if (fn && fn == error_mark_node)
2811 {
2812 if (complain & tf_error)
2813 locate_fn_flags (type: ctype, name: ovl_op_identifier (isass: false, code: DELETE_EXPR),
2814 ptr_type_node, flags, complain);
2815 if (deleted_p)
2816 *deleted_p = true;
2817 }
2818 check_vdtor = false;
2819 }
2820 }
2821
2822 vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (ctype);
2823 if (SFK_ASSIGN_P (sfk))
2824 /* Already examined vbases above. */;
2825 else if (vec_safe_is_empty (v: vbases))
2826 /* No virtual bases to worry about. */;
2827 else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14
2828 /* DR 1658 specifies that vbases of abstract classes are
2829 ignored for both ctors and dtors. Except DR 2336
2830 overrides that skipping when determing the eh-spec of a
2831 virtual destructor. */
2832 && sfk != sfk_virtual_destructor)
2833 /* Vbase cdtors are not relevant. */;
2834 else
2835 {
2836 if (constexpr_p)
2837 *constexpr_p = false;
2838
2839 FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
2840 synthesized_method_base_walk (binfo, base_binfo, sfk, fnname, quals,
2841 inheriting_ctor, inherited_parms,
2842 flags, diag,
2843 spec_p, trivial_p, deleted_p, constexpr_p);
2844 }
2845
2846 /* Now handle the non-static data members. */
2847 walk_field_subobs (TYPE_FIELDS (ctype), sfk, fnname, quals,
2848 spec_p, trivial_p, deleted_p, constexpr_p,
2849 diag, flags, complain, /*dtor_from_ctor*/false);
2850 if (SFK_CTOR_P (sfk))
2851 walk_field_subobs (TYPE_FIELDS (ctype), sfk: sfk_destructor,
2852 complete_dtor_identifier, quals: TYPE_UNQUALIFIED,
2853 NULL, NULL, deleted_p, NULL,
2854 diag: false, flags, complain, /*dtor_from_ctor*/true);
2855
2856 pop_scope (scope);
2857
2858 pop_deferring_access_checks ();
2859 --cp_unevaluated_operand;
2860 --c_inhibit_evaluation_warnings;
2861 maybe_pop_from_top_level (push_to_top);
2862}
2863
2864/* DECL is a defaulted function whose exception specification is now
2865 needed. Return what it should be. */
2866
2867tree
2868get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
2869{
2870 /* For DECL_MAYBE_DELETED this should already have been handled by
2871 synthesize_method. */
2872 gcc_assert (!DECL_MAYBE_DELETED (decl));
2873
2874 if (DECL_CLONED_FUNCTION_P (decl))
2875 decl = DECL_CLONED_FUNCTION (decl);
2876 special_function_kind sfk = special_function_p (decl);
2877 tree ctype = DECL_CONTEXT (decl);
2878 tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
2879 tree parm_type = TREE_VALUE (parms);
2880 bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
2881 tree spec = empty_except_spec;
2882 bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
2883 tree inh = DECL_INHERITED_CTOR (decl);
2884 if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
2885 /* We have to examine virtual bases even if abstract. */
2886 sfk = sfk_virtual_destructor;
2887 bool pushed = false;
2888 if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
2889 pushed = push_tinst_level (decl);
2890 synthesized_method_walk (ctype, sfk, const_p, spec_p: &spec, NULL, NULL,
2891 NULL, diag, inheriting_ctor: &inh, inherited_parms: parms);
2892 if (pushed)
2893 pop_tinst_level ();
2894 return spec;
2895}
2896
2897/* DECL is a deleted function. If it's implicitly deleted, explain why and
2898 return true; else return false. */
2899
2900bool
2901maybe_explain_implicit_delete (tree decl)
2902{
2903 /* If decl is a clone, get the primary variant. */
2904 decl = DECL_ORIGIN (decl);
2905 gcc_assert (DECL_DELETED_FN (decl));
2906 if (DECL_DEFAULTED_FN (decl))
2907 {
2908 /* Not marked GTY; it doesn't need to be GC'd or written to PCH. */
2909 static hash_set<tree> *explained;
2910
2911 special_function_kind sfk;
2912 location_t loc;
2913 bool informed;
2914 tree ctype;
2915
2916 if (!explained)
2917 explained = new hash_set<tree>;
2918 if (explained->add (k: decl))
2919 return true;
2920
2921 sfk = special_function_p (decl);
2922 ctype = DECL_CONTEXT (decl);
2923 loc = input_location;
2924 input_location = DECL_SOURCE_LOCATION (decl);
2925
2926 informed = false;
2927 if (LAMBDA_TYPE_P (ctype))
2928 {
2929 informed = true;
2930 if (sfk == sfk_constructor)
2931 inform (DECL_SOURCE_LOCATION (decl),
2932 "a lambda closure type has a deleted default constructor");
2933 else if (sfk == sfk_copy_assignment)
2934 inform (DECL_SOURCE_LOCATION (decl),
2935 "a lambda closure type has a deleted copy assignment operator");
2936 else
2937 informed = false;
2938 }
2939 else if (DECL_ARTIFICIAL (decl)
2940 && (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
2941 && classtype_has_move_assign_or_move_ctor_p (ctype, user_declared: true))
2942 {
2943 inform (DECL_SOURCE_LOCATION (decl),
2944 "%q#D is implicitly declared as deleted because %qT "
2945 "declares a move constructor or move assignment operator",
2946 decl, ctype);
2947 informed = true;
2948 }
2949 else if (sfk == sfk_inheriting_constructor)
2950 {
2951 tree binfo = inherited_ctor_binfo (fndecl: decl);
2952 if (TREE_CODE (binfo) != TREE_BINFO)
2953 {
2954 inform (DECL_SOURCE_LOCATION (decl),
2955 "%q#D inherits from multiple base subobjects",
2956 decl);
2957 informed = true;
2958 }
2959 }
2960 if (!informed && sfk == sfk_comparison)
2961 {
2962 inform (DECL_SOURCE_LOCATION (decl),
2963 "%q#D is implicitly deleted because the default "
2964 "definition would be ill-formed:", decl);
2965 build_comparison_op (fndecl: decl, defining: false, complain: tf_warning_or_error);
2966 }
2967 else if (!informed)
2968 {
2969 tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
2970 bool const_p = false;
2971 if (parms)
2972 {
2973 tree parm_type = TREE_VALUE (parms);
2974 const_p = CP_TYPE_CONST_P (non_reference (parm_type));
2975 }
2976 tree raises = NULL_TREE;
2977 bool deleted_p = false;
2978 tree scope = push_scope (ctype);
2979 tree inh = DECL_INHERITED_CTOR (decl);
2980
2981 synthesized_method_walk (ctype, sfk, const_p,
2982 spec_p: &raises, NULL, deleted_p: &deleted_p, NULL, diag: false,
2983 inheriting_ctor: &inh, inherited_parms: parms);
2984 if (deleted_p)
2985 {
2986 inform (DECL_SOURCE_LOCATION (decl),
2987 "%q#D is implicitly deleted because the default "
2988 "definition would be ill-formed:", decl);
2989 synthesized_method_walk (ctype, sfk, const_p,
2990 NULL, NULL, deleted_p: &deleted_p, NULL, diag: true,
2991 inheriting_ctor: &inh, inherited_parms: parms);
2992 }
2993 else if (!comp_except_specs
2994 (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
2995 raises, ce_normal))
2996 inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly "
2997 "deleted because its exception-specification does not "
2998 "match the implicit exception-specification %qX",
2999 decl, raises);
3000 else if (flag_checking)
3001 gcc_unreachable ();
3002
3003 pop_scope (scope);
3004 }
3005
3006 input_location = loc;
3007 return true;
3008 }
3009 return false;
3010}
3011
3012/* DECL is a defaulted function which was declared constexpr. Explain why
3013 it can't be constexpr. */
3014
3015void
3016explain_implicit_non_constexpr (tree decl)
3017{
3018 tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
3019 bool const_p = CP_TYPE_CONST_P (non_reference (TREE_VALUE (parms)));
3020 tree inh = DECL_INHERITED_CTOR (decl);
3021 bool dummy;
3022 special_function_kind sfk = special_function_p (decl);
3023 if (sfk == sfk_comparison)
3024 {
3025 DECL_DECLARED_CONSTEXPR_P (decl) = true;
3026 build_comparison_op (fndecl: decl, defining: false, complain: tf_warning_or_error);
3027 DECL_DECLARED_CONSTEXPR_P (decl) = false;
3028 }
3029 else
3030 synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
3031 sfk, const_p,
3032 NULL, NULL, NULL, constexpr_p: &dummy, diag: true,
3033 inheriting_ctor: &inh, inherited_parms: parms);
3034}
3035
3036/* DECL is an instantiation of an inheriting constructor template. Deduce
3037 the correct exception-specification and deletedness for this particular
3038 specialization. Return true if the deduction succeeds; false otherwise. */
3039
3040bool
3041deduce_inheriting_ctor (tree decl)
3042{
3043 decl = DECL_ORIGIN (decl);
3044 gcc_assert (DECL_INHERITED_CTOR (decl));
3045 tree spec;
3046 bool trivial, constexpr_, deleted;
3047 tree inh = DECL_INHERITED_CTOR (decl);
3048 synthesized_method_walk (DECL_CONTEXT (decl), sfk: sfk_inheriting_constructor,
3049 const_p: false, spec_p: &spec, trivial_p: &trivial, deleted_p: &deleted, constexpr_p: &constexpr_,
3050 /*diag*/false,
3051 inheriting_ctor: &inh,
3052 FUNCTION_FIRST_USER_PARMTYPE (decl));
3053 if (spec == error_mark_node)
3054 return false;
3055 if (TREE_CODE (inherited_ctor_binfo (decl)) != TREE_BINFO)
3056 /* Inherited the same constructor from different base subobjects. */
3057 deleted = true;
3058 DECL_DELETED_FN (decl) = deleted;
3059 TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
3060 SET_DECL_INHERITED_CTOR (decl, inh);
3061
3062 tree clone;
3063 FOR_EACH_CLONE (clone, decl)
3064 {
3065 DECL_DELETED_FN (clone) = deleted;
3066 TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec);
3067 SET_DECL_INHERITED_CTOR (clone, inh);
3068 }
3069
3070 return true;
3071}
3072
3073/* Implicitly declare the special function indicated by KIND, as a
3074 member of TYPE. For copy constructors and assignment operators,
3075 CONST_P indicates whether these functions should take a const
3076 reference argument or a non-const reference.
3077 Returns the FUNCTION_DECL for the implicitly declared function. */
3078
3079tree
3080implicitly_declare_fn (special_function_kind kind, tree type,
3081 bool const_p, tree pattern_fn,
3082 tree inherited_parms)
3083{
3084 tree fn;
3085 tree parameter_types = void_list_node;
3086 tree return_type;
3087 tree fn_type;
3088 tree raises = empty_except_spec;
3089 tree rhs_parm_type = NULL_TREE;
3090 tree this_parm;
3091 tree name;
3092 HOST_WIDE_INT saved_processing_template_decl;
3093 bool deleted_p = false;
3094 bool constexpr_p = false;
3095 tree inherited_ctor = (kind == sfk_inheriting_constructor
3096 ? pattern_fn : NULL_TREE);
3097
3098 /* Because we create declarations for implicitly declared functions
3099 lazily, we may be creating the declaration for a member of TYPE
3100 while in some completely different context. However, TYPE will
3101 never be a dependent class (because we never want to do lookups
3102 for implicitly defined functions in a dependent class). */
3103 gcc_assert (!dependent_type_p (type));
3104
3105 /* If the member-specification does not explicitly declare any member or
3106 friend named operator==, an == operator function is declared
3107 implicitly for each three-way comparison operator function defined as
3108 defaulted in the member-specification, with the same access and
3109 function-definition and in the same class scope as the respective
3110 three-way comparison operator function, except that the return type is
3111 replaced with bool and the declarator-id is replaced with
3112 operator==.
3113
3114 [Note: Such an implicitly-declared == operator for a class X is
3115 defined as defaulted in the definition of X and has the same
3116 parameter-declaration-clause and trailing requires-clause as the
3117 respective three-way comparison operator. It is declared with friend,
3118 virtual, constexpr, or consteval if the three-way comparison operator
3119 function is so declared. If the three-way comparison operator function
3120 has no noexcept-specifier, the implicitly-declared == operator
3121 function has an implicit exception specification (14.5) that may
3122 differ from the implicit exception specification of the three-way
3123 comparison operator function. --end note] */
3124 if (kind == sfk_comparison)
3125 {
3126 fn = copy_operator_fn (pattern_fn, code: EQ_EXPR);
3127 DECL_ARTIFICIAL (fn) = 1;
3128 apply_deduced_return_type (fn, boolean_type_node);
3129 return fn;
3130 }
3131
3132 /* Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
3133 because we only create clones for constructors and destructors
3134 when not in a template. */
3135 saved_processing_template_decl = processing_template_decl;
3136 processing_template_decl = 0;
3137
3138 type = TYPE_MAIN_VARIANT (type);
3139
3140 if (targetm.cxx.cdtor_returns_this ())
3141 {
3142 if (kind == sfk_destructor)
3143 /* See comment in check_special_function_return_type. */
3144 return_type = build_pointer_type (void_type_node);
3145 else
3146 return_type = build_pointer_type (type);
3147 }
3148 else
3149 return_type = void_type_node;
3150
3151 int this_quals = TYPE_UNQUALIFIED;
3152 switch (kind)
3153 {
3154 case sfk_destructor:
3155 /* Destructor. */
3156 name = dtor_identifier;
3157 break;
3158
3159 case sfk_constructor:
3160 /* Default constructor. */
3161 name = ctor_identifier;
3162 break;
3163
3164 case sfk_copy_constructor:
3165 case sfk_copy_assignment:
3166 case sfk_move_constructor:
3167 case sfk_move_assignment:
3168 case sfk_inheriting_constructor:
3169 {
3170 if (kind == sfk_copy_assignment
3171 || kind == sfk_move_assignment)
3172 {
3173 return_type = build_reference_type (type);
3174 name = assign_op_identifier;
3175 }
3176 else
3177 name = ctor_identifier;
3178
3179 if (kind == sfk_inheriting_constructor)
3180 parameter_types = inherited_parms;
3181 else
3182 {
3183 if (const_p)
3184 rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
3185 else
3186 rhs_parm_type = type;
3187 bool move_p = (kind == sfk_move_assignment
3188 || kind == sfk_move_constructor);
3189 rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
3190
3191 parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
3192 }
3193 break;
3194 }
3195
3196 default:
3197 gcc_unreachable ();
3198 }
3199
3200 bool trivial_p = false;
3201
3202 if (inherited_ctor)
3203 {
3204 /* For an inheriting constructor, just copy these flags from the
3205 inherited constructor until deduce_inheriting_ctor. */
3206 raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
3207 deleted_p = DECL_DELETED_FN (inherited_ctor);
3208 constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
3209 }
3210 else if (cxx_dialect >= cxx11)
3211 {
3212 raises = noexcept_deferred_spec;
3213 synthesized_method_walk (ctype: type, sfk: kind, const_p, NULL, trivial_p: &trivial_p,
3214 deleted_p: &deleted_p, constexpr_p: &constexpr_p, diag: false,
3215 inheriting_ctor: &inherited_ctor, inherited_parms);
3216 }
3217 else
3218 synthesized_method_walk (ctype: type, sfk: kind, const_p, spec_p: &raises, trivial_p: &trivial_p,
3219 deleted_p: &deleted_p, constexpr_p: &constexpr_p, diag: false,
3220 inheriting_ctor: &inherited_ctor, inherited_parms);
3221 /* Don't bother marking a deleted constructor as constexpr. */
3222 if (deleted_p)
3223 constexpr_p = false;
3224 /* A trivial copy/move constructor is also a constexpr constructor,
3225 unless the class has virtual bases (7.1.5p4). */
3226 else if (trivial_p
3227 && cxx_dialect >= cxx11
3228 && (kind == sfk_copy_constructor
3229 || kind == sfk_move_constructor)
3230 && !CLASSTYPE_VBASECLASSES (type))
3231 gcc_assert (constexpr_p);
3232
3233 if (!trivial_p && type_has_trivial_fn (ctype: type, sfk: kind))
3234 type_set_nontrivial_flag (ctype: type, sfk: kind);
3235
3236 /* Create the function. */
3237 tree this_type = cp_build_qualified_type (type, this_quals);
3238 fn_type = build_method_type_directly (this_type, return_type,
3239 parameter_types);
3240
3241 if (raises)
3242 {
3243 if (raises != error_mark_node)
3244 fn_type = build_exception_variant (fn_type, raises);
3245 else
3246 {
3247 /* Can happen, e.g., in C++98 mode for an ill-formed non-static data
3248 member initializer (c++/89914). Also, in C++98, we might have
3249 failed to deduce RAISES, so try again but complain this time. */
3250 if (cxx_dialect < cxx11)
3251 synthesized_method_walk (ctype: type, sfk: kind, const_p, spec_p: &raises, trivial_p: nullptr,
3252 deleted_p: nullptr, constexpr_p: nullptr, /*diag=*/true,
3253 inheriting_ctor: &inherited_ctor, inherited_parms);
3254 /* We should have seen an error at this point. */
3255 gcc_assert (seen_error ());
3256 }
3257 }
3258 fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
3259 if (kind != sfk_inheriting_constructor)
3260 DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
3261
3262 if (IDENTIFIER_OVL_OP_P (name))
3263 {
3264 const ovl_op_info_t *op = IDENTIFIER_OVL_OP_INFO (name);
3265 DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) = op->ovl_op_code;
3266 }
3267 else if (IDENTIFIER_CTOR_P (name))
3268 DECL_CXX_CONSTRUCTOR_P (fn) = true;
3269 else if (IDENTIFIER_DTOR_P (name))
3270 DECL_CXX_DESTRUCTOR_P (fn) = true;
3271 else
3272 gcc_unreachable ();
3273
3274 SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
3275
3276 /* Create the explicit arguments. */
3277 if (rhs_parm_type)
3278 {
3279 /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
3280 want its type to be included in the mangled function
3281 name. */
3282 tree decl = cp_build_parm_decl (fn, NULL_TREE, rhs_parm_type);
3283 TREE_READONLY (decl) = 1;
3284 retrofit_lang_decl (decl);
3285 DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
3286 DECL_ARGUMENTS (fn) = decl;
3287 }
3288 else if (kind == sfk_inheriting_constructor)
3289 {
3290 tree *p = &DECL_ARGUMENTS (fn);
3291 int index = 1;
3292 for (tree parm = inherited_parms; parm && parm != void_list_node;
3293 parm = TREE_CHAIN (parm))
3294 {
3295 *p = cp_build_parm_decl (fn, NULL_TREE, TREE_VALUE (parm));
3296 retrofit_lang_decl (*p);
3297 DECL_PARM_LEVEL (*p) = 1;
3298 DECL_PARM_INDEX (*p) = index++;
3299 p = &DECL_CHAIN (*p);
3300 }
3301 SET_DECL_INHERITED_CTOR (fn, inherited_ctor);
3302 DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
3303 /* A constructor so declared has the same access as the corresponding
3304 constructor in X. */
3305 TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
3306 TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
3307 /* Copy constexpr from the inherited constructor even if the
3308 inheriting constructor doesn't satisfy the requirements. */
3309 constexpr_p = DECL_DECLARED_CONSTEXPR_P (inherited_ctor);
3310 tree inherited_ctor_fn = STRIP_TEMPLATE (inherited_ctor);
3311 /* Also copy any attributes. */
3312 DECL_ATTRIBUTES (fn) = clone_attrs (DECL_ATTRIBUTES (inherited_ctor_fn));
3313 DECL_DISREGARD_INLINE_LIMITS (fn)
3314 = DECL_DISREGARD_INLINE_LIMITS (inherited_ctor_fn);
3315 }
3316
3317 /* Add the "this" parameter. */
3318 this_parm = build_this_parm (fn, fn_type, this_quals);
3319 DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
3320 DECL_ARGUMENTS (fn) = this_parm;
3321
3322 grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
3323
3324 DECL_IN_AGGR_P (fn) = 1;
3325 DECL_ARTIFICIAL (fn) = 1;
3326 DECL_DEFAULTED_FN (fn) = 1;
3327 if (cxx_dialect >= cxx11)
3328 {
3329 DECL_DELETED_FN (fn) = deleted_p;
3330 DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
3331 }
3332 DECL_EXTERNAL (fn) = true;
3333 DECL_NOT_REALLY_EXTERN (fn) = 1;
3334 DECL_DECLARED_INLINE_P (fn) = 1;
3335 set_linkage_according_to_type (type, fn);
3336 if (TREE_PUBLIC (fn))
3337 DECL_COMDAT (fn) = 1;
3338 rest_of_decl_compilation (fn, namespace_bindings_p (), at_eof);
3339 gcc_assert (!TREE_USED (fn));
3340
3341 /* Propagate constraints from the inherited constructor. */
3342 if (flag_concepts && inherited_ctor)
3343 if (tree orig_ci = get_constraints (inherited_ctor))
3344 {
3345 tree new_ci = copy_node (orig_ci);
3346 set_constraints (fn, new_ci);
3347 }
3348
3349 /* Restore PROCESSING_TEMPLATE_DECL. */
3350 processing_template_decl = saved_processing_template_decl;
3351
3352 if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
3353 fn = add_inherited_template_parms (fn, inherited_ctor);
3354
3355 /* Warn about calling a non-trivial move assignment in a virtual base. */
3356 if (kind == sfk_move_assignment && !deleted_p && !trivial_p
3357 && CLASSTYPE_VBASECLASSES (type))
3358 {
3359 location_t loc = input_location;
3360 input_location = DECL_SOURCE_LOCATION (fn);
3361 synthesized_method_walk (ctype: type, sfk: kind, const_p,
3362 NULL, NULL, NULL, NULL, diag: true,
3363 NULL, NULL_TREE);
3364 input_location = loc;
3365 }
3366
3367 return fn;
3368}
3369
3370/* Gives any errors about defaulted functions which need to be deferred
3371 until the containing class is complete. */
3372
3373void
3374defaulted_late_check (tree fn)
3375{
3376 /* Complain about invalid signature for defaulted fn. */
3377 tree ctx = DECL_CONTEXT (fn);
3378 special_function_kind kind = special_function_p (fn);
3379
3380 if (kind == sfk_comparison)
3381 {
3382 /* If the function was declared constexpr, check that the definition
3383 qualifies. Otherwise we can define the function lazily. */
3384 if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn))
3385 {
3386 /* Prevent GC. */
3387 function_depth++;
3388 synthesize_method (fndecl: fn);
3389 function_depth--;
3390 }
3391 return;
3392 }
3393
3394 bool fn_const_p = (copy_fn_p (fn) == 2);
3395 tree implicit_fn = implicitly_declare_fn (kind, type: ctx, const_p: fn_const_p,
3396 NULL, NULL);
3397 tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
3398
3399 /* Includes special handling for a default xobj operator. */
3400 auto compare_fn_params = [](tree fn, tree implicit_fn){
3401 tree fn_parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
3402 tree implicit_fn_parms = TYPE_ARG_TYPES (TREE_TYPE (implicit_fn));
3403
3404 if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
3405 {
3406 tree fn_obj_ref_type = TREE_VALUE (fn_parms);
3407 /* We can't default xobj operators with an xobj parameter that is not
3408 an lvalue reference, even if it would correspond. */
3409 if (!TYPE_REF_P (fn_obj_ref_type)
3410 || TYPE_REF_IS_RVALUE (fn_obj_ref_type)
3411 || !object_parms_correspond (fn, implicit_fn,
3412 DECL_CONTEXT (implicit_fn)))
3413 return false;
3414 /* We just compared the object parameters, skip over them before
3415 passing to compparms. */
3416 fn_parms = TREE_CHAIN (fn_parms);
3417 implicit_fn_parms = TREE_CHAIN (implicit_fn_parms);
3418 }
3419 return compparms (fn_parms, implicit_fn_parms);
3420 };
3421
3422 if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
3423 TREE_TYPE (TREE_TYPE (implicit_fn)))
3424 || !compare_fn_params (fn, implicit_fn))
3425 {
3426 error ("defaulted declaration %q+D does not match the "
3427 "expected signature", fn);
3428 inform (DECL_SOURCE_LOCATION (fn),
3429 "expected signature: %qD", implicit_fn);
3430 }
3431
3432 if (DECL_DELETED_FN (implicit_fn))
3433 {
3434 DECL_DELETED_FN (fn) = 1;
3435 return;
3436 }
3437
3438 /* If a function is explicitly defaulted on its first declaration without an
3439 exception-specification, it is implicitly considered to have the same
3440 exception-specification as if it had been implicitly declared. */
3441 if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
3442 && DECL_DEFAULTED_IN_CLASS_P (fn))
3443 TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
3444
3445 if (DECL_DEFAULTED_IN_CLASS_P (fn)
3446 && DECL_DECLARED_CONSTEXPR_P (implicit_fn))
3447 {
3448 /* Hmm...should we do this for out-of-class too? Should it be OK to
3449 add constexpr later like inline, rather than requiring
3450 declarations to match? */
3451 DECL_DECLARED_CONSTEXPR_P (fn) = true;
3452 if (kind == sfk_constructor)
3453 TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
3454 }
3455
3456 if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
3457 && DECL_DECLARED_CONSTEXPR_P (fn))
3458 {
3459 if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
3460 {
3461 error ("explicitly defaulted function %q+D cannot be declared "
3462 "%qs because the implicit declaration is not %qs:", fn,
3463 DECL_IMMEDIATE_FUNCTION_P (fn) ? "consteval" : "constexpr",
3464 "constexpr");
3465 explain_implicit_non_constexpr (decl: fn);
3466 }
3467 DECL_DECLARED_CONSTEXPR_P (fn) = false;
3468 }
3469}
3470
3471/* Returns true iff FN can be explicitly defaulted, and gives any
3472 errors if defaulting FN is ill-formed. */
3473
3474bool
3475defaultable_fn_check (tree fn)
3476{
3477 special_function_kind kind = sfk_none;
3478
3479 if (template_parm_scope_p ())
3480 {
3481 error ("a template cannot be defaulted");
3482 return false;
3483 }
3484
3485 if (DECL_CONSTRUCTOR_P (fn))
3486 {
3487 if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
3488 kind = sfk_constructor;
3489 else if (copy_fn_p (fn) > 0
3490 && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
3491 == void_list_node))
3492 kind = sfk_copy_constructor;
3493 else if (move_fn_p (fn))
3494 kind = sfk_move_constructor;
3495 }
3496 else if (DECL_DESTRUCTOR_P (fn))
3497 kind = sfk_destructor;
3498 else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
3499 && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
3500 {
3501 if (copy_fn_p (fn))
3502 kind = sfk_copy_assignment;
3503 else if (move_fn_p (fn))
3504 kind = sfk_move_assignment;
3505 }
3506 else if (DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) >= OVL_OP_EQ_EXPR
3507 && DECL_OVERLOADED_OPERATOR_CODE_RAW (fn) <= OVL_OP_SPACESHIP_EXPR)
3508 {
3509 kind = sfk_comparison;
3510 if (!early_check_defaulted_comparison (fn))
3511 return false;
3512 }
3513
3514 /* FIXME: We need to check for xobj member functions here to give better
3515 diagnostics for weird cases where unrelated xobj parameters are given.
3516 We just want to do better than 'cannot be defaulted'. */
3517
3518 if (kind == sfk_none)
3519 {
3520 error ("%qD cannot be defaulted", fn);
3521 return false;
3522 }
3523 else
3524 {
3525 for (tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
3526 t && t != void_list_node; t = TREE_CHAIN (t))
3527 if (TREE_PURPOSE (t))
3528 {
3529 error ("defaulted function %q+D with default argument", fn);
3530 break;
3531 }
3532
3533 /* Avoid do_warn_unused_parameter warnings. */
3534 for (tree p = FUNCTION_FIRST_USER_PARM (fn); p; p = DECL_CHAIN (p))
3535 if (DECL_NAME (p))
3536 suppress_warning (p, OPT_Wunused_parameter);
3537
3538 if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
3539 /* Defer checking. */;
3540 else if (!processing_template_decl)
3541 defaulted_late_check (fn);
3542
3543 return true;
3544 }
3545}
3546
3547/* Add an implicit declaration to TYPE for the kind of function
3548 indicated by SFK. Return the FUNCTION_DECL for the new implicit
3549 declaration. */
3550
3551tree
3552lazily_declare_fn (special_function_kind sfk, tree type)
3553{
3554 tree fn;
3555 /* Whether or not the argument has a const reference type. */
3556 bool const_p = false;
3557
3558 type = TYPE_MAIN_VARIANT (type);
3559
3560 switch (sfk)
3561 {
3562 case sfk_constructor:
3563 CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
3564 break;
3565 case sfk_copy_constructor:
3566 const_p = TYPE_HAS_CONST_COPY_CTOR (type);
3567 CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
3568 break;
3569 case sfk_move_constructor:
3570 CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
3571 break;
3572 case sfk_copy_assignment:
3573 const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
3574 CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
3575 break;
3576 case sfk_move_assignment:
3577 CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
3578 break;
3579 case sfk_destructor:
3580 CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
3581 break;
3582 default:
3583 gcc_unreachable ();
3584 }
3585
3586 /* Declare the function. */
3587 fn = implicitly_declare_fn (kind: sfk, type, const_p, NULL, NULL);
3588
3589 /* [class.copy]/8 If the class definition declares a move constructor or
3590 move assignment operator, the implicitly declared copy constructor is
3591 defined as deleted.... */
3592 if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
3593 && cxx_dialect >= cxx11)
3594 {
3595 if (classtype_has_move_assign_or_move_ctor_p (type, user_declared: true))
3596 DECL_DELETED_FN (fn) = true;
3597 else if (classtype_has_depr_implicit_copy (type))
3598 /* The implicit definition of a copy constructor as defaulted is
3599 deprecated if the class has a user-declared copy assignment operator
3600 or a user-declared destructor. The implicit definition of a copy
3601 assignment operator as defaulted is deprecated if the class has a
3602 user-declared copy constructor or a user-declared destructor (15.4,
3603 15.8). */
3604 TREE_DEPRECATED (fn) = true;
3605 }
3606
3607 /* Destructors and assignment operators may be virtual. */
3608 if (sfk == sfk_destructor
3609 || sfk == sfk_move_assignment
3610 || sfk == sfk_copy_assignment)
3611 check_for_override (fn, type);
3612
3613 /* Add it to the class */
3614 bool added = add_method (type, fn, false);
3615 gcc_assert (added || errorcount);
3616
3617 /* Add it to TYPE_FIELDS. */
3618 if (sfk == sfk_destructor
3619 && DECL_VIRTUAL_P (fn))
3620 /* The ABI requires that a virtual destructor go at the end of the
3621 vtable. */
3622 TYPE_FIELDS (type) = chainon (TYPE_FIELDS (type), fn);
3623 else
3624 {
3625 DECL_CHAIN (fn) = TYPE_FIELDS (type);
3626 TYPE_FIELDS (type) = fn;
3627 }
3628 /* Propagate TYPE_FIELDS. */
3629 fixup_type_variants (type);
3630
3631 maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
3632 if (DECL_MAYBE_IN_CHARGE_CDTOR_P (fn))
3633 /* Create appropriate clones. */
3634 clone_cdtor (fn, /*update_methods=*/true);
3635
3636 /* Classes, structs or unions TYPE marked with hotness attributes propagate
3637 the attribute to all methods. This is typically done in
3638 check_bases_and_members, but we must also inject them here for deferred
3639 lazily-declared functions. */
3640 maybe_propagate_warmth_attributes (fn, type);
3641
3642 return fn;
3643}
3644
3645/* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
3646 as there are artificial parms in FN. */
3647
3648tree
3649skip_artificial_parms_for (const_tree fn, tree list)
3650{
3651 if (DECL_IOBJ_MEMBER_FUNCTION_P (fn))
3652 list = TREE_CHAIN (list);
3653 else
3654 return list;
3655
3656 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
3657 list = TREE_CHAIN (list);
3658 if (DECL_HAS_VTT_PARM_P (fn))
3659 list = TREE_CHAIN (list);
3660 return list;
3661}
3662
3663/* Given a FUNCTION_DECL FN and a chain LIST, return the number of
3664 artificial parms in FN. */
3665
3666int
3667num_artificial_parms_for (const_tree fn)
3668{
3669 int count = 0;
3670
3671 if (DECL_IOBJ_MEMBER_FUNCTION_P (fn))
3672 count++;
3673 else
3674 return 0;
3675
3676 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
3677 count++;
3678 if (DECL_HAS_VTT_PARM_P (fn))
3679 count++;
3680 return count;
3681}
3682
3683
3684#include "gt-cp-method.h"
3685

source code of gcc/cp/method.cc