Line data Source code
1 : /* Perform C++ constant expression evaluation, including calls to
2 : constexpr functions. These routines are used both during actual parsing
3 : and during the instantiation of template functions.
4 :
5 : Copyright (C) 1998-2026 Free Software Foundation, Inc.
6 :
7 : This file is part of GCC.
8 :
9 : GCC is free software; you can redistribute it and/or modify it
10 : under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3, or (at your option)
12 : any later version.
13 :
14 : GCC is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with GCC; see the file COPYING3. If not see
21 : <http://www.gnu.org/licenses/>. */
22 :
23 : #include "config.h"
24 : #include "system.h"
25 : #include "coretypes.h"
26 : #include "cp-tree.h"
27 : #include "varasm.h"
28 : #include "c-family/c-objc.h"
29 : #include "tree-iterator.h"
30 : #include "gimplify.h"
31 : #include "builtins.h"
32 : #include "tree-inline.h"
33 : #include "ubsan.h"
34 : #include "timevar.h"
35 : #include "fold-const-call.h"
36 : #include "stor-layout.h"
37 : #include "cgraph.h"
38 : #include "opts.h"
39 : #include "stringpool.h"
40 : #include "attribs.h"
41 : #include "fold-const.h"
42 : #include "intl.h"
43 : #include "toplev.h"
44 : #include "contracts.h"
45 :
46 : static bool verify_constant (tree, bool, bool *, bool *);
47 : #define VERIFY_CONSTANT(X) \
48 : do { \
49 : if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \
50 : return t; \
51 : } while (0)
52 :
53 : static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex,
54 : bool insert = false);
55 : static int array_index_cmp (tree key, tree index);
56 :
57 : /* Returns true iff FUN is an instantiation of a constexpr function
58 : template or a defaulted constexpr function. */
59 :
60 : bool
61 196689144 : is_instantiation_of_constexpr (tree fun)
62 : {
63 272402597 : return ((DECL_TEMPLOID_INSTANTIATION (fun)
64 121475546 : && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
65 292364557 : || (DECL_DEFAULTED_FN (fun)
66 410 : && DECL_DECLARED_CONSTEXPR_P (fun)));
67 : }
68 :
69 : /* Return true if T is a literal type. */
70 :
71 : bool
72 195744153 : literal_type_p (tree t)
73 : {
74 197406233 : if (SCALAR_TYPE_P (t)
75 92634829 : || VECTOR_TYPE_P (t)
76 92603176 : || TYPE_REF_P (t)
77 76764416 : || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
78 : return true;
79 73452571 : if (CLASS_TYPE_P (t))
80 : {
81 71790279 : t = complete_type (t);
82 71790279 : gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
83 71790279 : return CLASSTYPE_LITERAL_P (t);
84 : }
85 1662292 : if (TREE_CODE (t) == ARRAY_TYPE)
86 1662080 : return literal_type_p (strip_array_types (t));
87 : return false;
88 : }
89 :
90 : /* If DECL is a variable declared `constexpr', require its type
91 : be literal. Return error_mark_node if we give an error, the
92 : DECL otherwise. */
93 :
94 : tree
95 341855119 : ensure_literal_type_for_constexpr_object (tree decl)
96 : {
97 341855119 : tree type = TREE_TYPE (decl);
98 341855119 : if (VAR_P (decl)
99 128920244 : && (DECL_DECLARED_CONSTEXPR_P (decl)
100 90010873 : || var_in_constexpr_fn (decl))
101 400588837 : && !processing_template_decl)
102 : {
103 38047999 : tree stype = strip_array_types (type);
104 38047999 : if (CLASS_TYPE_P (stype) && !COMPLETE_TYPE_P (complete_type (stype)))
105 : /* Don't complain here, we'll complain about incompleteness
106 : when we try to initialize the variable. */;
107 38047993 : else if (!literal_type_p (type))
108 : {
109 24309 : if (DECL_DECLARED_CONSTEXPR_P (decl))
110 : {
111 53 : auto_diagnostic_group d;
112 53 : error_at (DECL_SOURCE_LOCATION (decl),
113 : "the type %qT of %<constexpr%> variable %qD "
114 : "is not literal", type, decl);
115 53 : explain_non_literal_class (type);
116 53 : decl = error_mark_node;
117 53 : }
118 24256 : else if (cxx_dialect < cxx23)
119 : {
120 18452 : if (!is_instantiation_of_constexpr (current_function_decl))
121 : {
122 8 : auto_diagnostic_group d;
123 8 : error_at (DECL_SOURCE_LOCATION (decl),
124 : "variable %qD of non-literal type %qT in "
125 : "%<constexpr%> function only available with "
126 : "%<-std=c++23%> or %<-std=gnu++23%>", decl, type);
127 8 : explain_non_literal_class (type);
128 8 : decl = error_mark_node;
129 8 : }
130 18452 : cp_function_chain->invalid_constexpr = true;
131 : }
132 : }
133 38023684 : else if (DECL_DECLARED_CONSTEXPR_P (decl)
134 38023684 : && variably_modified_type_p (type, NULL_TREE))
135 : {
136 4 : error_at (DECL_SOURCE_LOCATION (decl),
137 : "%<constexpr%> variable %qD has variably-modified "
138 : "type %qT", decl, type);
139 4 : decl = error_mark_node;
140 : }
141 : }
142 341855119 : return decl;
143 : }
144 :
145 : /* Issue a diagnostic with text GMSGID for constructs that are invalid in
146 : constexpr functions. CONSTEXPR_FUNDEF_P is true if we're checking
147 : a constexpr function body; if so, don't report hard errors and issue
148 : a pedwarn pre-C++23, or a warning in C++23, if requested by
149 : -Winvalid-constexpr. Otherwise, we're not in the context where we are
150 : checking if a function can be marked 'constexpr', so give a hard error. */
151 :
152 : ATTRIBUTE_GCC_DIAG(3,4)
153 : static bool
154 1060 : constexpr_error (location_t location, bool constexpr_fundef_p,
155 : const char *gmsgid, ...)
156 : {
157 1060 : diagnostics::diagnostic_info diagnostic;
158 1060 : va_list ap;
159 1060 : rich_location richloc (line_table, location);
160 1060 : va_start (ap, gmsgid);
161 1060 : bool ret;
162 1060 : if (!constexpr_fundef_p)
163 : {
164 : /* Report an error that cannot be suppressed. */
165 754 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
166 : diagnostics::kind::error);
167 754 : ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
168 : }
169 306 : else if (warn_invalid_constexpr)
170 : {
171 163 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
172 163 : (cxx_dialect < cxx23
173 : ? diagnostics::kind::pedwarn
174 : : diagnostics::kind::warning));
175 163 : diagnostic.m_option_id = OPT_Winvalid_constexpr;
176 163 : ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
177 : }
178 : else
179 : ret = false;
180 1060 : va_end (ap);
181 2120 : return ret;
182 1060 : }
183 :
184 : struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
185 : {
186 : static hashval_t hash (const constexpr_fundef *);
187 : static bool equal (const constexpr_fundef *, const constexpr_fundef *);
188 : };
189 :
190 : /* This table holds all constexpr function definitions seen in
191 : the current translation unit. */
192 :
193 : static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
194 :
195 : /* Utility function used for managing the constexpr function table.
196 : Return true if the entries pointed to by P and Q are for the
197 : same constexpr function. */
198 :
199 : inline bool
200 970800839 : constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
201 : const constexpr_fundef *rhs)
202 : {
203 942895448 : return lhs->decl == rhs->decl;
204 : }
205 :
206 : /* Utility function used for managing the constexpr function table.
207 : Return a hash value for the entry pointed to by Q. */
208 :
209 : inline hashval_t
210 936755545 : constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
211 : {
212 936755545 : return DECL_UID (fundef->decl);
213 : }
214 :
215 : /* Return a previously saved definition of function FUN. */
216 :
217 : constexpr_fundef *
218 111326235 : retrieve_constexpr_fundef (tree fun)
219 : {
220 111326235 : if (constexpr_fundef_table == NULL)
221 : return NULL;
222 :
223 111322187 : constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
224 111322187 : return constexpr_fundef_table->find (&fundef);
225 : }
226 :
227 : /* Check whether the parameter and return types of FUN are valid for a
228 : constexpr function, and complain if COMPLAIN. */
229 :
230 : bool
231 32132210 : is_valid_constexpr_fn (tree fun, bool complain)
232 : {
233 32132210 : bool ret = true;
234 :
235 64264420 : if (DECL_INHERITED_CTOR (fun)
236 3734792 : && TREE_CODE (fun) == TEMPLATE_DECL)
237 : {
238 0 : ret = false;
239 0 : if (complain)
240 0 : error ("inherited constructor %qD is not %<constexpr%>",
241 0 : DECL_INHERITED_CTOR (fun));
242 : }
243 : else
244 : {
245 32132210 : for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
246 64900611 : parm != NULL_TREE; parm = TREE_CHAIN (parm))
247 32768401 : if (!literal_type_p (TREE_TYPE (parm)))
248 : {
249 13292 : ret = false;
250 13292 : if (complain)
251 : {
252 23 : auto_diagnostic_group d;
253 23 : if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
254 : "invalid type for parameter %d of "
255 : "%<constexpr%> function %q+#D",
256 23 : DECL_PARM_INDEX (parm), fun))
257 15 : explain_non_literal_class (TREE_TYPE (parm));
258 23 : }
259 : }
260 : }
261 :
262 53289477 : if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun)) && cxx_dialect < cxx17)
263 : {
264 4 : ret = false;
265 4 : if (complain)
266 3 : inform (DECL_SOURCE_LOCATION (fun),
267 : "lambdas are implicitly %<constexpr%> only in C++17 and later");
268 : }
269 64264412 : else if (DECL_DESTRUCTOR_P (fun) && cxx_dialect < cxx20)
270 : {
271 0 : ret = false;
272 0 : if (complain)
273 0 : error_at (DECL_SOURCE_LOCATION (fun),
274 : "%<constexpr%> destructors only available with "
275 : "%<-std=c++20%> or %<-std=gnu++20%>");
276 : }
277 32132206 : else if (!DECL_CONSTRUCTOR_P (fun) && !DECL_DESTRUCTOR_P (fun))
278 : {
279 27713787 : tree rettype = TREE_TYPE (TREE_TYPE (fun));
280 27713787 : if (!literal_type_p (rettype))
281 : {
282 51062 : ret = false;
283 51062 : if (complain)
284 : {
285 21 : auto_diagnostic_group d;
286 21 : if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
287 : "invalid return type %qT of %<constexpr%> "
288 : "function %q+D", rettype, fun))
289 10 : explain_non_literal_class (rettype);
290 21 : }
291 : }
292 :
293 : /* C++14 DR 1684 removed this restriction. */
294 27713787 : if (cxx_dialect < cxx14
295 33013 : && DECL_IOBJ_MEMBER_FUNCTION_P (fun)
296 27714915 : && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun)))
297 : {
298 1 : ret = false;
299 1 : if (complain)
300 : {
301 1 : auto_diagnostic_group d;
302 1 : if (pedwarn (DECL_SOURCE_LOCATION (fun), OPT_Wpedantic,
303 : "enclosing class of %<constexpr%> non-static"
304 : " member function %q+#D is not a literal type",
305 : fun))
306 1 : explain_non_literal_class (DECL_CONTEXT (fun));
307 1 : }
308 : }
309 : }
310 4418419 : else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)) && cxx_dialect < cxx26)
311 : {
312 69 : ret = false;
313 69 : if (complain)
314 : {
315 10 : if (DECL_CONSTRUCTOR_P (fun))
316 8 : error ("%<constexpr%> constructor in %q#T that has "
317 : "virtual base classes only available with "
318 8 : "%<-std=c++2c%> or %<-std=gnu++2c%>", DECL_CONTEXT (fun));
319 : else
320 2 : error ("%<constexpr%> destructor in %q#T that has "
321 : "virtual base classes only available with "
322 2 : "%<-std=c++2c%> or %<-std=gnu++2c%>", DECL_CONTEXT (fun));
323 : }
324 : }
325 :
326 32132210 : return ret;
327 : }
328 :
329 : /* Subroutine of build_data_member_initialization. MEMBER is a COMPONENT_REF
330 : for a member of an anonymous aggregate, INIT is the initializer for that
331 : member, and VEC_OUTER is the vector of constructor elements for the class
332 : whose constructor we are processing. Add the initializer to the vector
333 : and return true to indicate success. */
334 :
335 : static bool
336 4596 : build_anon_member_initialization (tree member, tree init,
337 : vec<constructor_elt, va_gc> **vec_outer)
338 : {
339 : /* MEMBER presents the relevant fields from the inside out, but we need
340 : to build up the initializer from the outside in so that we can reuse
341 : previously built CONSTRUCTORs if this is, say, the second field in an
342 : anonymous struct. So we use a vec as a stack. */
343 4596 : auto_vec<tree, 2> fields;
344 9288 : do
345 : {
346 9288 : fields.safe_push (TREE_OPERAND (member, 1));
347 9288 : member = TREE_OPERAND (member, 0);
348 : }
349 9288 : while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
350 18582 : && TREE_CODE (member) == COMPONENT_REF);
351 :
352 : /* VEC has the constructor elements vector for the context of FIELD.
353 : If FIELD is an anonymous aggregate, we will push inside it. */
354 : vec<constructor_elt, va_gc> **vec = vec_outer;
355 : tree field;
356 9288 : while (field = fields.pop(),
357 9288 : ANON_AGGR_TYPE_P (TREE_TYPE (field)))
358 : {
359 4692 : tree ctor;
360 : /* If there is already an outer constructor entry for the anonymous
361 : aggregate FIELD, use it; otherwise, insert one. */
362 4692 : if (vec_safe_is_empty (*vec)
363 198 : || (*vec)->last().index != field)
364 : {
365 4590 : ctor = build_constructor (TREE_TYPE (field), NULL);
366 4590 : CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
367 : }
368 : else
369 102 : ctor = (*vec)->last().value;
370 4692 : vec = &CONSTRUCTOR_ELTS (ctor);
371 : }
372 :
373 : /* Now we're at the innermost field, the one that isn't an anonymous
374 : aggregate. Add its initializer to the CONSTRUCTOR and we're done. */
375 4596 : gcc_assert (fields.is_empty());
376 4596 : CONSTRUCTOR_APPEND_ELT (*vec, field, init);
377 :
378 4596 : return true;
379 4596 : }
380 :
381 : /* Subroutine of build_constexpr_constructor_member_initializers.
382 : The expression tree T represents a data member initialization
383 : in a (constexpr) constructor definition. Build a pairing of
384 : the data member with its initializer, and prepend that pair
385 : to the existing initialization pair INITS. */
386 :
387 : static bool
388 6164193 : build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
389 : {
390 6882536 : tree member, init;
391 6882536 : if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
392 3137109 : t = TREE_OPERAND (t, 0);
393 6882536 : if (TREE_CODE (t) == EXPR_STMT)
394 3137045 : t = TREE_OPERAND (t, 0);
395 6882536 : if (t == error_mark_node)
396 : return false;
397 6882527 : if (TREE_CODE (t) == STATEMENT_LIST)
398 : {
399 1630855 : for (tree stmt : tsi_range (t))
400 916262 : if (! build_data_member_initialization (stmt, vec))
401 6164193 : return false;
402 : return true;
403 : }
404 6167934 : if (TREE_CODE (t) == CLEANUP_STMT)
405 : {
406 : /* We can't see a CLEANUP_STMT in a constructor for a literal class,
407 : but we can in a constexpr constructor for a non-literal class. Just
408 : ignore it; either all the initialization will be constant, in which
409 : case the cleanup can't run, or it can't be constexpr.
410 : Still recurse into CLEANUP_BODY. */
411 683980 : return build_data_member_initialization (CLEANUP_BODY (t), vec);
412 : }
413 5483954 : if (TREE_CODE (t) == CONVERT_EXPR)
414 3059402 : t = TREE_OPERAND (t, 0);
415 5483954 : if (TREE_CODE (t) == INIT_EXPR)
416 : {
417 2911905 : member = TREE_OPERAND (t, 0);
418 2911905 : init = break_out_target_exprs (TREE_OPERAND (t, 1));
419 : }
420 2572049 : else if (TREE_CODE (t) == CALL_EXPR)
421 : {
422 2091276 : tree fn = get_callee_fndecl (t);
423 4182552 : if (!fn || !DECL_CONSTRUCTOR_P (fn))
424 : /* We're only interested in calls to subobject constructors. */
425 : return true;
426 1676448 : member = CALL_EXPR_ARG (t, 0);
427 : /* We don't use build_cplus_new here because it complains about
428 : abstract bases. Leaving the call unwrapped means that it has the
429 : wrong type, but cxx_eval_constant_expression doesn't care. */
430 1676448 : init = break_out_target_exprs (t);
431 : }
432 480773 : else if (TREE_CODE (t) == BIND_EXPR)
433 34363 : return build_data_member_initialization (BIND_EXPR_BODY (t), vec);
434 : else
435 : /* Don't add anything else to the CONSTRUCTOR. */
436 : return true;
437 4588353 : if (INDIRECT_REF_P (member))
438 63181 : member = TREE_OPERAND (member, 0);
439 4588353 : if (TREE_CODE (member) == NOP_EXPR)
440 : {
441 568520 : tree op = member;
442 568520 : STRIP_NOPS (op);
443 568520 : if (TREE_CODE (op) == ADDR_EXPR)
444 : {
445 714 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
446 : (TREE_TYPE (TREE_TYPE (op)),
447 : TREE_TYPE (TREE_TYPE (member))));
448 : /* Initializing a cv-qualified member; we need to look through
449 : the const_cast. */
450 : member = op;
451 : }
452 567806 : else if (op == current_class_ptr
453 1135461 : && (same_type_ignoring_top_level_qualifiers_p
454 567655 : (TREE_TYPE (TREE_TYPE (member)),
455 : current_class_type)))
456 : /* Delegating constructor. */
457 : member = op;
458 : else
459 : {
460 : /* This is an initializer for an empty base; keep it for now so
461 : we can check it in cxx_eval_bare_aggregate. */
462 487971 : gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
463 : }
464 : }
465 4588353 : if (TREE_CODE (member) == ADDR_EXPR)
466 1171823 : member = TREE_OPERAND (member, 0);
467 4588353 : if (TREE_CODE (member) == COMPONENT_REF)
468 : {
469 3994566 : tree aggr = TREE_OPERAND (member, 0);
470 3994566 : if (TREE_CODE (aggr) == VAR_DECL)
471 : /* Initializing a local variable, don't add anything. */
472 : return true;
473 3994564 : if (TREE_CODE (aggr) != COMPONENT_REF)
474 : /* Normal member initialization. */
475 3989965 : member = TREE_OPERAND (member, 1);
476 4599 : else if (VAR_P (get_base_address (aggr)))
477 : /* Initializing a local variable, don't add anything. */
478 : return true;
479 4596 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
480 : /* Initializing a member of an anonymous union. */
481 4596 : return build_anon_member_initialization (member, init, vec);
482 : else
483 : /* We're initializing a vtable pointer in a base. Leave it as
484 : COMPONENT_REF so we remember the path to get to the vfield. */
485 0 : gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node);
486 : }
487 :
488 : /* Value-initialization can produce multiple initializers for the
489 : same field; use the last one. */
490 5722167 : if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
491 1324 : (*vec)->last().value = init;
492 : else
493 4582428 : CONSTRUCTOR_APPEND_ELT (*vec, member, init);
494 : return true;
495 : }
496 :
497 : /* Subroutine of check_constexpr_ctor_body_1 and constexpr_fn_retval.
498 : In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a
499 : BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations. */
500 :
501 : static bool
502 3772 : check_constexpr_bind_expr_vars (tree t)
503 : {
504 3772 : gcc_assert (TREE_CODE (t) == BIND_EXPR);
505 :
506 4610 : for (tree var = BIND_EXPR_VARS (t); var; var = DECL_CHAIN (var))
507 850 : if (TREE_CODE (var) == TYPE_DECL
508 831 : && DECL_IMPLICIT_TYPEDEF_P (var)
509 872 : && !LAMBDA_TYPE_P (TREE_TYPE (var)))
510 : return false;
511 : return true;
512 : }
513 :
514 : /* Subroutine of check_constexpr_ctor_body. */
515 :
516 : static bool
517 8627 : check_constexpr_ctor_body_1 (tree last, tree list)
518 : {
519 8627 : switch (TREE_CODE (list))
520 : {
521 6 : case DECL_EXPR:
522 6 : if (TREE_CODE (DECL_EXPR_DECL (list)) == USING_DECL
523 6 : || TREE_CODE (DECL_EXPR_DECL (list)) == TYPE_DECL)
524 : return true;
525 : return false;
526 :
527 4 : case CLEANUP_POINT_EXPR:
528 4 : return check_constexpr_ctor_body (last, TREE_OPERAND (list, 0),
529 4 : /*complain=*/false);
530 :
531 3429 : case BIND_EXPR:
532 3429 : if (!check_constexpr_bind_expr_vars (list)
533 3429 : || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list),
534 : /*complain=*/false))
535 : return false;
536 : return true;
537 :
538 : case USING_STMT:
539 : case STATIC_ASSERT:
540 : case DEBUG_BEGIN_STMT:
541 : return true;
542 :
543 : default:
544 : return false;
545 : }
546 : }
547 :
548 : /* Make sure that there are no statements after LAST in the constructor
549 : body represented by LIST. */
550 :
551 : bool
552 6121733 : check_constexpr_ctor_body (tree last, tree list, bool complain)
553 : {
554 : /* C++14 doesn't require a constexpr ctor to have an empty body. */
555 6121733 : if (cxx_dialect >= cxx14)
556 : return true;
557 :
558 15268 : bool ok = true;
559 15268 : if (TREE_CODE (list) == STATEMENT_LIST)
560 : {
561 13870 : tree_stmt_iterator i = tsi_last (list);
562 21028 : for (; !tsi_end_p (i); tsi_prev (&i))
563 : {
564 18870 : tree t = tsi_stmt (i);
565 18870 : if (t == last)
566 : break;
567 7229 : if (!check_constexpr_ctor_body_1 (last, t))
568 : {
569 : ok = false;
570 : break;
571 : }
572 : }
573 : }
574 1398 : else if (list != last
575 1398 : && !check_constexpr_ctor_body_1 (last, list))
576 : ok = false;
577 15268 : if (!ok && complain)
578 : {
579 50 : pedwarn (input_location, OPT_Wc__14_extensions,
580 : "%<constexpr%> constructor does not have empty body");
581 50 : ok = true;
582 : }
583 : return ok;
584 : }
585 :
586 : /* V is a vector of constructor elements built up for the base and member
587 : initializers of a constructor for TYPE. They need to be in increasing
588 : offset order, which they might not be yet if TYPE has a primary base
589 : which is not first in the base-clause or a vptr and at least one base
590 : all of which are non-primary. */
591 :
592 : static vec<constructor_elt, va_gc> *
593 3655285 : sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
594 : {
595 3655285 : tree pri = CLASSTYPE_PRIMARY_BINFO (type);
596 3655285 : tree field_type;
597 3655285 : unsigned i;
598 3655285 : constructor_elt *ce;
599 :
600 3655285 : if (pri)
601 90543 : field_type = BINFO_TYPE (pri);
602 3564742 : else if (TYPE_CONTAINS_VPTR_P (type))
603 38002 : field_type = vtbl_ptr_type_node;
604 : else
605 : return v;
606 :
607 : /* Find the element for the primary base or vptr and move it to the
608 : beginning of the vec. */
609 170566 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
610 132440 : if (TREE_TYPE (ce->index) == field_type)
611 : break;
612 :
613 150969 : if (i > 0 && i < vec_safe_length (v))
614 : {
615 34 : vec<constructor_elt, va_gc> &vref = *v;
616 34 : constructor_elt elt = vref[i];
617 68 : for (; i > 0; --i)
618 34 : vref[i] = vref[i-1];
619 34 : vref[0] = elt;
620 : }
621 :
622 : return v;
623 : }
624 :
625 : /* Build compile-time evalable representations of member-initializer list
626 : for a constexpr constructor. */
627 :
628 : static tree
629 3733921 : build_constexpr_constructor_member_initializers (tree type, tree body)
630 : {
631 3733921 : vec<constructor_elt, va_gc> *vec = NULL;
632 3733921 : bool ok = true;
633 5819633 : while (true)
634 5819633 : switch (TREE_CODE (body))
635 : {
636 2085633 : case MUST_NOT_THROW_EXPR:
637 2085633 : case EH_SPEC_BLOCK:
638 2085633 : case TRY_FINALLY_EXPR: // For C++26 postconditions.
639 2085633 : body = TREE_OPERAND (body, 0);
640 2085633 : break;
641 :
642 79 : case STATEMENT_LIST:
643 2085897 : for (tree stmt : tsi_range (body))
644 : {
645 161 : body = stmt;
646 161 : if (TREE_CODE (body) == BIND_EXPR)
647 : break;
648 : }
649 : break;
650 :
651 3733921 : case BIND_EXPR:
652 3733921 : body = BIND_EXPR_BODY (body);
653 3733921 : goto found;
654 :
655 0 : default:
656 0 : gcc_unreachable ();
657 : }
658 3733921 : found:
659 3733921 : if (TREE_CODE (body) == TRY_BLOCK)
660 : {
661 31 : body = TREE_OPERAND (body, 0);
662 31 : if (TREE_CODE (body) == BIND_EXPR)
663 31 : body = BIND_EXPR_BODY (body);
664 : }
665 3733921 : if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
666 : {
667 2013357 : body = TREE_OPERAND (body, 0);
668 2013357 : if (TREE_CODE (body) == EXPR_STMT)
669 2013321 : body = TREE_OPERAND (body, 0);
670 2013357 : if (TREE_CODE (body) == INIT_EXPR
671 2013357 : && (same_type_ignoring_top_level_qualifiers_p
672 0 : (TREE_TYPE (TREE_OPERAND (body, 0)),
673 : current_class_type)))
674 : {
675 : /* Trivial copy. */
676 0 : return TREE_OPERAND (body, 1);
677 : }
678 2013357 : ok = build_data_member_initialization (body, &vec);
679 : }
680 1720564 : else if (TREE_CODE (body) == STATEMENT_LIST)
681 : {
682 4944135 : for (tree stmt : tsi_range (body))
683 : {
684 3229073 : ok = build_data_member_initialization (stmt, &vec);
685 3229073 : if (!ok)
686 : break;
687 : }
688 : }
689 5501 : else if (EXPR_P (body))
690 5501 : ok = build_data_member_initialization (body, &vec);
691 : else
692 0 : gcc_assert (errorcount > 0);
693 3733921 : if (ok)
694 : {
695 3733912 : if (vec_safe_length (vec) > 0)
696 : {
697 : /* In a delegating constructor, return the target. */
698 3449807 : constructor_elt *ce = &(*vec)[0];
699 3449807 : if (ce->index == current_class_ptr)
700 : {
701 78627 : body = ce->value;
702 78627 : vec_free (vec);
703 78627 : return body;
704 : }
705 : }
706 3655285 : vec = sort_constexpr_mem_initializers (type, vec);
707 3655285 : return build_constructor (type, vec);
708 : }
709 : else
710 9 : return error_mark_node;
711 : }
712 :
713 : /* We have an expression tree T that represents a call, either CALL_EXPR
714 : or AGGR_INIT_EXPR. If the call is lexically to a named function,
715 : return the _DECL for that function. */
716 :
717 : static tree
718 569703550 : get_function_named_in_call (tree t)
719 : {
720 569703550 : tree callee = cp_get_callee (t);
721 569703550 : tree fun = cp_get_fndecl_from_callee (callee, /*fold*/false);
722 569703550 : return fun ? fun : callee;
723 : }
724 :
725 : /* Subroutine of check_constexpr_fundef. BODY is the body of a function
726 : declared to be constexpr, or a sub-statement thereof. Returns the
727 : return value if suitable, error_mark_node for a statement not allowed in
728 : a constexpr function, or NULL_TREE if no return value was found. */
729 :
730 : tree
731 70646 : constexpr_fn_retval (tree body)
732 : {
733 77469 : switch (TREE_CODE (body))
734 : {
735 18785 : case STATEMENT_LIST:
736 18785 : {
737 18785 : tree expr = NULL_TREE;
738 56285 : for (tree stmt : tsi_range (body))
739 : {
740 37529 : tree s = constexpr_fn_retval (stmt);
741 37529 : if (s == error_mark_node)
742 : return error_mark_node;
743 37502 : else if (s == NULL_TREE)
744 : /* Keep iterating. */;
745 18750 : else if (expr)
746 : /* Multiple return statements. */
747 : return error_mark_node;
748 : else
749 : expr = s;
750 : }
751 : return expr;
752 : }
753 :
754 33067 : case RETURN_EXPR:
755 33067 : return break_out_target_exprs (TREE_OPERAND (body, 0));
756 :
757 20 : case DECL_EXPR:
758 20 : {
759 20 : tree decl = DECL_EXPR_DECL (body);
760 20 : if (TREE_CODE (decl) == USING_DECL
761 : /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */
762 20 : || DECL_ARTIFICIAL (decl))
763 : return NULL_TREE;
764 6 : return error_mark_node;
765 : }
766 :
767 6486 : case CLEANUP_POINT_EXPR:
768 6486 : return constexpr_fn_retval (TREE_OPERAND (body, 0));
769 :
770 343 : case BIND_EXPR:
771 343 : if (!check_constexpr_bind_expr_vars (body))
772 6 : return error_mark_node;
773 337 : return constexpr_fn_retval (BIND_EXPR_BODY (body));
774 :
775 : case USING_STMT:
776 : case DEBUG_BEGIN_STMT:
777 : return NULL_TREE;
778 :
779 0 : case CALL_EXPR:
780 0 : {
781 0 : tree fun = get_function_named_in_call (body);
782 0 : if (fun != NULL_TREE
783 0 : && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE))
784 : return NULL_TREE;
785 : }
786 : /* Fallthru. */
787 :
788 30 : default:
789 30 : return error_mark_node;
790 : }
791 : }
792 :
793 : /* Subroutine of check_constexpr_fundef. BODY is the DECL_SAVED_TREE of
794 : FUN; do the necessary transformations to turn it into a single expression
795 : that we can store in the hash table. */
796 :
797 : static tree
798 31415459 : massage_constexpr_body (tree fun, tree body)
799 : {
800 62830918 : if (DECL_CONSTRUCTOR_P (fun))
801 3733921 : body = build_constexpr_constructor_member_initializers
802 3733921 : (DECL_CONTEXT (fun), body);
803 27681538 : else if (cxx_dialect < cxx14)
804 : {
805 32882 : if (TREE_CODE (body) == EH_SPEC_BLOCK)
806 1 : body = EH_SPEC_STMTS (body);
807 32882 : if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
808 21467 : body = TREE_OPERAND (body, 0);
809 32882 : body = constexpr_fn_retval (body);
810 : }
811 31415459 : return body;
812 : }
813 :
814 : /* CTYPE is a type constructed from BODY. Return true if some
815 : bases/fields are uninitialized, and complain if COMPLAIN. */
816 :
817 : static bool
818 3383562 : cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
819 : {
820 : /* We allow uninitialized bases/fields in C++20. */
821 3383562 : if (cxx_dialect >= cxx20)
822 : return false;
823 :
824 13768 : unsigned nelts = 0;
825 :
826 13768 : if (body)
827 : {
828 13764 : if (TREE_CODE (body) != CONSTRUCTOR)
829 : return false;
830 13711 : nelts = CONSTRUCTOR_NELTS (body);
831 : }
832 13715 : tree field = TYPE_FIELDS (ctype);
833 :
834 13715 : if (TREE_CODE (ctype) == UNION_TYPE)
835 : {
836 110 : if (nelts == 0 && next_aggregate_field (field))
837 : {
838 2 : if (complain)
839 2 : error ("%<constexpr%> constructor for union %qT must "
840 : "initialize exactly one non-static data member", ctype);
841 : return true;
842 : }
843 : return false;
844 : }
845 :
846 : /* Iterate over the CONSTRUCTOR, checking any missing fields don't
847 : need an explicit initialization. */
848 : bool bad = false;
849 28868 : for (unsigned i = 0; i <= nelts; ++i)
850 : {
851 28868 : tree index = NULL_TREE;
852 28868 : if (i < nelts)
853 : {
854 15263 : index = CONSTRUCTOR_ELT (body, i)->index;
855 : /* Skip vptr adjustment represented with a COMPONENT_REF. */
856 15263 : if (TREE_CODE (index) != FIELD_DECL)
857 627 : continue;
858 : }
859 :
860 498362 : for (; field != index; field = DECL_CHAIN (field))
861 : {
862 470127 : tree ftype;
863 470127 : if (TREE_CODE (field) != FIELD_DECL)
864 470099 : continue;
865 1789 : if (DECL_UNNAMED_BIT_FIELD (field))
866 10 : continue;
867 : /* Artificial fields can be ignored unless they're bases. */
868 1779 : if (DECL_ARTIFICIAL (field) && !DECL_FIELD_IS_BASE (field))
869 6 : continue;
870 1773 : if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
871 : {
872 : /* Recurse to check the anonymous aggregate member. */
873 8 : bad |= cx_check_missing_mem_inits
874 4 : (TREE_TYPE (field), NULL_TREE, complain);
875 4 : if (bad && !complain)
876 6 : return true;
877 4 : continue;
878 : }
879 1769 : ftype = TREE_TYPE (field);
880 1769 : if (!ftype || !TYPE_P (ftype) || !COMPLETE_TYPE_P (ftype))
881 : /* A flexible array can't be initialized here, so don't complain
882 : that it isn't. */
883 1 : continue;
884 1768 : if (is_empty_field (field))
885 : /* An empty field doesn't need an initializer. */
886 1733 : continue;
887 35 : ftype = strip_array_types (ftype);
888 35 : if (type_has_constexpr_default_constructor (ftype))
889 : {
890 : /* It's OK to skip a member with a trivial constexpr ctor.
891 : A constexpr ctor that isn't trivial should have been
892 : added in by now. */
893 7 : gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)
894 : || errorcount != 0);
895 7 : continue;
896 : }
897 28 : if (!complain)
898 : return true;
899 22 : auto_diagnostic_group d;
900 22 : error ("member %qD must be initialized by mem-initializer "
901 : "in %<constexpr%> constructor", field);
902 22 : inform (DECL_SOURCE_LOCATION (field), "declared here");
903 22 : bad = true;
904 22 : }
905 28235 : if (field == NULL_TREE)
906 : break;
907 :
908 14636 : if (ANON_AGGR_TYPE_P (TREE_TYPE (index)))
909 : {
910 : /* Check the anonymous aggregate initializer is valid. */
911 38 : bad |= cx_check_missing_mem_inits
912 38 : (TREE_TYPE (index), CONSTRUCTOR_ELT (body, i)->value, complain);
913 38 : if (bad && !complain)
914 : return true;
915 : }
916 14636 : field = DECL_CHAIN (field);
917 : }
918 :
919 : return bad;
920 : }
921 :
922 : /* We are processing the definition of the constexpr function FUN.
923 : Check that its body fulfills the appropriate requirements and
924 : enter it in the constexpr function definition table. */
925 :
926 : void
927 169652789 : maybe_save_constexpr_fundef (tree fun)
928 : {
929 169652789 : if (processing_template_decl
930 70026581 : || cp_function_chain->invalid_constexpr
931 239661027 : || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
932 138237624 : return;
933 :
934 : /* With -fimplicit-constexpr, try to make inlines constexpr. We'll
935 : actually set DECL_DECLARED_CONSTEXPR_P below if the checks pass. */
936 53524696 : bool implicit = false;
937 53524696 : if (flag_implicit_constexpr)
938 : {
939 22 : if (DECL_DELETING_DESTRUCTOR_P (fun)
940 22 : && decl_implicit_constexpr_p (DECL_CLONED_FUNCTION (fun)))
941 : /* Don't inherit implicit constexpr from the non-deleting
942 : destructor. */
943 0 : DECL_DECLARED_CONSTEXPR_P (fun) = false;
944 :
945 22 : if (!DECL_DECLARED_CONSTEXPR_P (fun)
946 18 : && DECL_DECLARED_INLINE_P (fun)
947 36 : && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fun)))
948 : implicit = true;
949 : }
950 :
951 53524696 : if (!DECL_DECLARED_CONSTEXPR_P (fun) && !implicit)
952 : return;
953 :
954 31471374 : bool complain = !DECL_GENERATED_P (fun) && !implicit;
955 :
956 31471374 : if (!is_valid_constexpr_fn (fun, complain))
957 : return;
958 :
959 31415379 : tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
960 31415379 : if (massaged == NULL_TREE || massaged == error_mark_node)
961 : {
962 72 : if (!DECL_CONSTRUCTOR_P (fun) && complain)
963 22 : error ("body of %<constexpr%> function %qD not a return-statement",
964 : fun);
965 : return;
966 : }
967 :
968 31415343 : bool potential = potential_rvalue_constant_expression (massaged);
969 31415343 : if (!potential && complain)
970 264 : require_potential_rvalue_constant_expression_fncheck (massaged);
971 :
972 35149241 : if (DECL_CONSTRUCTOR_P (fun) && potential
973 35145112 : && !DECL_DEFAULTED_FN (fun))
974 : {
975 3383506 : if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
976 : massaged, complain))
977 : potential = false;
978 3383480 : else if (cxx_dialect > cxx11)
979 : {
980 : /* What we got from massage_constexpr_body is pretty much just the
981 : ctor-initializer, also check the body. */
982 3378616 : massaged = DECL_SAVED_TREE (fun);
983 3378616 : potential = potential_rvalue_constant_expression (massaged);
984 3378616 : if (!potential && complain)
985 20 : require_potential_rvalue_constant_expression_fncheck (massaged);
986 : }
987 : }
988 :
989 31415343 : if (!potential && complain
990 : /* If -Wno-invalid-constexpr was specified, we haven't complained
991 : about non-constant expressions yet. Register the function and
992 : complain in explain_invalid_constexpr_fn if the function is
993 : called. */
994 304 : && warn_invalid_constexpr != 0)
995 : return;
996 :
997 31415176 : if (implicit)
998 : {
999 14 : if (potential)
1000 : {
1001 3 : DECL_DECLARED_CONSTEXPR_P (fun) = true;
1002 3 : DECL_LANG_SPECIFIC (fun)->u.fn.implicit_constexpr = true;
1003 6 : if (DECL_CONSTRUCTOR_P (fun))
1004 0 : TYPE_HAS_CONSTEXPR_CTOR (DECL_CONTEXT (fun)) = true;
1005 : }
1006 : else
1007 : /* Don't bother keeping the pre-generic body of unsuitable functions
1008 : not explicitly declared constexpr. */
1009 : return;
1010 : }
1011 :
1012 31415165 : constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
1013 31415165 : bool clear_ctx = false;
1014 31415165 : if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
1015 : {
1016 31415165 : clear_ctx = true;
1017 31415165 : DECL_CONTEXT (DECL_RESULT (fun)) = fun;
1018 : }
1019 31415165 : tree saved_fn = current_function_decl;
1020 31415165 : current_function_decl = fun;
1021 31415165 : entry.body = copy_fn (entry.decl, entry.parms, entry.result);
1022 31415165 : current_function_decl = saved_fn;
1023 31415165 : if (clear_ctx)
1024 31415165 : DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
1025 31415165 : if (!potential)
1026 : /* For a template instantiation, we want to remember the pre-generic body
1027 : for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression
1028 : that it doesn't need to bother trying to expand the function. */
1029 61335 : entry.result = error_mark_node;
1030 :
1031 31415165 : register_constexpr_fundef (entry);
1032 : }
1033 :
1034 : /* BODY is a validated and massaged definition of a constexpr
1035 : function. Register it in the hash table. */
1036 :
1037 : void
1038 31453847 : register_constexpr_fundef (const constexpr_fundef &value)
1039 : {
1040 : /* Create the constexpr function table if necessary. */
1041 31453847 : if (constexpr_fundef_table == NULL)
1042 28030 : constexpr_fundef_table
1043 28030 : = hash_table<constexpr_fundef_hasher>::create_ggc (101);
1044 :
1045 31453847 : constexpr_fundef **slot = constexpr_fundef_table->find_slot
1046 31453847 : (const_cast<constexpr_fundef *> (&value), INSERT);
1047 :
1048 31453847 : gcc_assert (*slot == NULL);
1049 31453847 : *slot = ggc_alloc<constexpr_fundef> ();
1050 31453847 : **slot = value;
1051 31453847 : }
1052 :
1053 : /* FUN is a non-constexpr (or, with -Wno-invalid-constexpr, a constexpr
1054 : function called in a context that requires a constant expression).
1055 : If it comes from a constexpr template, explain why the instantiation
1056 : isn't constexpr. Otherwise, explain why the function cannot be used
1057 : in a constexpr context. */
1058 :
1059 : void
1060 1063 : explain_invalid_constexpr_fn (tree fun)
1061 : {
1062 1063 : static hash_set<tree> *diagnosed;
1063 1063 : tree body;
1064 :
1065 : /* Don't try to explain a function we already complained about. */
1066 1063 : if (function *f = DECL_STRUCT_FUNCTION (fun))
1067 859 : if (f->language->erroneous)
1068 1063 : return;
1069 :
1070 : /* In C++23, a function marked 'constexpr' may not actually be a constant
1071 : expression. We haven't diagnosed the problem yet: -Winvalid-constexpr
1072 : wasn't enabled. The function was called, so diagnose why it cannot be
1073 : used in a constant expression. */
1074 1014 : if (warn_invalid_constexpr == 0 && DECL_DECLARED_CONSTEXPR_P (fun))
1075 : /* Go on. */;
1076 : /* Only diagnose defaulted functions, lambdas, or instantiations. */
1077 978 : else if (!DECL_DEFAULTED_FN (fun)
1078 1230 : && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
1079 941 : && !(flag_implicit_constexpr
1080 9 : && !DECL_DECLARED_CONSTEXPR_P (fun)
1081 9 : && DECL_DECLARED_INLINE_P (fun))
1082 1913 : && !is_instantiation_of_constexpr (fun))
1083 : {
1084 917 : inform (DECL_SOURCE_LOCATION (fun), "%qD declared here", fun);
1085 3 : if (flag_implicit_constexpr && !maybe_constexpr_fn (fun)
1086 920 : && decl_defined_p (fun))
1087 3 : inform (DECL_SOURCE_LOCATION (fun),
1088 : "%<-fimplicit-constexpr%> only affects %<inline%> functions");
1089 : return;
1090 : }
1091 97 : if (diagnosed == NULL)
1092 74 : diagnosed = new hash_set<tree>;
1093 97 : if (diagnosed->add (fun))
1094 : /* Already explained. */
1095 : return;
1096 :
1097 96 : iloc_sentinel ils = input_location;
1098 96 : if (!lambda_static_thunk_p (fun))
1099 : {
1100 : /* Diagnostics should completely ignore the static thunk, so leave
1101 : input_location set to our caller's location. */
1102 84 : input_location = DECL_SOURCE_LOCATION (fun);
1103 84 : inform (input_location,
1104 : "%qD is not usable as a %<constexpr%> function because:", fun);
1105 : }
1106 : /* First check the declaration. */
1107 96 : if (is_valid_constexpr_fn (fun, true))
1108 : {
1109 : /* Then if it's OK, the body. */
1110 90 : if (!DECL_DECLARED_CONSTEXPR_P (fun)
1111 90 : && DECL_DEFAULTED_FN (fun))
1112 10 : explain_implicit_non_constexpr (fun);
1113 : else
1114 : {
1115 80 : if (constexpr_fundef *fd = retrieve_constexpr_fundef (fun))
1116 54 : body = fd->body;
1117 : else
1118 26 : body = DECL_SAVED_TREE (fun);
1119 80 : tree massaged = massage_constexpr_body (fun, body);
1120 80 : require_potential_rvalue_constant_expression (massaged);
1121 160 : if (DECL_CONSTRUCTOR_P (fun))
1122 : {
1123 14 : cx_check_missing_mem_inits (DECL_CONTEXT (fun), massaged, true);
1124 14 : if (cxx_dialect > cxx11)
1125 : /* Also check the body, not just the ctor-initializer. */
1126 12 : require_potential_rvalue_constant_expression (body);
1127 : }
1128 66 : else if (massaged == NULL_TREE || massaged == error_mark_node)
1129 1 : error ("body of %<constexpr%> function %qD not a return-statement",
1130 : fun);
1131 : }
1132 : }
1133 96 : }
1134 :
1135 : /* Objects of this type represent calls to constexpr functions
1136 : along with the bindings of parameters to their arguments, for
1137 : the purpose of compile time evaluation. */
1138 :
1139 : struct GTY((for_user)) constexpr_call {
1140 : /* Description of the constexpr function definition. */
1141 : constexpr_fundef *fundef = nullptr;
1142 : /* Parameter bindings environment. A TREE_VEC of arguments. */
1143 : tree bindings = NULL_TREE;
1144 : /* Result of the call, indexed by the value of
1145 : constexpr_ctx::manifestly_const_eval.
1146 : unknown_type_node means the call is being evaluated.
1147 : error_mark_node means that the evaluation was erroneous or otherwise
1148 : uncacheable (e.g. because it depends on the caller).
1149 : Otherwise, the actual value of the call. */
1150 : tree results[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
1151 : /* The hash of this call; we remember it here to avoid having to
1152 : recalculate it when expanding the hash table. */
1153 : hashval_t hash = 0;
1154 :
1155 : /* The result slot corresponding to the given mce_value. */
1156 65162128 : tree& result (mce_value mce) { return results[1 + int(mce)]; }
1157 : };
1158 :
1159 : struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
1160 : {
1161 : static hashval_t hash (constexpr_call *);
1162 : static bool equal (constexpr_call *, constexpr_call *);
1163 : };
1164 :
1165 : enum constexpr_switch_state {
1166 : /* Used when processing a switch for the first time by cxx_eval_switch_expr
1167 : and default: label for that switch has not been seen yet. */
1168 : css_default_not_seen,
1169 : /* Used when processing a switch for the first time by cxx_eval_switch_expr
1170 : and default: label for that switch has been seen already. */
1171 : css_default_seen,
1172 : /* Used when processing a switch for the second time by
1173 : cxx_eval_switch_expr, where default: label should match. */
1174 : css_default_processing
1175 : };
1176 :
1177 : /* The constexpr expansion context part which needs one instance per
1178 : cxx_eval_outermost_constant_expr invocation. VALUES is a map of values of
1179 : variables initialized within the expression. */
1180 :
1181 : class constexpr_global_ctx {
1182 : /* Values for any temporaries or local variables within the
1183 : constant-expression. Objects outside their lifetime have
1184 : value 'void_node' or 'void_list_node', the former if they are outside
1185 : of lifetime but still before storage has been deallocated. */
1186 : hash_map<tree,tree> values;
1187 : public:
1188 : /* Number of cxx_eval_constant_expression calls (except skipped ones,
1189 : on simple constants or location wrappers) encountered during current
1190 : cxx_eval_outermost_constant_expr call. */
1191 : HOST_WIDE_INT constexpr_ops_count;
1192 : /* Heap VAR_DECLs created during the evaluation of the outermost constant
1193 : expression. */
1194 : auto_vec<tree, 16> heap_vars;
1195 : /* Vector of caught exceptions, including exceptions still not active at
1196 : the start of a handler (those are immediately followed up by HANDLER_TYPE
1197 : until __cxa_begin_catch finishes). If __cxa_begin_catch or
1198 : __cxa_get_exception_ptr need to create temporaries, the VAR_DECL of the
1199 : exception object is wrapped in the vector into a TREE_LIST where
1200 : TREE_VALUE of it is the VAR_DECL of the exception object and TREE_PURPOSE
1201 : one of the temporaries, others chained through DECL_CHAIN. */
1202 : auto_vec<tree, 2> caught_exceptions;
1203 : /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */
1204 : vec<tree> *cleanups;
1205 : /* If non-null, only allow modification of existing values of the variables
1206 : in this set. Set by modifiable_tracker, below. */
1207 : hash_set<tree> *modifiable;
1208 : /* If cxx_eval_outermost_constant_expr is called on the consteval block
1209 : operator (), this is the FUNCTION_DECL of that operator (). */
1210 : tree consteval_block;
1211 : /* Number of heap VAR_DECL deallocations. */
1212 : unsigned heap_dealloc_count;
1213 : /* Number of uncaught exceptions. */
1214 : unsigned uncaught_exceptions;
1215 : /* A contract statement that failed or was not constant, we only store the
1216 : first one that fails. */
1217 : tree contract_statement;
1218 : /* [basic.contract.eval]/7.3 if this expression would otherwise be constant
1219 : then a non-const contract makes the program ill-formed. */
1220 : bool contract_condition_non_const;
1221 : /* Some metafunctions aren't dependent just on their arguments, but also
1222 : on various other dependencies, e.g. has_identifier on a function parameter
1223 : reflection can change depending on further declarations of corresponding
1224 : function, is_complete_type depends on type definitions and template
1225 : specializations in between the calls, define_aggregate even defines
1226 : class types, etc. Thus, we need to arrange for calls which call
1227 : at least some metafunctions to be non-cacheable, because their behavior
1228 : might not be the same. Until we figure out which exact metafunctions
1229 : need this and which don't, do it for all of them.
1230 : Also used for some cases in constexpr EH, e.g. __cxa_rethrow,
1231 : __builtin_uncaught_exceptions and __builtin_current_exception, which can
1232 : be also dependent on some state (pending uncaught or caught exceptions)
1233 : not tracked in the constexpr call caching. */
1234 : bool state_dependent;
1235 :
1236 : /* Constructor. */
1237 581596999 : constexpr_global_ctx ()
1238 581596999 : : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
1239 581596999 : consteval_block (NULL_TREE), heap_dealloc_count (0),
1240 581596999 : uncaught_exceptions (0), contract_statement (NULL_TREE),
1241 581596999 : contract_condition_non_const (false), state_dependent (false) {}
1242 :
1243 467936935 : bool is_outside_lifetime (tree t)
1244 : {
1245 467936935 : if (tree *p = values.get (t))
1246 210704643 : if (*p == void_node || *p == void_list_node)
1247 268 : return true;
1248 : return false;
1249 : }
1250 : /* This differs from !is_outside_lifetime in that it returns false if
1251 : T is not in the map. */
1252 108 : bool in_eval_lifetime_p (tree t)
1253 : {
1254 108 : if (tree *p = values.get (t))
1255 40 : if (*p != void_node && *p != void_list_node)
1256 40 : return true;
1257 : return false;
1258 : }
1259 592424349 : tree get_value (tree t)
1260 : {
1261 592424349 : if (tree *p = values.get (t))
1262 310309682 : if (*p != void_node && *p != void_list_node)
1263 302149609 : return *p;
1264 : return NULL_TREE;
1265 : }
1266 5036 : tree *get_raw_value_ptr (tree t)
1267 : {
1268 5036 : return values.get (t);
1269 : }
1270 126146718 : tree *get_value_ptr (tree t, bool initializing)
1271 : {
1272 126146718 : if (modifiable && !modifiable->contains (t))
1273 : return nullptr;
1274 126146701 : if (tree *p = values.get (t))
1275 : {
1276 126137143 : if (*p != void_node && *p != void_list_node)
1277 : return p;
1278 63 : else if (initializing)
1279 : {
1280 21 : *p = NULL_TREE;
1281 21 : return p;
1282 : }
1283 : }
1284 : return nullptr;
1285 : }
1286 304135942 : void put_value (tree t, tree v)
1287 : {
1288 : /* If modifiable is not null, any key that was not previously in the
1289 : map, or that has been destroyed and freed (as indicated by
1290 : void_list_node), is tracked in modifiable. If the object is there,
1291 : or its storage remains (as indicated by void_node), then we don't
1292 : track it as modifiable. */
1293 304135942 : bool already_in_map;
1294 304135942 : tree &slot = values.get_or_insert (t, &already_in_map);
1295 304135942 : bool newval = !already_in_map || slot == void_list_node;
1296 304135942 : slot = v;
1297 304135942 : if (newval && modifiable)
1298 64 : modifiable->add (t);
1299 304135942 : }
1300 243820099 : void destroy_value (tree t, bool past_storage_end = true)
1301 : {
1302 243820099 : if (TREE_CODE (t) == VAR_DECL
1303 243820099 : || TREE_CODE (t) == PARM_DECL
1304 : || TREE_CODE (t) == RESULT_DECL)
1305 244111384 : values.put (t, past_storage_end ? void_list_node : void_node);
1306 : else
1307 9269 : values.remove (t);
1308 243820099 : }
1309 19330401 : void clear_value (tree t)
1310 : {
1311 38660802 : values.remove (t);
1312 : }
1313 : };
1314 :
1315 : /* Helper class for constexpr_global_ctx. In some cases we want to avoid
1316 : side-effects from evaluation of a particular subexpression of a
1317 : constant-expression. In such cases we use modifiable_tracker to prevent
1318 : modification of variables created outside of that subexpression. Keep and
1319 : then restore the original value of global->modifiable so that tracker
1320 : instantiations can nest.
1321 :
1322 : ??? We could change the hash_set to a hash_map, allow and track external
1323 : modifications, and roll them back in the destructor. It's not clear to me
1324 : that this would be worthwhile. */
1325 :
1326 : class modifiable_tracker
1327 : {
1328 : hash_set<tree> set;
1329 : constexpr_global_ctx *global;
1330 : hash_set<tree> *previous_set;
1331 : public:
1332 173612 : modifiable_tracker (constexpr_global_ctx *g)
1333 173612 : : global (g), previous_set (g->modifiable)
1334 : {
1335 173612 : global->modifiable = &set;
1336 173612 : }
1337 173612 : ~modifiable_tracker ()
1338 : {
1339 173676 : for (tree t: set)
1340 64 : global->clear_value (t);
1341 173612 : global->modifiable = previous_set;
1342 173612 : }
1343 : };
1344 :
1345 : /* The constexpr expansion context. CALL is the current function
1346 : expansion, CTOR is the current aggregate initializer, OBJECT is the
1347 : object being initialized by CTOR, either a VAR_DECL or a _REF. */
1348 :
1349 : struct constexpr_ctx {
1350 : /* The part of the context that needs to be unique to the whole
1351 : cxx_eval_outermost_constant_expr invocation. */
1352 : constexpr_global_ctx *global;
1353 : /* The innermost call we're evaluating. */
1354 : constexpr_call *call;
1355 : /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen
1356 : within the current LOOP_EXPR. NULL if we aren't inside a loop. */
1357 : vec<tree> *save_exprs;
1358 : /* The CONSTRUCTOR we're currently building up for an aggregate
1359 : initializer. */
1360 : tree ctor;
1361 : /* The object we're building the CONSTRUCTOR for. */
1362 : tree object;
1363 : /* If inside SWITCH_EXPR. */
1364 : constexpr_switch_state *css_state;
1365 : /* The aggregate initialization context inside which this one is nested. This
1366 : is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs. */
1367 : const constexpr_ctx *parent;
1368 :
1369 : /* Whether we should error on a non-constant expression or fail quietly.
1370 : This flag needs to be here, but some of the others could move to global
1371 : if they get larger than a word. */
1372 : bool quiet;
1373 : /* Whether we are strictly conforming to constant expression rules or
1374 : trying harder to get a constant value. */
1375 : bool strict;
1376 : /* Whether __builtin_is_constant_evaluated () should be true. */
1377 : mce_value manifestly_const_eval;
1378 : };
1379 :
1380 : /* Return ctx->quiet. For use in reflect.cc. */
1381 :
1382 : bool
1383 1376 : cxx_constexpr_quiet_p (const constexpr_ctx *ctx)
1384 : {
1385 1376 : return ctx->quiet;
1386 : }
1387 :
1388 : /* Return ctx->manifestly_const_eval. For use in reflect.cc. */
1389 :
1390 : mce_value
1391 388 : cxx_constexpr_manifestly_const_eval (const constexpr_ctx *ctx)
1392 : {
1393 388 : return ctx->manifestly_const_eval;
1394 : }
1395 :
1396 : /* Return ctx->call->fundef->decl or NULL_TREE. For use in
1397 : reflect.cc. */
1398 :
1399 : tree
1400 2120 : cxx_constexpr_caller (const constexpr_ctx *ctx)
1401 : {
1402 2120 : if (ctx->call)
1403 958 : return ctx->call->fundef->decl;
1404 : else
1405 : return NULL_TREE;
1406 : }
1407 :
1408 : /* Return ctx->global->consteval_block. For use in reflect.cc. */
1409 :
1410 : tree
1411 159 : cxx_constexpr_consteval_block (const constexpr_ctx *ctx)
1412 : {
1413 159 : return ctx->global->consteval_block;
1414 : }
1415 :
1416 : /* Return true if T's lifetime began within the core constant expression
1417 : currently under evaluation. */
1418 :
1419 : bool
1420 108 : cxx_constexpr_in_eval_lifetime_p (const constexpr_ctx *ctx, tree t)
1421 : {
1422 108 : return ctx->global->in_eval_lifetime_p (t);
1423 : }
1424 :
1425 : /* Predicates for the meaning of *jump_target. */
1426 :
1427 : static bool
1428 111147123 : returns (tree *jump_target)
1429 : {
1430 19399449 : return *jump_target && TREE_CODE (*jump_target) == RETURN_EXPR;
1431 : }
1432 :
1433 : static bool
1434 105665219 : breaks (tree *jump_target)
1435 : {
1436 105665219 : return (*jump_target
1437 105665219 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1438 339 : && LABEL_DECL_BREAK (*jump_target))
1439 1378901 : || TREE_CODE (*jump_target) == BREAK_STMT
1440 1240238 : || TREE_CODE (*jump_target) == EXIT_EXPR));
1441 : }
1442 :
1443 : static bool
1444 142661265 : continues (tree *jump_target)
1445 : {
1446 142661265 : return (*jump_target
1447 142661265 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1448 339 : && LABEL_DECL_CONTINUE (*jump_target))
1449 1255695 : || TREE_CODE (*jump_target) == CONTINUE_STMT));
1450 : }
1451 :
1452 : static bool
1453 12990095 : switches (tree *jump_target)
1454 : {
1455 78173 : return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST;
1456 : }
1457 :
1458 : static bool
1459 1931722322 : throws (tree *jump_target)
1460 : {
1461 : /* void_node is for use in potential_constant_expression_1, otherwise
1462 : it should an artificial VAR_DECL created by constant evaluation
1463 : of __cxa_allocate_exception (). */
1464 214451495 : return (*jump_target && (VAR_P (*jump_target) || *jump_target == void_node));
1465 : }
1466 :
1467 : /* True if the constexpr relaxations afforded by P2280R4 for unknown
1468 : references and objects are in effect. */
1469 :
1470 : static bool
1471 272053901 : p2280_active_p (const constexpr_ctx *ctx)
1472 : {
1473 34704007 : if (ctx->manifestly_const_eval != mce_true)
1474 : /* Disable these relaxations during speculative constexpr folding,
1475 : as it can significantly increase compile time/memory use
1476 : (PR119387). */
1477 : return false;
1478 :
1479 : /* P2280R4 was accepted as a DR against C++11. */
1480 0 : return cxx_dialect >= cxx11;
1481 : }
1482 :
1483 : /* Remove T from the global values map, checking for attempts to destroy
1484 : a value that has already finished its lifetime. */
1485 :
1486 : static void
1487 243436868 : destroy_value_checked (const constexpr_ctx* ctx, tree t, bool *non_constant_p)
1488 : {
1489 243436868 : if (t == error_mark_node || TREE_TYPE (t) == error_mark_node)
1490 : return;
1491 :
1492 : /* Don't error again here if we've already reported a problem. */
1493 243436807 : if (!*non_constant_p
1494 211907765 : && DECL_P (t)
1495 : /* Non-trivial destructors have their lifetimes ended explicitly
1496 : with a clobber, so don't worry about it here. */
1497 211898702 : && (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (t))
1498 : /* ...except parameters are remapped in cxx_eval_call_expression,
1499 : and the destructor call during cleanup won't be able to tell that
1500 : this value has already been destroyed, so complain now. This is
1501 : not quite unobservable, but is extremely unlikely to crop up in
1502 : practice; see g++.dg/cpp2a/constexpr-lifetime2.C. */
1503 772472 : || TREE_CODE (t) == PARM_DECL)
1504 454564488 : && ctx->global->is_outside_lifetime (t))
1505 : {
1506 54 : if (!ctx->quiet)
1507 : {
1508 18 : auto_diagnostic_group d;
1509 18 : error ("destroying %qE outside its lifetime", t);
1510 18 : inform (DECL_SOURCE_LOCATION (t), "declared here");
1511 18 : }
1512 54 : *non_constant_p = true;
1513 : }
1514 243436807 : ctx->global->destroy_value (t);
1515 : }
1516 :
1517 : /* This internal flag controls whether we should avoid doing anything during
1518 : constexpr evaluation that would cause extra DECL_UID generation, such as
1519 : template instantiation and function body copying. */
1520 :
1521 : static bool uid_sensitive_constexpr_evaluation_value;
1522 :
1523 : /* An internal counter that keeps track of the number of times
1524 : uid_sensitive_constexpr_evaluation_p returned true. */
1525 :
1526 : static unsigned uid_sensitive_constexpr_evaluation_true_counter;
1527 :
1528 : /* The accessor for uid_sensitive_constexpr_evaluation_value which also
1529 : increments the corresponding counter. */
1530 :
1531 : static bool
1532 9123101 : uid_sensitive_constexpr_evaluation_p ()
1533 : {
1534 9036941 : if (uid_sensitive_constexpr_evaluation_value)
1535 : {
1536 243774 : ++uid_sensitive_constexpr_evaluation_true_counter;
1537 243765 : return true;
1538 : }
1539 : else
1540 : return false;
1541 : }
1542 :
1543 : /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel
1544 : enables the internal flag for uid_sensitive_constexpr_evaluation_p
1545 : during the lifetime of the sentinel object. Upon its destruction, the
1546 : previous value of uid_sensitive_constexpr_evaluation_p is restored. */
1547 :
1548 81775098 : uid_sensitive_constexpr_evaluation_sentinel
1549 : ::uid_sensitive_constexpr_evaluation_sentinel ()
1550 81775098 : : ovr (uid_sensitive_constexpr_evaluation_value, true)
1551 : {
1552 81775098 : }
1553 :
1554 : /* The default constructor for uid_sensitive_constexpr_evaluation_checker
1555 : records the current number of times that uid_sensitive_constexpr_evaluation_p
1556 : has been called and returned true. */
1557 :
1558 3892795186 : uid_sensitive_constexpr_evaluation_checker
1559 : ::uid_sensitive_constexpr_evaluation_checker ()
1560 3892795186 : : saved_counter (uid_sensitive_constexpr_evaluation_true_counter)
1561 : {
1562 3892795186 : }
1563 :
1564 : /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and
1565 : some constexpr evaluation was restricted due to u_s_c_e_p being called
1566 : and returning true during the lifetime of this checker object. */
1567 :
1568 : bool
1569 2582110806 : uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const
1570 : {
1571 2582110806 : return (uid_sensitive_constexpr_evaluation_value
1572 2582110806 : && saved_counter != uid_sensitive_constexpr_evaluation_true_counter);
1573 : }
1574 :
1575 :
1576 : /* A table of all constexpr calls that have been evaluated by the
1577 : compiler in this translation unit. */
1578 :
1579 : static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
1580 :
1581 : /* Compute a hash value for a constexpr call representation. */
1582 :
1583 : inline hashval_t
1584 230601689 : constexpr_call_hasher::hash (constexpr_call *info)
1585 : {
1586 230601689 : return info->hash;
1587 : }
1588 :
1589 : /* Return true if the objects pointed to by P and Q represent calls
1590 : to the same constexpr function with the same arguments.
1591 : Otherwise, return false. */
1592 :
1593 : bool
1594 240682044 : constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
1595 : {
1596 240682044 : if (lhs == rhs)
1597 : return true;
1598 240682044 : if (lhs->hash != rhs->hash)
1599 : return false;
1600 27905391 : if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
1601 : return false;
1602 27905391 : return cp_tree_equal (lhs->bindings, rhs->bindings);
1603 : }
1604 :
1605 : /* Initialize the constexpr call table, if needed. */
1606 :
1607 : static void
1608 37135456 : maybe_initialize_constexpr_call_table (void)
1609 : {
1610 37135456 : if (constexpr_call_table == NULL)
1611 18833 : constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
1612 37135456 : }
1613 :
1614 : /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
1615 : a function happens to get called recursively, we unshare the callee
1616 : function's body and evaluate this unshared copy instead of evaluating the
1617 : original body.
1618 :
1619 : FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function
1620 : copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map
1621 : that's keyed off of the original FUNCTION_DECL and whose value is a
1622 : TREE_LIST of this function's unused copies awaiting reuse.
1623 :
1624 : This is not GC-deletable to avoid GC affecting UID generation. */
1625 :
1626 : static GTY(()) decl_tree_map *fundef_copies_table;
1627 :
1628 : /* Reuse a copy or create a new unshared copy of the function FUN.
1629 : Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE
1630 : is parms, TYPE is result. */
1631 :
1632 : static tree
1633 87356815 : get_fundef_copy (constexpr_fundef *fundef)
1634 : {
1635 87356815 : tree copy;
1636 87356815 : bool existed;
1637 87356815 : tree *slot = &(hash_map_safe_get_or_insert<hm_ggc>
1638 87356815 : (fundef_copies_table, fundef->decl, &existed, 127));
1639 :
1640 87356815 : if (!existed)
1641 : {
1642 : /* There is no cached function available, or in use. We can use
1643 : the function directly. That the slot is now created records
1644 : that this function is now in use. */
1645 7659019 : copy = build_tree_list (fundef->body, fundef->parms);
1646 7659019 : TREE_TYPE (copy) = fundef->result;
1647 : }
1648 79697796 : else if (*slot == NULL_TREE)
1649 : {
1650 4443 : if (uid_sensitive_constexpr_evaluation_p ())
1651 9 : return NULL_TREE;
1652 :
1653 : /* We've already used the function itself, so make a copy. */
1654 4434 : copy = build_tree_list (NULL, NULL);
1655 4434 : tree saved_body = DECL_SAVED_TREE (fundef->decl);
1656 4434 : tree saved_parms = DECL_ARGUMENTS (fundef->decl);
1657 4434 : tree saved_result = DECL_RESULT (fundef->decl);
1658 4434 : tree saved_fn = current_function_decl;
1659 4434 : DECL_SAVED_TREE (fundef->decl) = fundef->body;
1660 4434 : DECL_ARGUMENTS (fundef->decl) = fundef->parms;
1661 4434 : DECL_RESULT (fundef->decl) = fundef->result;
1662 4434 : current_function_decl = fundef->decl;
1663 4434 : TREE_PURPOSE (copy) = copy_fn (fundef->decl, TREE_VALUE (copy),
1664 4434 : TREE_TYPE (copy));
1665 4434 : current_function_decl = saved_fn;
1666 4434 : DECL_RESULT (fundef->decl) = saved_result;
1667 4434 : DECL_ARGUMENTS (fundef->decl) = saved_parms;
1668 4434 : DECL_SAVED_TREE (fundef->decl) = saved_body;
1669 : }
1670 : else
1671 : {
1672 : /* We have a cached function available. */
1673 79693353 : copy = *slot;
1674 79693353 : *slot = TREE_CHAIN (copy);
1675 : }
1676 :
1677 : return copy;
1678 : }
1679 :
1680 : /* Save the copy COPY of function FUN for later reuse by
1681 : get_fundef_copy(). By construction, there will always be an entry
1682 : to find. */
1683 :
1684 : static void
1685 87356802 : save_fundef_copy (tree fun, tree copy)
1686 : {
1687 87356802 : tree *slot = fundef_copies_table->get (fun);
1688 87356802 : TREE_CHAIN (copy) = *slot;
1689 87356802 : *slot = copy;
1690 87356802 : }
1691 :
1692 : static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree,
1693 : value_cat, bool *, bool *, tree *);
1694 : static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree,
1695 : bool *, tree *);
1696 : static tree find_heap_var_refs (tree *, int *, void *);
1697 :
1698 : /* For exception object EXC if it has class type and usable what () method
1699 : which returns cv char * return the xmalloced string literal which it returns
1700 : if possible, otherwise return NULL. */
1701 :
1702 : static char *
1703 414 : exception_what_str (const constexpr_ctx *ctx, tree exc)
1704 : {
1705 414 : tree type = strip_array_types (TREE_TYPE (exc));
1706 414 : if (!CLASS_TYPE_P (type))
1707 : return NULL;
1708 358 : tree std_exception = lookup_qualified_name (std_node, "exception",
1709 : LOOK_want::NORMAL, false);
1710 358 : if (TREE_CODE (std_exception) != TYPE_DECL)
1711 : return NULL;
1712 352 : if (!CLASS_TYPE_P (TREE_TYPE (std_exception)))
1713 : return NULL;
1714 352 : base_kind b_kind;
1715 352 : tree binfo = lookup_base (type, TREE_TYPE (std_exception), ba_check, &b_kind,
1716 : tf_none);
1717 352 : if (binfo == NULL_TREE || binfo == error_mark_node)
1718 : return NULL;
1719 344 : if (type != TREE_TYPE (exc))
1720 306 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1721 344 : tree call
1722 344 : = finish_class_member_access_expr (exc, get_identifier ("what"), false,
1723 : tf_none);
1724 344 : if (call == error_mark_node)
1725 : return NULL;
1726 344 : releasing_vec what_args;
1727 344 : call = finish_call_expr (call, &what_args, false, false, tf_none);
1728 344 : if (call == error_mark_node)
1729 : return NULL;
1730 344 : if (TREE_CODE (TREE_TYPE (call)) != POINTER_TYPE
1731 344 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1732 344 : || !COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1733 344 : || !tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (call))),
1734 344 : TYPE_SIZE_UNIT (char_type_node))
1735 688 : || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (call))) != BITS_PER_UNIT)
1736 : return NULL;
1737 344 : if (!potential_constant_expression (call))
1738 : return NULL;
1739 344 : bool non_constant_p = false, overflow_p = false;
1740 344 : tree jmp_target = NULL;
1741 344 : tree ptr = cxx_eval_constant_expression (ctx, call, vc_prvalue,
1742 : &non_constant_p, &overflow_p,
1743 : &jmp_target);
1744 688 : if (throws (&jmp_target) || non_constant_p)
1745 : return NULL;
1746 344 : if (reduced_constant_expression_p (ptr))
1747 42 : if (const char *msg = c_getstr (ptr))
1748 42 : return xstrdup (msg);
1749 302 : auto_vec <char, 32> v;
1750 12222 : for (unsigned i = 0; i < INT_MAX; ++i)
1751 : {
1752 12222 : tree t = call;
1753 12222 : if (i)
1754 11920 : t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, size_int (i));
1755 12222 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
1756 12222 : non_constant_p = false;
1757 12222 : overflow_p = false;
1758 12222 : jmp_target = NULL;
1759 12222 : tree t2 = cxx_eval_constant_expression (ctx, t, vc_prvalue,
1760 : &non_constant_p, &overflow_p,
1761 : &jmp_target);
1762 12222 : if (throws (&jmp_target)
1763 12222 : || non_constant_p
1764 12222 : || !tree_fits_shwi_p (t2))
1765 0 : return NULL;
1766 12222 : char c = tree_to_shwi (t2);
1767 12222 : v.safe_push (c);
1768 12222 : if (c == '\0')
1769 : break;
1770 : }
1771 604 : return xstrdup (v.address ());
1772 646 : }
1773 :
1774 : /* Diagnose constant expression evaluation encountering call to
1775 : std::terminate due to exception EXC. */
1776 :
1777 : static void
1778 22 : diagnose_std_terminate (location_t loc, const constexpr_ctx *ctx, tree exc)
1779 : {
1780 22 : tree type = strip_array_types (TREE_TYPE (exc));
1781 22 : if (char *str = exception_what_str (ctx, exc))
1782 : {
1783 4 : error_at (loc, "%qs called after throwing an exception of type %qT; "
1784 : "%<what()%>: %qs", "std::terminate", type, str);
1785 4 : free (str);
1786 : }
1787 : else
1788 : {
1789 18 : if (type != TREE_TYPE (exc))
1790 18 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1791 18 : bool non_constant_p = false, overflow_p = false;
1792 18 : tree jmp_target = NULL;
1793 18 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1794 : &non_constant_p, &overflow_p,
1795 : &jmp_target);
1796 18 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1797 18 : if (reduced_constant_expression_p (val))
1798 18 : error_at (loc, "%qs called after throwing an exception %qE",
1799 : "std::terminate", val);
1800 : else
1801 0 : error_at (loc, "%qs called after throwing an exception of type %qT",
1802 : "std::terminate", type);
1803 : }
1804 22 : }
1805 :
1806 : /* Diagnose constant expression evaluation encountering call to
1807 : uncaught exception EXC. */
1808 :
1809 : static void
1810 392 : diagnose_uncaught_exception (location_t loc, const constexpr_ctx *ctx, tree exc)
1811 : {
1812 392 : tree type = strip_array_types (TREE_TYPE (exc));
1813 392 : if (char *str = exception_what_str (ctx, exc))
1814 : {
1815 340 : error_at (loc, "uncaught exception of type %qT; %<what()%>: %qs", type, str);
1816 340 : free (str);
1817 : }
1818 : else
1819 : {
1820 52 : if (type != TREE_TYPE (exc))
1821 52 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1822 52 : bool non_constant_p = false, overflow_p = false;
1823 52 : tree jmp_target = NULL;
1824 52 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1825 : &non_constant_p, &overflow_p,
1826 : &jmp_target);
1827 52 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1828 52 : if (reduced_constant_expression_p (val))
1829 50 : error_at (loc, "uncaught exception %qE", val);
1830 : else
1831 2 : error_at (loc, "uncaught exception of type %qT", type);
1832 : }
1833 392 : }
1834 :
1835 : /* Kinds of __cxa_* functions (and a few other EH related ones) we handle as
1836 : magic constexpr functions for C++26. */
1837 :
1838 : enum cxa_builtin {
1839 : CXA_NONE = 0,
1840 : CXA_ALLOCATE_EXCEPTION = 1,
1841 : CXA_FREE_EXCEPTION = 2,
1842 : CXA_THROW = 3,
1843 : CXA_BEGIN_CATCH = 4,
1844 : CXA_END_CATCH = 5,
1845 : CXA_RETHROW = 6,
1846 : CXA_GET_EXCEPTION_PTR = 7,
1847 : CXA_BAD_CAST = 8,
1848 : CXA_BAD_TYPEID = 9,
1849 : CXA_THROW_BAD_ARRAY_NEW_LENGTH = 10,
1850 : STD_RETHROW_EXCEPTION = 11,
1851 : BUILTIN_EH_PTR_ADJUST_REF = 12,
1852 : BUILTIN_UNCAUGHT_EXCEPTIONS = 13,
1853 : BUILTIN_CURRENT_EXCEPTION = 14
1854 : };
1855 :
1856 : /* Return cxa_builtin if FNDECL is a __cxa_* function handled as
1857 : magic constexpr function for C++26. Return CXA_NONE otherwise. */
1858 :
1859 : static enum cxa_builtin
1860 37068842 : cxx_cxa_builtin_fn_p (tree fndecl)
1861 : {
1862 37068842 : if (cxx_dialect < cxx26)
1863 : return CXA_NONE;
1864 3696957 : if (DECL_LANGUAGE (fndecl) != lang_c)
1865 : {
1866 3083230 : if (!decl_in_std_namespace_p (fndecl))
1867 : return CXA_NONE;
1868 1301308 : if (id_equal (DECL_NAME (fndecl), "rethrow_exception"))
1869 : return STD_RETHROW_EXCEPTION;
1870 1301266 : return CXA_NONE;
1871 : }
1872 613727 : if (!startswith (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__cxa_"))
1873 : return CXA_NONE;
1874 82052 : if (id_equal (DECL_NAME (fndecl), "__cxa_allocate_exception"))
1875 : return CXA_ALLOCATE_EXCEPTION;
1876 25592 : if (id_equal (DECL_NAME (fndecl), "__cxa_free_exception"))
1877 : return CXA_FREE_EXCEPTION;
1878 25590 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw"))
1879 : return CXA_THROW;
1880 16178 : if (id_equal (DECL_NAME (fndecl), "__cxa_begin_catch"))
1881 : return CXA_BEGIN_CATCH;
1882 4839 : if (id_equal (DECL_NAME (fndecl), "__cxa_end_catch"))
1883 : return CXA_END_CATCH;
1884 1084 : if (id_equal (DECL_NAME (fndecl), "__cxa_rethrow"))
1885 : return CXA_RETHROW;
1886 978 : if (id_equal (DECL_NAME (fndecl), "__cxa_get_exception_ptr"))
1887 : return CXA_GET_EXCEPTION_PTR;
1888 934 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_cast"))
1889 : return CXA_BAD_CAST;
1890 638 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_typeid"))
1891 : return CXA_BAD_TYPEID;
1892 625 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw_bad_array_new_length"))
1893 33 : return CXA_THROW_BAD_ARRAY_NEW_LENGTH;
1894 : return CXA_NONE;
1895 : }
1896 :
1897 : /* Helper function for cxx_eval_cxa_builtin_fn.
1898 : Check if ARG is a valid first argument of __cxa_throw or
1899 : __cxa_free_exception or __builtin_eh_ptr_adjust_ref. Return NULL_TREE if
1900 : not, otherwise return the artificial __cxa_allocate_exception allocated
1901 : VAR_DECL. FREE_EXC is true for __cxa_free_exception, false otherwise. */
1902 :
1903 : static tree
1904 1916 : cxa_check_throw_arg (tree arg, bool free_exc)
1905 : {
1906 1916 : STRIP_NOPS (arg);
1907 1916 : if (TREE_CODE (arg) != ADDR_EXPR)
1908 : return NULL_TREE;
1909 1916 : arg = TREE_OPERAND (arg, 0);
1910 1916 : if (!VAR_P (arg)
1911 1916 : || !DECL_ARTIFICIAL (arg)
1912 1916 : || ((!free_exc || DECL_NAME (arg) != heap_uninit_identifier)
1913 1916 : && DECL_NAME (arg) != heap_identifier)
1914 3832 : || !DECL_LANG_SPECIFIC (arg))
1915 0 : return NULL_TREE;
1916 : return arg;
1917 : }
1918 :
1919 : /* Helper function for cxx_eval_cxa_builtin_fn.
1920 : "Allocate" on the constexpr heap an exception object of TYPE
1921 : with REFCOUNT. */
1922 :
1923 : static tree
1924 18084 : cxa_allocate_exception (location_t loc, const constexpr_ctx *ctx, tree type,
1925 : tree refcount)
1926 : {
1927 18084 : tree var = build_decl (loc, VAR_DECL, heap_uninit_identifier, type);
1928 18084 : DECL_ARTIFICIAL (var) = 1;
1929 18084 : retrofit_lang_decl (var);
1930 18084 : DECL_EXCEPTION_REFCOUNT (var) = refcount;
1931 18084 : ctx->global->heap_vars.safe_push (var);
1932 18084 : return var;
1933 : }
1934 :
1935 : /* Evaluate various __cxa_* calls as magic constexpr builtins for
1936 : C++26 constexpr exception support (P3068R5). */
1937 :
1938 : static tree
1939 30540 : cxx_eval_cxa_builtin_fn (const constexpr_ctx *ctx, tree call,
1940 : enum cxa_builtin kind, tree fndecl,
1941 : bool *non_constant_p, bool *overflow_p,
1942 : tree *jump_target)
1943 : {
1944 30540 : int nargs = call_expr_nargs (call);
1945 30540 : location_t loc = cp_expr_loc_or_input_loc (call);
1946 30540 : tree args[4], arg;
1947 30540 : if (nargs > 4)
1948 : {
1949 0 : invalid_nargs:
1950 0 : if (!ctx->quiet)
1951 0 : error_at (loc, "call to %qD function with incorrect "
1952 : "number of arguments", fndecl);
1953 0 : *non_constant_p = true;
1954 0 : return call;
1955 : }
1956 30540 : if ((kind == CXA_BEGIN_CATCH || kind == CXA_GET_EXCEPTION_PTR)
1957 7585 : && nargs == 1
1958 7585 : && (arg = CALL_EXPR_ARG (call, 0))
1959 7585 : && TREE_CODE (arg) == CALL_EXPR
1960 7585 : && call_expr_nargs (arg) == 1
1961 38125 : && integer_zerop (CALL_EXPR_ARG (arg, 0)))
1962 7585 : if (tree fun = get_function_named_in_call (arg))
1963 7585 : if (fndecl_built_in_p (fun, BUILT_IN_EH_POINTER))
1964 : {
1965 7585 : if (ctx->global->caught_exceptions.length () < 2)
1966 : {
1967 3798 : no_caught_exceptions:
1968 3798 : if (!ctx->quiet)
1969 0 : error_at (loc, "%qD called with no caught exceptions pending",
1970 : fndecl);
1971 3798 : *non_constant_p = true;
1972 3798 : return call;
1973 : }
1974 : /* Both __cxa_get_exception_ptr (__builtin_eh_pointer (0))
1975 : and __cxa_begin_catch (__builtin_eh_pointer (0)) calls expect
1976 : ctx->global->caught_exceptions vector to end with
1977 : __cxa_allocate_exception created artificial VAR_DECL (the
1978 : exception object) followed by handler type, pushed by TRY_BLOCK
1979 : evaluation. The only difference between the functions is that
1980 : __cxa_begin_catch pops the handler type from the vector and keeps
1981 : the VAR_DECL last and decreases uncaught_exceptions. The
1982 : VAR_DECL after __cxa_begin_catch serves as the current exception
1983 : and is then popped in __cxa_end_catch evaluation. */
1984 3787 : tree handler_type = ctx->global->caught_exceptions.last ();
1985 3787 : if (handler_type && (VAR_P (handler_type)
1986 3705 : || TREE_CODE (handler_type) == TREE_LIST))
1987 0 : goto no_caught_exceptions;
1988 3787 : unsigned idx = ctx->global->caught_exceptions.length () - 2;
1989 3787 : arg = ctx->global->caught_exceptions[idx];
1990 3787 : if (TREE_CODE (arg) == TREE_LIST)
1991 0 : arg = TREE_VALUE (arg);
1992 3787 : gcc_assert (VAR_P (arg));
1993 3787 : if (kind == CXA_BEGIN_CATCH)
1994 : {
1995 3759 : ctx->global->caught_exceptions.pop ();
1996 3759 : --ctx->global->uncaught_exceptions;
1997 : }
1998 3787 : if (handler_type == NULL_TREE)
1999 : /* Used for catch (...). Just return void. */
2000 82 : return void_node;
2001 3705 : else if (POINTER_TYPE_P (handler_type))
2002 : {
2003 : /* Used for catch of a pointer. */
2004 66 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
2005 66 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
2006 : size_zero_node, NULL_TREE, NULL_TREE);
2007 66 : arg = cp_convert (handler_type, arg,
2008 66 : ctx->quiet ? tf_none : tf_warning_or_error);
2009 66 : if (arg == error_mark_node)
2010 : {
2011 0 : *non_constant_p = true;
2012 0 : return call;
2013 : }
2014 : }
2015 : else
2016 : {
2017 : /* Used for catch of a non-pointer type. */
2018 3639 : tree exc_type = strip_array_types (TREE_TYPE (arg));
2019 3619 : if (TYPE_PTRMEM_P (handler_type)
2020 3685 : && !same_type_ignoring_top_level_qualifiers_p
2021 46 : (handler_type, exc_type))
2022 : {
2023 46 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
2024 46 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
2025 : size_zero_node, NULL_TREE, NULL_TREE);
2026 46 : arg = cp_convert (handler_type, arg,
2027 46 : ctx->quiet ? tf_none
2028 : : tf_warning_or_error);
2029 46 : if (arg == error_mark_node)
2030 : {
2031 0 : *non_constant_p = true;
2032 0 : return call;
2033 : }
2034 46 : tree var = build_decl (loc, VAR_DECL, heap_identifier,
2035 46 : handler_type);
2036 46 : DECL_ARTIFICIAL (var) = 1;
2037 46 : ctx->global->heap_vars.safe_push (var);
2038 46 : ctx->global->put_value (var, NULL_TREE);
2039 46 : tree init = build2_loc (loc, INIT_EXPR, handler_type,
2040 : var, arg);
2041 46 : arg = ctx->global->caught_exceptions[idx];
2042 46 : if (TREE_CODE (arg) == TREE_LIST)
2043 : {
2044 0 : DECL_CHAIN (var) = TREE_PURPOSE (arg);
2045 0 : TREE_PURPOSE (arg) = var;
2046 : }
2047 : else
2048 46 : ctx->global->caught_exceptions[idx]
2049 92 : = build_tree_list (var, arg);
2050 46 : arg = cp_build_addr_expr (var, tf_none);
2051 46 : arg = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (arg),
2052 : init, arg);
2053 : }
2054 : else
2055 : {
2056 3593 : tree exc_ptr_type = build_pointer_type (exc_type);
2057 3593 : arg = build_fold_addr_expr_with_type (arg, exc_ptr_type);
2058 3593 : if (CLASS_TYPE_P (handler_type))
2059 : {
2060 3503 : tree ptr_type = build_pointer_type (handler_type);
2061 3503 : arg = cp_convert (ptr_type, arg,
2062 3503 : ctx->quiet ? tf_none
2063 : : tf_warning_or_error);
2064 3503 : if (arg == error_mark_node)
2065 : {
2066 0 : *non_constant_p = true;
2067 0 : return call;
2068 : }
2069 : }
2070 : }
2071 : }
2072 3705 : return cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2073 : non_constant_p, overflow_p,
2074 3705 : jump_target);
2075 : }
2076 43208 : for (int i = 0; i < nargs; ++i)
2077 : {
2078 20253 : args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (call, i),
2079 : vc_prvalue, non_constant_p,
2080 : overflow_p, jump_target);
2081 20253 : if (*non_constant_p)
2082 : return call;
2083 20253 : if (*jump_target)
2084 : return NULL_TREE;
2085 : }
2086 22955 : switch (kind)
2087 : {
2088 14715 : case CXA_ALLOCATE_EXCEPTION:
2089 14715 : if (nargs != 1)
2090 0 : goto invalid_nargs;
2091 14715 : if (!tree_fits_uhwi_p (args[0]))
2092 : {
2093 0 : if (!ctx->quiet)
2094 0 : error_at (loc, "cannot allocate exception: size not constant");
2095 0 : *non_constant_p = true;
2096 0 : return call;
2097 : }
2098 : else
2099 : {
2100 29430 : tree type = build_array_type_nelts (char_type_node,
2101 14715 : tree_to_uhwi (args[0]));
2102 14715 : tree var = cxa_allocate_exception (loc, ctx, type, size_zero_node);
2103 14715 : ctx->global->put_value (var, NULL_TREE);
2104 14715 : return fold_convert (ptr_type_node, build_address (var));
2105 : }
2106 2 : case CXA_FREE_EXCEPTION:
2107 2 : if (nargs != 1)
2108 0 : goto invalid_nargs;
2109 2 : arg = cxa_check_throw_arg (args[0], true);
2110 2 : if (arg == NULL_TREE)
2111 : {
2112 0 : invalid_ptr:
2113 0 : if (!ctx->quiet)
2114 0 : error_at (loc, "first argument to %qD function not result of "
2115 : "%<__cxa_allocate_exception%>", fndecl);
2116 0 : *non_constant_p = true;
2117 0 : return call;
2118 : }
2119 2 : DECL_NAME (arg) = heap_deleted_identifier;
2120 2 : ctx->global->destroy_value (arg);
2121 2 : ctx->global->heap_dealloc_count++;
2122 2 : return void_node;
2123 1748 : case CXA_THROW:
2124 1748 : if (nargs != 3)
2125 0 : goto invalid_nargs;
2126 1748 : arg = cxa_check_throw_arg (args[0], false);
2127 1748 : if (arg == NULL_TREE)
2128 0 : goto invalid_ptr;
2129 1748 : DECL_EXCEPTION_REFCOUNT (arg)
2130 1748 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2131 : size_one_node);
2132 1748 : ++ctx->global->uncaught_exceptions;
2133 1748 : *jump_target = arg;
2134 1748 : return void_node;
2135 0 : case CXA_BEGIN_CATCH:
2136 0 : case CXA_GET_EXCEPTION_PTR:
2137 0 : goto invalid_nargs;
2138 3755 : case CXA_END_CATCH:
2139 3755 : if (nargs != 0)
2140 0 : goto invalid_nargs;
2141 3755 : if (ctx->global->caught_exceptions.is_empty ())
2142 : {
2143 0 : no_active_exc:
2144 0 : if (!ctx->quiet)
2145 0 : error_at (loc, "%qD called with no caught exceptions active",
2146 : fndecl);
2147 0 : *non_constant_p = true;
2148 0 : return call;
2149 : }
2150 : else
2151 : {
2152 3755 : arg = ctx->global->caught_exceptions.pop ();
2153 3755 : if (arg == NULL_TREE
2154 3755 : || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2155 0 : goto no_active_exc;
2156 3755 : if (TREE_CODE (arg) == TREE_LIST)
2157 : {
2158 92 : for (tree aux = TREE_PURPOSE (arg); aux; aux = DECL_CHAIN (aux))
2159 : {
2160 46 : DECL_NAME (aux) = heap_deleted_identifier;
2161 46 : ctx->global->destroy_value (aux);
2162 46 : ctx->global->heap_dealloc_count++;
2163 : }
2164 46 : arg = TREE_VALUE (arg);
2165 : }
2166 3755 : DECL_CHAIN (arg) = NULL_TREE;
2167 3833 : free_except:
2168 3833 : DECL_EXCEPTION_REFCOUNT (arg)
2169 3833 : = size_binop (MINUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2170 : size_one_node);
2171 3833 : if (integer_zerop (DECL_EXCEPTION_REFCOUNT (arg)))
2172 : {
2173 3623 : if (type_build_dtor_call (TREE_TYPE (arg)))
2174 : {
2175 : /* So that we don't complain about out-of-consteval use. */
2176 3405 : temp_override<tree> ovr (current_function_decl);
2177 3405 : if (ctx->call && ctx->call->fundef)
2178 3405 : current_function_decl = ctx->call->fundef->decl;
2179 3405 : tree cleanup
2180 3427 : = cxx_maybe_build_cleanup (arg, (ctx->quiet ? tf_none
2181 : : tf_warning_or_error));
2182 3405 : if (cleanup == error_mark_node)
2183 0 : *non_constant_p = true;
2184 3405 : tree jmp_target = NULL_TREE;
2185 3405 : cxx_eval_constant_expression (ctx, cleanup, vc_discard,
2186 : non_constant_p, overflow_p,
2187 : &jmp_target);
2188 3405 : if (throws (&jmp_target))
2189 0 : *jump_target = jmp_target;
2190 3405 : }
2191 3623 : DECL_NAME (arg) = heap_deleted_identifier;
2192 3623 : ctx->global->destroy_value (arg);
2193 3623 : ctx->global->heap_dealloc_count++;
2194 : }
2195 : }
2196 3833 : return void_node;
2197 98 : case CXA_RETHROW:
2198 98 : if (nargs != 0)
2199 0 : goto invalid_nargs;
2200 98 : unsigned idx;
2201 196 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2202 82 : if (arg == NULL_TREE || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2203 0 : --idx;
2204 : else
2205 : break;
2206 98 : if (arg == NULL_TREE)
2207 : {
2208 16 : if (!ctx->quiet)
2209 4 : error_at (loc, "%qD called with no caught exceptions active",
2210 : fndecl);
2211 16 : *non_constant_p = true;
2212 16 : return call;
2213 : }
2214 82 : if (TREE_CODE (arg) == TREE_LIST)
2215 0 : arg = TREE_VALUE (arg);
2216 82 : DECL_EXCEPTION_REFCOUNT (arg)
2217 82 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2218 82 : ++ctx->global->uncaught_exceptions;
2219 : /* Don't cache calls which rethrow, they depend on the current
2220 : exception which might be caught in the caller. */
2221 82 : ctx->global->state_dependent = true;
2222 82 : *jump_target = arg;
2223 82 : return void_node;
2224 163 : case CXA_BAD_CAST:
2225 163 : case CXA_BAD_TYPEID:
2226 163 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2227 163 : if (nargs != 0)
2228 0 : goto invalid_nargs;
2229 : else
2230 : {
2231 163 : tree name;
2232 163 : switch (kind)
2233 : {
2234 123 : case CXA_BAD_CAST:
2235 123 : name = get_identifier ("bad_cast");
2236 123 : break;
2237 7 : case CXA_BAD_TYPEID:
2238 7 : name = get_identifier ("bad_typeid");
2239 7 : break;
2240 33 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2241 33 : name = get_identifier ("bad_array_new_length");
2242 33 : break;
2243 : default:
2244 : gcc_unreachable ();
2245 : }
2246 163 : tree decl = lookup_qualified_name (std_node, name);
2247 163 : if (TREE_CODE (decl) != TYPE_DECL
2248 135 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2249 298 : || !type_build_ctor_call (TREE_TYPE (decl)))
2250 : {
2251 28 : if (!ctx->quiet)
2252 8 : error_at (loc, "%qD called without %<std::%D%> being defined",
2253 : fndecl, name);
2254 28 : *non_constant_p = true;
2255 28 : return call;
2256 : }
2257 135 : tree type = TREE_TYPE (decl);
2258 135 : tree var = cxa_allocate_exception (loc, ctx, type, size_one_node);
2259 135 : tree ctor
2260 135 : = build_special_member_call (var, complete_ctor_identifier,
2261 : NULL, type, LOOKUP_NORMAL,
2262 135 : ctx->quiet ? tf_none
2263 : : tf_warning_or_error);
2264 135 : if (ctor == error_mark_node)
2265 : {
2266 0 : *non_constant_p = true;
2267 0 : return call;
2268 : }
2269 135 : if (TREE_CONSTANT (ctor))
2270 0 : ctx->global->put_value (var, ctor);
2271 : else
2272 : {
2273 135 : ctx->global->put_value (var, NULL_TREE);
2274 135 : cxx_eval_constant_expression (ctx, ctor, vc_discard,
2275 : non_constant_p, overflow_p,
2276 : jump_target);
2277 135 : if (*non_constant_p)
2278 : return call;
2279 135 : if (throws (jump_target))
2280 : return NULL_TREE;
2281 : }
2282 135 : ++ctx->global->uncaught_exceptions;
2283 135 : *jump_target = var;
2284 : }
2285 135 : return void_node;
2286 82 : case BUILTIN_UNCAUGHT_EXCEPTIONS:
2287 82 : if (nargs != 0)
2288 0 : goto invalid_nargs;
2289 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2290 : want to give a definite answer during mce_unknown evaluation,
2291 : because that might prevent evaluation later on when some
2292 : exceptions might be uncaught. But unlike that, we don't
2293 : want to constant fold it even during cp_fold, because at runtime
2294 : std::uncaught_exceptions () might still be non-zero. */
2295 82 : if (ctx->manifestly_const_eval != mce_true)
2296 : {
2297 46 : *non_constant_p = true;
2298 46 : return call;
2299 : }
2300 : /* Don't cache calls which call __builtin_uncaught_exceptions (),
2301 : they depend on the current uncaught exceptions which might
2302 : be the state from their caller. */
2303 36 : ctx->global->state_dependent = true;
2304 36 : return build_int_cst (integer_type_node,
2305 36 : ctx->global->uncaught_exceptions);
2306 2226 : case BUILTIN_CURRENT_EXCEPTION:
2307 2226 : if (nargs != 0)
2308 0 : goto invalid_nargs;
2309 : else
2310 : {
2311 2226 : tree name = get_identifier ("exception_ptr");
2312 2226 : tree decl = lookup_qualified_name (std_node, name);
2313 2226 : tree fld;
2314 2226 : if (TREE_CODE (decl) != TYPE_DECL
2315 2226 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2316 2226 : || !COMPLETE_TYPE_P (TREE_TYPE (decl))
2317 2226 : || !(fld = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (decl))))
2318 2226 : || DECL_ARTIFICIAL (fld)
2319 2226 : || TREE_CODE (TREE_TYPE (fld)) != POINTER_TYPE
2320 2226 : || next_aggregate_field (DECL_CHAIN (fld))
2321 4452 : || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (decl)),
2322 2226 : TYPE_SIZE (TREE_TYPE (fld))))
2323 : {
2324 0 : if (!ctx->quiet)
2325 0 : error_at (loc, "%qD called without supportable %qs",
2326 : fndecl, "std::exception_ptr");
2327 0 : *non_constant_p = true;
2328 0 : return call;
2329 : }
2330 4452 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2331 42 : if (arg == NULL_TREE
2332 42 : || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2333 0 : --idx;
2334 : else
2335 : break;
2336 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2337 : want to give a definite answer during mce_unknown evaluation,
2338 : because that might prevent evaluation later on when some
2339 : exceptions might be current. But unlike that, we don't
2340 : want to constant fold it to null even during cp_fold, because
2341 : at runtime std::current_exception () might still be non-null. */
2342 2226 : if (ctx->manifestly_const_eval != mce_true && arg == NULL_TREE)
2343 : {
2344 2172 : *non_constant_p = true;
2345 2172 : return call;
2346 : }
2347 54 : if (arg == NULL_TREE)
2348 12 : arg = build_zero_cst (TREE_TYPE (fld));
2349 : else
2350 : {
2351 42 : if (TREE_CODE (arg) == TREE_LIST)
2352 0 : arg = TREE_VALUE (arg);
2353 42 : DECL_EXCEPTION_REFCOUNT (arg)
2354 42 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2355 : size_one_node);
2356 42 : arg = fold_convert (ptr_type_node, build_address (arg));
2357 : }
2358 : /* Don't cache calls which call __builtin_current_exception (),
2359 : they depend on the current exception which might be caught
2360 : in the caller. */
2361 54 : ctx->global->state_dependent = true;
2362 54 : return build_constructor_single (TREE_TYPE (decl), fld, arg);
2363 : }
2364 40 : case STD_RETHROW_EXCEPTION:
2365 40 : if (nargs != 1)
2366 0 : goto invalid_nargs;
2367 40 : if (TYPE_REF_P (TREE_TYPE (args[0])))
2368 : {
2369 40 : arg = args[0];
2370 40 : STRIP_NOPS (arg);
2371 40 : if (TREE_CODE (arg) == ADDR_EXPR)
2372 : {
2373 40 : args[0]
2374 40 : = cxx_eval_constant_expression (ctx, TREE_OPERAND (arg, 0),
2375 : vc_prvalue, non_constant_p,
2376 : overflow_p, jump_target);
2377 40 : if (*non_constant_p)
2378 : return call;
2379 40 : if (*jump_target)
2380 : return NULL_TREE;
2381 : }
2382 : }
2383 40 : if (TREE_CODE (args[0]) != CONSTRUCTOR
2384 40 : || CONSTRUCTOR_NELTS (args[0]) != 1)
2385 : {
2386 0 : invalid_std_rethrow:
2387 0 : if (!ctx->quiet)
2388 0 : error_at (loc, "%qD called with unexpected %qs argument",
2389 : fndecl, "std::exception_ptr");
2390 0 : *non_constant_p = true;
2391 0 : return void_node;
2392 : }
2393 40 : arg = cxa_check_throw_arg (CONSTRUCTOR_ELT (args[0], 0)->value, false);
2394 40 : if (arg == NULL_TREE)
2395 0 : goto invalid_std_rethrow;
2396 40 : DECL_EXCEPTION_REFCOUNT (arg)
2397 40 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2398 40 : ++ctx->global->uncaught_exceptions;
2399 40 : *jump_target = arg;
2400 40 : return void_node;
2401 126 : case BUILTIN_EH_PTR_ADJUST_REF:
2402 126 : if (nargs != 2)
2403 0 : goto invalid_nargs;
2404 126 : arg = cxa_check_throw_arg (args[0], false);
2405 126 : if (arg == NULL_TREE)
2406 0 : goto invalid_ptr;
2407 126 : if (integer_onep (args[1]))
2408 48 : DECL_EXCEPTION_REFCOUNT (arg)
2409 96 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2410 : size_one_node);
2411 78 : else if (integer_minus_onep (args[1]))
2412 78 : goto free_except;
2413 : else
2414 : {
2415 0 : if (!ctx->quiet)
2416 0 : error_at (loc, "%qD called with second argument "
2417 : "other than 1 or -1", fndecl);
2418 0 : *non_constant_p = true;
2419 : }
2420 48 : return void_node;
2421 0 : default:
2422 0 : gcc_unreachable ();
2423 : }
2424 : }
2425 :
2426 : /* Variables and functions to manage constexpr call expansion context.
2427 : These do not need to be marked for PCH or GC. */
2428 :
2429 : /* FIXME remember and print actual constant arguments. */
2430 : static vec<tree> call_stack;
2431 : static int call_stack_tick;
2432 : static int last_cx_error_tick;
2433 :
2434 : /* Attempt to evaluate T which represents a call to __builtin_constexpr_diag.
2435 : The arguments should be an integer (0 for inform, 1 for warning, 2 for
2436 : error) optionally with 16 ored in if it should use caller's caller location
2437 : instead of caller's location and 2 messages which are either a pointer to
2438 : a STRING_CST or class with data () and size () member functions like
2439 : string_view or u8string_view. The first message is a tag, with "" passed
2440 : for no tag, data () should return const char *, the tag should only contain
2441 : alphanumeric letters or underscores. The second message is the diagnostic
2442 : message, data () can be either const char * or const char8_t *. size ()
2443 : should return the corresponding length of the strings in bytes as an
2444 : integer. */
2445 :
2446 : static tree
2447 210 : cxx_eval_constexpr_diag (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
2448 : bool *overflow_p, tree *jump_target)
2449 : {
2450 210 : location_t loc = EXPR_LOCATION (t);
2451 210 : if (call_expr_nargs (t) != 3)
2452 : {
2453 12 : if (!ctx->quiet)
2454 12 : error_at (loc, "wrong number of arguments to %qs call",
2455 : "__builtin_constexpr_diag");
2456 12 : *non_constant_p = true;
2457 12 : return t;
2458 : }
2459 : tree args[3];
2460 792 : for (int i = 0; i < 3; ++i)
2461 : {
2462 594 : tree arg = convert_from_reference (CALL_EXPR_ARG (t, i));
2463 594 : arg = cxx_eval_constant_expression (ctx, arg,
2464 : (i == 0
2465 534 : || POINTER_TYPE_P (TREE_TYPE (arg)))
2466 990 : ? vc_prvalue : vc_glvalue,
2467 : non_constant_p, overflow_p,
2468 : jump_target);
2469 594 : if (*jump_target)
2470 : return NULL_TREE;
2471 594 : if (*non_constant_p)
2472 : return t;
2473 594 : args[i] = arg;
2474 : }
2475 396 : if (TREE_CODE (args[0]) != INTEGER_CST
2476 198 : || wi::to_widest (args[0]) < 0
2477 194 : || wi::to_widest (args[0]) > 18
2478 396 : || (wi::to_widest (args[0]) & 15) > 2)
2479 : {
2480 8 : if (!ctx->quiet)
2481 8 : error_at (loc, "first %qs call argument should be 0, 1, 2, 16, 17 or "
2482 : "18", "__builtin_constexpr_diag");
2483 8 : *non_constant_p = true;
2484 8 : return t;
2485 : }
2486 190 : const char *msgs[2] = {};
2487 190 : int lens[3] = {};
2488 950 : cexpr_str cstrs[2];
2489 478 : diagnostics::kind kind = diagnostics::kind::error;
2490 478 : for (int i = 1; i < 3; ++i)
2491 : {
2492 344 : tree arg = args[i];
2493 344 : if (POINTER_TYPE_P (TREE_TYPE (arg)))
2494 : {
2495 206 : tree str = arg;
2496 206 : STRIP_NOPS (str);
2497 206 : if (TREE_CODE (str) == ADDR_EXPR
2498 206 : && TREE_CODE (TREE_OPERAND (str, 0)) == STRING_CST)
2499 : {
2500 206 : str = TREE_OPERAND (str, 0);
2501 206 : tree eltype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)));
2502 206 : if (eltype == char_type_node
2503 24 : || (i == 2 && eltype == char8_type_node))
2504 344 : arg = str;
2505 : }
2506 : }
2507 344 : cstrs[i - 1].message = arg;
2508 344 : if (!cstrs[i - 1].type_check (loc, i == 2))
2509 : {
2510 40 : *non_constant_p = true;
2511 40 : return t;
2512 : }
2513 304 : if (!cstrs[i - 1].extract (loc, msgs[i - 1], lens[i - 1], ctx,
2514 : non_constant_p, overflow_p, jump_target))
2515 : {
2516 16 : if (*jump_target)
2517 : return NULL_TREE;
2518 16 : *non_constant_p = true;
2519 16 : return t;
2520 : }
2521 : }
2522 134 : if (msgs[0])
2523 : {
2524 726 : for (int i = 0; i < lens[0]; ++i)
2525 596 : if (!ISALNUM (msgs[0][i]) && msgs[0][i] != '_')
2526 : {
2527 4 : if (!ctx->quiet)
2528 4 : error_at (loc, "%qs tag string contains %qc character other than"
2529 : " letters, digits or %<_%>",
2530 : "__builtin_constexpr_diag", msgs[0][i]);
2531 4 : *non_constant_p = true;
2532 4 : return t;
2533 : }
2534 : }
2535 130 : if (ctx->manifestly_const_eval == mce_unknown)
2536 : {
2537 0 : *non_constant_p = true;
2538 0 : return t;
2539 : }
2540 130 : int arg0 = tree_to_uhwi (args[0]);
2541 130 : if (arg0 & 16)
2542 : {
2543 32 : arg0 &= 15;
2544 32 : if (!call_stack.is_empty ())
2545 : {
2546 32 : tree call = call_stack.last ();
2547 32 : if (EXPR_HAS_LOCATION (call))
2548 32 : loc = EXPR_LOCATION (call);
2549 : }
2550 : }
2551 130 : if (arg0 == 0)
2552 : kind = diagnostics::kind::note;
2553 82 : else if (arg0 == 1)
2554 36 : kind = diagnostics::kind::warning;
2555 130 : if (lens[0])
2556 : {
2557 88 : const char *color = "error";
2558 88 : if (kind == diagnostics::kind::note)
2559 : color = "note";
2560 60 : else if (kind == diagnostics::kind::warning)
2561 32 : color = "warning";
2562 88 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s [%r%.*s%R]",
2563 : lens[1], msgs[1], color, lens[0], msgs[0]);
2564 : }
2565 : else
2566 42 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s",
2567 : lens[1], msgs[1]);
2568 130 : return void_node;
2569 570 : }
2570 :
2571 : static tree eval_and_check_array_index (const constexpr_ctx *, tree, bool,
2572 : bool *, bool *, tree *);
2573 :
2574 : /* Helper function for cxx_eval_is_within_lifetime and
2575 : cxx_eval_start_lifetime. Check if ARG is within lifetime. */
2576 :
2577 : static tree
2578 5078 : is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun,
2579 : tree arg, bool *non_constant_p, bool *overflow_p,
2580 : tree *jump_target)
2581 : {
2582 5078 : auto_vec <tree, 4> refs;
2583 5078 : tree obj;
2584 12113 : for (obj = arg; ; obj = TREE_OPERAND (obj, 0))
2585 : {
2586 12113 : switch (TREE_CODE (obj))
2587 : {
2588 7035 : case COMPONENT_REF:
2589 7035 : case ARRAY_REF:
2590 7035 : case REALPART_EXPR:
2591 7035 : case IMAGPART_EXPR:
2592 7035 : refs.safe_push (obj);
2593 7035 : continue;
2594 5078 : default:
2595 5078 : break;
2596 : }
2597 5078 : break;
2598 : }
2599 5078 : tree *valp = nullptr;
2600 5078 : bool check_mutable = false;
2601 5078 : if (DECL_P (obj))
2602 : {
2603 5036 : valp = ctx->global->get_raw_value_ptr (obj);
2604 5036 : if (!valp
2605 1162 : && VAR_P (obj)
2606 1162 : && TREE_STATIC (obj)
2607 5458 : && decl_constant_var_p (obj))
2608 : {
2609 410 : valp = &DECL_INITIAL (obj);
2610 410 : check_mutable = true;
2611 : }
2612 : }
2613 5036 : if (!valp || *valp == void_list_node)
2614 : {
2615 980 : if (!ctx->quiet)
2616 : {
2617 57 : auto_diagnostic_group d;
2618 57 : if (DECL_P (obj) && DECL_NAME (obj) == heap_deleted_identifier)
2619 : {
2620 3 : error_at (loc, "%qE on allocated storage after deallocation "
2621 3 : "is not a constant expression", DECL_NAME (fun));
2622 3 : inform (DECL_SOURCE_LOCATION (obj), "allocated here");
2623 : }
2624 54 : else if (DECL_P (obj) && ctx->global->is_outside_lifetime (obj))
2625 : {
2626 45 : error_at (loc, "%qE on %qE after its storage has been released "
2627 45 : "is not a constant expression", DECL_NAME (fun), obj);
2628 45 : inform (DECL_SOURCE_LOCATION (obj), "declared here");
2629 : }
2630 : else
2631 9 : error_at (loc, "%qE on %qE from outside current evaluation "
2632 9 : "is not a constant expression", DECL_NAME (fun), obj);
2633 57 : }
2634 980 : *non_constant_p = true;
2635 980 : return t;
2636 : }
2637 4098 : tree val = *valp;
2638 4098 : if (val == void_node)
2639 15 : return boolean_false_node;
2640 4083 : unsigned i;
2641 4083 : tree ref;
2642 : /* Magic value used for val when inside the following loop when
2643 : inside of an omitted part of initializer due to it being
2644 : uninitialized. In this case return boolean_true_node unless
2645 : there is some union member access, in unitialized union
2646 : no member is within lifetime. */
2647 4083 : const tree val_uninit = global_namespace;
2648 : /* Magic value used for val when inside the following loop when
2649 : inside of an omitted part of initializer due to it being
2650 : zero initialized. In this case return boolean_true_node unless
2651 : there is some union member access except for the first member. */
2652 4083 : const tree val_zero_init = std_node;
2653 4083 : if (val == NULL_TREE)
2654 141 : val = val_uninit;
2655 12571 : FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
2656 5193 : switch (TREE_CODE (ref))
2657 : {
2658 18 : case REALPART_EXPR:
2659 18 : case IMAGPART_EXPR:
2660 18 : if (TREE_CODE (val) == COMPLEX_EXPR
2661 18 : && (TREE_OPERAND (val, TREE_CODE (ref) == IMAGPART_EXPR)
2662 12 : == void_node))
2663 6 : return boolean_false_node;
2664 12 : return boolean_true_node;
2665 4151 : case COMPONENT_REF:
2666 4151 : if (check_mutable && DECL_MUTABLE_P (TREE_OPERAND (ref, 1)))
2667 : {
2668 12 : if (!ctx->quiet)
2669 3 : error_at (loc, "%qE on %<mutable%> sub-object %qD",
2670 3 : DECL_NAME (fun), TREE_OPERAND (ref, 1));
2671 12 : *non_constant_p = true;
2672 12 : return t;
2673 : }
2674 4139 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
2675 : {
2676 1280 : tree union_type = TREE_TYPE (TREE_OPERAND (ref, 0));
2677 1280 : if (val == val_zero_init)
2678 : {
2679 48 : if (TREE_OPERAND (ref, 1)
2680 24 : != next_aggregate_field (TYPE_FIELDS (union_type)))
2681 15 : return boolean_false_node;
2682 9 : continue;
2683 : }
2684 1256 : else if (val == val_uninit)
2685 102 : return boolean_false_node;
2686 1154 : else if (val == error_mark_node)
2687 : return val;
2688 : else
2689 : {
2690 1154 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2691 1154 : if (CONSTRUCTOR_NELTS (val) == 0)
2692 : {
2693 147 : if (CONSTRUCTOR_NO_CLEARING (val))
2694 135 : return boolean_false_node;
2695 12 : tree first
2696 12 : = next_aggregate_field (TYPE_FIELDS (union_type));
2697 12 : if (first != TREE_OPERAND (ref, 1))
2698 3 : return boolean_false_node;
2699 9 : val = val_zero_init;
2700 9 : continue;
2701 9 : }
2702 : else
2703 : {
2704 1007 : if (CONSTRUCTOR_ELT (val, 0)->index
2705 1007 : != TREE_OPERAND (ref, 1))
2706 287 : return boolean_false_node;
2707 720 : val = CONSTRUCTOR_ELT (val, 0)->value;
2708 720 : if (val == void_node)
2709 0 : return boolean_false_node;
2710 720 : continue;
2711 : }
2712 : }
2713 : }
2714 2859 : if (val == val_zero_init || val == val_uninit)
2715 80 : continue;
2716 2779 : if (val == error_mark_node)
2717 : return val;
2718 2767 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2719 : unsigned int j;
2720 : tree field, value;
2721 4202 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (val), j, field, value)
2722 2628 : if (field == TREE_OPERAND (ref, 1))
2723 : {
2724 1193 : if (value == void_node)
2725 6 : return boolean_false_node;
2726 : val = value;
2727 : ref = NULL_TREE;
2728 : break;
2729 : }
2730 2761 : if (ref == NULL_TREE)
2731 1187 : continue;
2732 1574 : if (CONSTRUCTOR_NO_CLEARING (val))
2733 : {
2734 1457 : if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
2735 75 : return boolean_false_node;
2736 : val = val_uninit;
2737 : }
2738 : else
2739 : val = val_zero_init;
2740 1499 : continue;
2741 1024 : case ARRAY_REF:
2742 1024 : field = eval_and_check_array_index (ctx, ref, false,
2743 : non_constant_p, overflow_p,
2744 : jump_target);
2745 1024 : if (*jump_target)
2746 : return NULL_TREE;
2747 1024 : if (*non_constant_p)
2748 : return t;
2749 1012 : if (val == val_zero_init || val == val_uninit)
2750 33 : continue;
2751 979 : if (val == error_mark_node)
2752 : return val;
2753 979 : if (TREE_CODE (val) == STRING_CST)
2754 0 : return boolean_true_node;
2755 979 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2756 979 : HOST_WIDE_INT idx;
2757 979 : idx = find_array_ctor_elt (val, field, false);
2758 979 : if (idx != -1)
2759 : {
2760 595 : val = CONSTRUCTOR_ELT (val, idx)->value;
2761 595 : if (val == void_node)
2762 72 : return boolean_false_node;
2763 523 : continue;
2764 : }
2765 384 : if (CONSTRUCTOR_NO_CLEARING (val))
2766 : {
2767 159 : if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
2768 39 : return boolean_false_node;
2769 : val = val_uninit;
2770 : }
2771 : else
2772 : val = val_zero_init;
2773 345 : continue;
2774 0 : default:
2775 0 : gcc_unreachable ();
2776 1844 : }
2777 3295 : return boolean_true_node;
2778 5078 : }
2779 :
2780 : /* Attempt to evaluate T which represents a call to
2781 : __builtin_is_within_lifetime. */
2782 :
2783 : static tree
2784 3952 : cxx_eval_is_within_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
2785 : bool *non_constant_p, bool *overflow_p,
2786 : tree *jump_target)
2787 : {
2788 3952 : location_t loc = EXPR_LOCATION (t);
2789 3952 : tree arg = CALL_EXPR_ARG (t, 0);
2790 3952 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2791 : non_constant_p, overflow_p,
2792 : jump_target);
2793 3952 : if (*jump_target)
2794 : return NULL_TREE;
2795 3952 : if (*non_constant_p)
2796 : return t;
2797 : /* Need to strip casts to pointers to void, but should preserve
2798 : pointer casts within the innermost pointer to void cast if
2799 : any, so that e.g. pointers to heap allocations are handled
2800 : correctly. */
2801 : tree p = arg;
2802 6290 : while (CONVERT_EXPR_P (p) || TREE_CODE (p) == NON_LVALUE_EXPR)
2803 : {
2804 2754 : if (!TYPE_PTR_P (TREE_TYPE (p)))
2805 : break;
2806 2754 : if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (p))))
2807 174 : arg = TREE_OPERAND (p, 0);
2808 2754 : p = TREE_OPERAND (p, 0);
2809 : }
2810 3536 : if (integer_zerop (arg))
2811 : {
2812 24 : if (!ctx->quiet)
2813 6 : error_at (loc, "%qE called with a null pointer",
2814 6 : DECL_NAME (fun));
2815 24 : *non_constant_p = true;
2816 24 : return t;
2817 : }
2818 3512 : if (POINTER_TYPE_P (TREE_TYPE (arg))
2819 3512 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == FUNCTION_TYPE
2820 3491 : || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == METHOD_TYPE))
2821 : {
2822 21 : if (!ctx->quiet)
2823 6 : error_at (loc, "%qE called with pointer to function",
2824 6 : DECL_NAME (fun));
2825 21 : *non_constant_p = true;
2826 21 : return t;
2827 : }
2828 3491 : arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
2829 3491 : arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
2830 : non_constant_p, overflow_p,
2831 : jump_target);
2832 3491 : if (*jump_target)
2833 : return NULL_TREE;
2834 3491 : if (*non_constant_p)
2835 : return t;
2836 3491 : return is_within_lifetime (loc, ctx, t, fun, arg,
2837 3491 : non_constant_p, overflow_p, jump_target);
2838 : }
2839 :
2840 : static tree cxx_eval_store_expression (const constexpr_ctx *, tree,
2841 : value_cat, bool *, bool *,
2842 : tree *);
2843 :
2844 : /* Attempt to evaluate T which represents a call to
2845 : __builtin_start_lifetime. */
2846 :
2847 : static tree
2848 1593 : cxx_eval_start_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
2849 : bool *non_constant_p, bool *overflow_p,
2850 : tree *jump_target)
2851 : {
2852 1593 : location_t loc = EXPR_LOCATION (t);
2853 1593 : tree arg = CALL_EXPR_ARG (t, 0), within_lifetime;
2854 1593 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2855 : non_constant_p, overflow_p,
2856 : jump_target);
2857 1593 : if (*jump_target)
2858 : return NULL_TREE;
2859 1593 : if (*non_constant_p)
2860 : return t;
2861 1593 : arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
2862 1593 : arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
2863 : non_constant_p, overflow_p,
2864 : jump_target);
2865 1593 : if (*jump_target)
2866 : return NULL_TREE;
2867 1593 : if (*non_constant_p)
2868 : return t;
2869 1593 : switch (TREE_CODE (arg))
2870 : {
2871 1587 : case COMPONENT_REF:
2872 1587 : case ARRAY_REF:
2873 1587 : case REALPART_EXPR:
2874 1587 : case IMAGPART_EXPR:
2875 1587 : within_lifetime
2876 1587 : = is_within_lifetime (loc, ctx, t, fun, TREE_OPERAND (arg, 0),
2877 : non_constant_p, overflow_p, jump_target);
2878 1587 : if (*jump_target)
2879 : return NULL_TREE;
2880 1587 : if (*non_constant_p)
2881 : return t;
2882 1587 : if (within_lifetime != boolean_true_node)
2883 : {
2884 90 : if (!ctx->quiet)
2885 30 : error_at (loc, "%qE with containing object not within lifetime",
2886 30 : DECL_NAME (fun));
2887 90 : *non_constant_p = true;
2888 90 : return t;
2889 : }
2890 : break;
2891 : default:
2892 : break;
2893 : }
2894 1503 : tree ctor = build_constructor (TREE_TYPE (arg), NULL);
2895 1503 : CONSTRUCTOR_NO_CLEARING (ctor) = 1;
2896 1503 : CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
2897 1503 : tree modopexpr
2898 1503 : = build3_loc (loc, MODOP_EXPR, TREE_TYPE (arg), arg, ctor, NULL_TREE);
2899 1503 : arg = cxx_eval_store_expression (ctx, modopexpr, vc_discard, non_constant_p,
2900 : overflow_p, jump_target);
2901 1503 : ggc_free (modopexpr);
2902 1503 : if (*jump_target)
2903 : return NULL_TREE;
2904 1503 : if (*non_constant_p)
2905 : return t;
2906 1499 : return void_node;
2907 : }
2908 :
2909 : /* Attempt to evaluate T which represents a call to a builtin function.
2910 : We assume here that all builtin functions evaluate to scalar types
2911 : represented by _CST nodes. */
2912 :
2913 : static tree
2914 20795617 : cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
2915 : value_cat lval,
2916 : bool *non_constant_p, bool *overflow_p,
2917 : tree *jump_target)
2918 : {
2919 20795617 : const int nargs = call_expr_nargs (t);
2920 20795617 : tree *args = (tree *) alloca (nargs * sizeof (tree));
2921 20795617 : tree new_call;
2922 20795617 : int i;
2923 :
2924 : /* Don't fold __builtin_constant_p within a constexpr function. */
2925 20795617 : bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
2926 :
2927 : /* If we aren't requiring a constant expression, defer __builtin_constant_p
2928 : in a constexpr function until we have values for the parameters. */
2929 3574546 : if (bi_const_p
2930 3574546 : && ctx->manifestly_const_eval != mce_true
2931 1756398 : && current_function_decl
2932 1755269 : && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2933 : {
2934 1402408 : *non_constant_p = true;
2935 1402408 : return t;
2936 : }
2937 :
2938 19393209 : if (fndecl_built_in_p (fun, BUILT_IN_FRONTEND))
2939 4008038 : switch (DECL_FE_FUNCTION_CODE (fun))
2940 : {
2941 3983716 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
2942 : /* For __builtin_is_constant_evaluated, defer it if not
2943 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
2944 : without manifestly_const_eval even expressions or parts thereof
2945 : which will later be manifestly const_eval evaluated), otherwise fold
2946 : it to true. */
2947 3983716 : if (ctx->manifestly_const_eval == mce_unknown)
2948 : {
2949 3935472 : *non_constant_p = true;
2950 3935472 : return t;
2951 : }
2952 48244 : return constant_boolean_node (ctx->manifestly_const_eval == mce_true,
2953 48244 : boolean_type_node);
2954 :
2955 10995 : case CP_BUILT_IN_SOURCE_LOCATION:
2956 10995 : {
2957 10995 : temp_override<tree> ovr (current_function_decl);
2958 10995 : if (ctx->call && ctx->call->fundef)
2959 2765 : current_function_decl = ctx->call->fundef->decl;
2960 10995 : return fold_builtin_source_location (t);
2961 10995 : }
2962 :
2963 126 : case CP_BUILT_IN_EH_PTR_ADJUST_REF:
2964 126 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_EH_PTR_ADJUST_REF,
2965 : fun, non_constant_p, overflow_p,
2966 126 : jump_target);
2967 :
2968 2226 : case CP_BUILT_IN_CURRENT_EXCEPTION:
2969 2226 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_CURRENT_EXCEPTION,
2970 : fun, non_constant_p, overflow_p,
2971 2226 : jump_target);
2972 :
2973 82 : case CP_BUILT_IN_UNCAUGHT_EXCEPTIONS:
2974 82 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_UNCAUGHT_EXCEPTIONS,
2975 : fun, non_constant_p, overflow_p,
2976 82 : jump_target);
2977 :
2978 210 : case CP_BUILT_IN_CONSTEXPR_DIAG:
2979 210 : return cxx_eval_constexpr_diag (ctx, t, non_constant_p, overflow_p,
2980 210 : jump_target);
2981 :
2982 3952 : case CP_BUILT_IN_IS_WITHIN_LIFETIME:
2983 3952 : return cxx_eval_is_within_lifetime (ctx, t, fun, non_constant_p,
2984 3952 : overflow_p, jump_target);
2985 :
2986 1593 : case CP_BUILT_IN_START_LIFETIME:
2987 1593 : return cxx_eval_start_lifetime (ctx, t, fun, non_constant_p,
2988 1593 : overflow_p, jump_target);
2989 :
2990 : default:
2991 : break;
2992 : }
2993 :
2994 15390309 : int strops = 0;
2995 15390309 : int strret = 0;
2996 15390309 : bool bos = false;
2997 15390309 : if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
2998 14042987 : switch (DECL_FUNCTION_CODE (fun))
2999 : {
3000 : case BUILT_IN_STRLEN:
3001 : case BUILT_IN_STRNLEN:
3002 15390158 : strops = 1;
3003 : break;
3004 201852 : case BUILT_IN_MEMCHR:
3005 201852 : case BUILT_IN_STRCHR:
3006 201852 : case BUILT_IN_STRRCHR:
3007 201852 : strops = 1;
3008 201852 : strret = 1;
3009 201852 : break;
3010 112893 : case BUILT_IN_MEMCMP:
3011 112893 : case BUILT_IN_STRCMP:
3012 112893 : strops = 2;
3013 112893 : break;
3014 50056 : case BUILT_IN_STRSTR:
3015 50056 : strops = 2;
3016 50056 : strret = 1;
3017 50056 : break;
3018 66 : case BUILT_IN_ASAN_POINTER_COMPARE:
3019 66 : case BUILT_IN_ASAN_POINTER_SUBTRACT:
3020 66 : case BUILT_IN_OBSERVABLE_CHKPT:
3021 : /* These builtins shall be ignored during constant expression
3022 : evaluation. */
3023 66 : return void_node;
3024 85 : case BUILT_IN_UNREACHABLE:
3025 85 : case BUILT_IN_TRAP:
3026 85 : if (!*non_constant_p && !ctx->quiet)
3027 : {
3028 : /* Do not allow__builtin_unreachable in constexpr function.
3029 : The __builtin_unreachable call with BUILTINS_LOCATION
3030 : comes from cp_maybe_instrument_return. */
3031 25 : if (EXPR_LOCATION (t) == BUILTINS_LOCATION)
3032 0 : error ("%<constexpr%> call flows off the end of the function");
3033 : else
3034 25 : error ("%q+E is not a constant expression", t);
3035 : }
3036 85 : *non_constant_p = true;
3037 85 : return t;
3038 2881 : case BUILT_IN_OBJECT_SIZE:
3039 2881 : case BUILT_IN_DYNAMIC_OBJECT_SIZE:
3040 2881 : bos = ctx->manifestly_const_eval == mce_true;
3041 2881 : break;
3042 : default:
3043 : break;
3044 : }
3045 :
3046 : /* Be permissive for arguments to built-ins; __builtin_constant_p should
3047 : return constant false for a non-constant argument. */
3048 15390158 : constexpr_ctx new_ctx = *ctx;
3049 15390158 : new_ctx.quiet = true;
3050 41815032 : for (i = 0; i < nargs; ++i)
3051 : {
3052 26424876 : tree arg = CALL_EXPR_ARG (t, i);
3053 26424876 : tree oarg = arg;
3054 :
3055 : /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
3056 : expand_builtin doesn't know how to look in the values table. */
3057 26424876 : bool strop = i < strops;
3058 26424876 : if (strop)
3059 : {
3060 690678 : STRIP_NOPS (arg);
3061 690678 : if (TREE_CODE (arg) == ADDR_EXPR)
3062 8231 : arg = TREE_OPERAND (arg, 0);
3063 : else
3064 : strop = false;
3065 : }
3066 :
3067 : /* If builtin_valid_in_constant_expr_p is true,
3068 : potential_constant_expression_1 has not recursed into the arguments
3069 : of the builtin, verify it here. */
3070 26424876 : if (!builtin_valid_in_constant_expr_p (fun)
3071 26424876 : || potential_constant_expression (arg))
3072 : {
3073 26424739 : bool dummy1 = false, dummy2 = false;
3074 26424739 : tree jmp_target = NULL_TREE;
3075 26424739 : arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3076 : &dummy1, &dummy2, &jmp_target);
3077 26424737 : if (jmp_target)
3078 : {
3079 0 : *jump_target = jmp_target;
3080 0 : return NULL_TREE;
3081 : }
3082 : }
3083 :
3084 26424874 : if (bi_const_p)
3085 : /* For __builtin_constant_p, fold all expressions with constant values
3086 : even if they aren't C++ constant-expressions. */
3087 2172136 : arg = cp_fold_rvalue (arg);
3088 24252738 : else if (strop)
3089 : {
3090 8231 : if (TREE_CODE (arg) == CONSTRUCTOR)
3091 76 : arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
3092 8231 : if (TREE_CODE (arg) == STRING_CST)
3093 3073 : arg = build_address (arg);
3094 : else
3095 : arg = oarg;
3096 : }
3097 :
3098 : /* If the argument STRRET refers to didn't end up as the address of a
3099 : STRING_CST, the folded result is already relative to it and must not
3100 : be re-based on the original argument below. */
3101 26424874 : if (i == strret - 1
3102 26424874 : && (TREE_CODE (arg) != ADDR_EXPR
3103 110 : || TREE_CODE (TREE_OPERAND (arg, 0)) != STRING_CST))
3104 : strret = 0;
3105 :
3106 26424874 : args[i] = arg;
3107 : }
3108 15390156 : if (bos)
3109 : {
3110 102 : tree arg = args[0];
3111 102 : STRIP_NOPS (arg);
3112 102 : if (TREE_CODE (arg) == ADDR_EXPR)
3113 102 : args[0] = arg;
3114 : }
3115 :
3116 15390156 : bool save_ffbcp = force_folding_builtin_constant_p;
3117 15390156 : force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true;
3118 15390156 : tree save_cur_fn = current_function_decl;
3119 : /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */
3120 15390156 : if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION)
3121 37 : && ctx->call
3122 15390160 : && ctx->call->fundef)
3123 4 : current_function_decl = ctx->call->fundef->decl;
3124 15390156 : if (fndecl_built_in_p (fun,
3125 : CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
3126 : BUILT_IN_FRONTEND))
3127 : {
3128 336 : location_t loc = EXPR_LOCATION (t);
3129 336 : if (nargs >= 1)
3130 333 : VERIFY_CONSTANT (args[0]);
3131 136 : new_call
3132 136 : = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
3133 : args);
3134 : }
3135 15389820 : else if (fndecl_built_in_p (fun,
3136 : CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
3137 : BUILT_IN_FRONTEND))
3138 : {
3139 471 : location_t loc = EXPR_LOCATION (t);
3140 471 : if (nargs >= 2)
3141 : {
3142 465 : VERIFY_CONSTANT (args[0]);
3143 237 : VERIFY_CONSTANT (args[1]);
3144 : }
3145 243 : new_call = fold_builtin_is_corresponding_member (loc, nargs, args);
3146 : }
3147 15389349 : else if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_STRING_LITERAL,
3148 : BUILT_IN_FRONTEND))
3149 : {
3150 4331 : location_t loc = EXPR_LOCATION (t);
3151 4331 : if (nargs >= 1)
3152 : {
3153 4331 : tree arg = CALL_EXPR_ARG (t, 0);
3154 4331 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3155 : non_constant_p, overflow_p,
3156 : jump_target);
3157 4331 : if (*jump_target)
3158 : return NULL_TREE;
3159 4331 : args[0] = arg;
3160 : }
3161 4331 : new_call = fold_builtin_is_string_literal (loc, nargs, args);
3162 : }
3163 : else
3164 30770036 : new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
3165 15385018 : CALL_EXPR_FN (t), nargs, args);
3166 15389728 : current_function_decl = save_cur_fn;
3167 15389728 : force_folding_builtin_constant_p = save_ffbcp;
3168 15389728 : if (new_call == NULL)
3169 : {
3170 10473968 : if (!*non_constant_p && !ctx->quiet)
3171 : {
3172 0 : new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
3173 0 : CALL_EXPR_FN (t), nargs, args);
3174 0 : error ("%q+E is not a constant expression", new_call);
3175 : }
3176 10473968 : *non_constant_p = true;
3177 10473968 : return t;
3178 : }
3179 :
3180 4915760 : if (!potential_constant_expression (new_call))
3181 : {
3182 861 : if (!*non_constant_p && !ctx->quiet)
3183 4 : error ("%q+E is not a constant expression", new_call);
3184 861 : *non_constant_p = true;
3185 861 : return t;
3186 : }
3187 :
3188 4914899 : if (strret)
3189 : {
3190 : /* memchr returns a pointer into the first argument, but we replaced the
3191 : argument above with a STRING_CST; put it back it now. */
3192 18 : tree op = CALL_EXPR_ARG (t, strret-1);
3193 18 : STRIP_NOPS (new_call);
3194 18 : if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
3195 15 : TREE_OPERAND (new_call, 0) = op;
3196 3 : else if (TREE_CODE (new_call) == ADDR_EXPR)
3197 4914899 : new_call = op;
3198 : }
3199 :
3200 4914899 : return cxx_eval_constant_expression (&new_ctx, new_call, lval,
3201 : non_constant_p, overflow_p,
3202 4914899 : jump_target);
3203 : }
3204 :
3205 : /* TEMP is the constant value of a temporary object of type TYPE. Adjust
3206 : the type of the value to match. */
3207 :
3208 : static tree
3209 137195840 : adjust_temp_type (tree type, tree temp)
3210 : {
3211 137195840 : if (same_type_p (TREE_TYPE (temp), type))
3212 : return temp;
3213 : /* Avoid wrapping an aggregate value in a NOP_EXPR. */
3214 63353447 : if (TREE_CODE (temp) == CONSTRUCTOR)
3215 : {
3216 : /* build_constructor wouldn't retain various CONSTRUCTOR flags. */
3217 3829217 : tree t = copy_node (temp);
3218 3829217 : TREE_TYPE (t) = type;
3219 3829217 : return t;
3220 : }
3221 59524230 : if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
3222 0 : return build0 (EMPTY_CLASS_EXPR, type);
3223 59524230 : gcc_assert (scalarish_type_p (type));
3224 : /* Now we know we're dealing with a scalar, and a prvalue of non-class
3225 : type is cv-unqualified. */
3226 59524230 : return cp_fold_convert (cv_unqualified (type), temp);
3227 : }
3228 :
3229 : /* If T is a CONSTRUCTOR, return an unshared copy of T and any
3230 : sub-CONSTRUCTORs. Otherwise return T.
3231 :
3232 : We use this whenever we initialize an object as a whole, whether it's a
3233 : parameter, a local variable, or a subobject, so that subsequent
3234 : modifications don't affect other places where it was used. */
3235 :
3236 : tree
3237 124235767 : unshare_constructor (tree t MEM_STAT_DECL)
3238 : {
3239 124235767 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
3240 : return t;
3241 18650553 : auto_vec <tree*, 4> ptrs;
3242 18650553 : ptrs.safe_push (&t);
3243 18650553 : while (!ptrs.is_empty ())
3244 : {
3245 24534812 : tree *p = ptrs.pop ();
3246 24534812 : tree n = copy_node (*p PASS_MEM_STAT);
3247 40705174 : CONSTRUCTOR_ELTS (n) = vec_safe_copy (CONSTRUCTOR_ELTS (*p) PASS_MEM_STAT);
3248 24534812 : *p = n;
3249 24534812 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n);
3250 24534812 : constructor_elt *ce;
3251 94252716 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i)
3252 : {
3253 26532539 : if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
3254 780 : ce->index = copy_node (ce->index PASS_MEM_STAT);
3255 26532539 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
3256 5884259 : ptrs.safe_push (&ce->value);
3257 : }
3258 : }
3259 18650553 : return t;
3260 18650553 : }
3261 :
3262 : /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs. */
3263 :
3264 : static void
3265 884092 : free_constructor (tree t)
3266 : {
3267 884092 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
3268 0 : return;
3269 884092 : releasing_vec ctors;
3270 884092 : vec_safe_push (ctors, t);
3271 2691502 : while (!ctors->is_empty ())
3272 : {
3273 923318 : tree c = ctors->pop ();
3274 923318 : if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c))
3275 : {
3276 : constructor_elt *ce;
3277 394421 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
3278 255386 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
3279 39226 : vec_safe_push (ctors, ce->value);
3280 139035 : ggc_free (elts);
3281 : }
3282 923318 : ggc_free (c);
3283 : }
3284 884092 : }
3285 :
3286 : /* Helper function of cxx_bind_parameters_in_call. Return non-NULL
3287 : if *TP is address of a static variable (or part of it) currently being
3288 : constructed or of a heap artificial variable. */
3289 :
3290 : static tree
3291 49056658 : addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data)
3292 : {
3293 49056658 : if (TREE_CODE (*tp) == ADDR_EXPR)
3294 9095103 : if (tree var = get_base_address (TREE_OPERAND (*tp, 0)))
3295 9095103 : if (VAR_P (var) && TREE_STATIC (var))
3296 : {
3297 5683494 : if (DECL_NAME (var) == heap_uninit_identifier
3298 5683494 : || DECL_NAME (var) == heap_identifier
3299 5683494 : || DECL_NAME (var) == heap_vec_uninit_identifier
3300 11366988 : || DECL_NAME (var) == heap_vec_identifier)
3301 : return var;
3302 :
3303 5683494 : constexpr_global_ctx *global = (constexpr_global_ctx *) data;
3304 5683494 : if (global->get_value (var))
3305 : return var;
3306 : }
3307 48607413 : if (TYPE_P (*tp))
3308 2503 : *walk_subtrees = false;
3309 : return NULL_TREE;
3310 : }
3311 :
3312 : /* Subroutine of cxx_eval_call_expression.
3313 : We are processing a call expression (either CALL_EXPR or
3314 : AGGR_INIT_EXPR) in the context of CTX. Evaluate
3315 : all arguments and bind their values to correspondings
3316 : parameters, making up the NEW_CALL context. */
3317 :
3318 : static tree
3319 185332810 : cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
3320 : tree orig_fun, bool *non_constant_p,
3321 : bool *overflow_p, bool *non_constant_args,
3322 : tree *jump_target)
3323 : {
3324 185332810 : int nargs = call_expr_nargs (t);
3325 185332810 : tree parms = DECL_ARGUMENTS (fun);
3326 185332810 : int i, j = 0;
3327 185332810 : if (DECL_HAS_IN_CHARGE_PARM_P (fun) && fun != orig_fun)
3328 1523 : ++nargs;
3329 185332810 : if (DECL_HAS_VTT_PARM_P (fun)
3330 1525 : && fun != orig_fun
3331 185334333 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3332 1082 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
3333 463 : ++nargs;
3334 : /* We don't record ellipsis args below. */
3335 185332810 : int nparms = list_length (parms);
3336 185332810 : int nbinds = nargs < nparms ? nargs : nparms;
3337 185332810 : tree binds = make_tree_vec (nbinds);
3338 :
3339 : /* The call is not a constant expression if it involves the cdtor for a type
3340 : with virtual bases before C++26. */
3341 185332810 : if (cxx_dialect < cxx26
3342 185332810 : && (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun)))
3343 : {
3344 17 : if (!ctx->quiet)
3345 : {
3346 3 : error_at (cp_expr_loc_or_input_loc (t),
3347 : "call to non-%<constexpr%> function %qD", fun);
3348 3 : explain_invalid_constexpr_fn (fun);
3349 : }
3350 17 : *non_constant_p = true;
3351 17 : return binds;
3352 : }
3353 :
3354 333552436 : for (i = 0; i < nargs; ++i)
3355 : {
3356 222843806 : tree x, arg;
3357 222843806 : tree type = parms ? TREE_TYPE (parms) : void_type_node;
3358 222843806 : if (parms && DECL_BY_REFERENCE (parms))
3359 27167 : type = TREE_TYPE (type);
3360 222843806 : if (i == 1
3361 222843806 : && j == 0
3362 47768079 : && DECL_HAS_IN_CHARGE_PARM_P (fun)
3363 222845197 : && orig_fun != fun)
3364 : {
3365 1391 : if (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3366 1391 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))
3367 428 : x = boolean_true_node;
3368 : else
3369 963 : x = boolean_false_node;
3370 : j = -1;
3371 : }
3372 222842415 : else if (i == 2
3373 222842415 : && j == -1
3374 1391 : && DECL_HAS_VTT_PARM_P (fun)
3375 1391 : && orig_fun != fun
3376 222843806 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3377 985 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
3378 : {
3379 428 : x = build_zero_cst (type);
3380 428 : j = -2;
3381 : }
3382 : else
3383 222841987 : x = get_nth_callarg (t, i + j);
3384 : /* For member function, the first argument is a pointer to the implied
3385 : object. For a constructor, it might still be a dummy object, in
3386 : which case we get the real argument from ctx. */
3387 326695110 : if (i == 0 && DECL_CONSTRUCTOR_P (fun)
3388 245998770 : && is_dummy_object (x))
3389 : {
3390 11855994 : x = ctx->object;
3391 11855994 : x = build_address (x);
3392 : }
3393 222843806 : if (TREE_ADDRESSABLE (type))
3394 : {
3395 : /* Undo convert_for_arg_passing work here. */
3396 39225 : x = convert_from_reference (x);
3397 39225 : arg = cxx_eval_constant_expression (ctx, x, vc_glvalue,
3398 : non_constant_p, overflow_p,
3399 : jump_target);
3400 : }
3401 : else
3402 : /* Normally we would strip a TARGET_EXPR in an initialization context
3403 : such as this, but here we do the elision differently: we keep the
3404 : TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */
3405 222804581 : arg = cxx_eval_constant_expression (ctx, x, vc_prvalue,
3406 : non_constant_p, overflow_p,
3407 : jump_target);
3408 222843806 : if (*jump_target)
3409 : break;
3410 : /* Check we aren't dereferencing a null pointer when calling a non-static
3411 : member function, which is undefined behaviour. */
3412 163347500 : if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun)
3413 92945626 : && integer_zerop (arg)
3414 : /* But ignore calls from within compiler-generated code, to handle
3415 : cases like lambda function pointer conversion operator thunks
3416 : which pass NULL as the 'this' pointer. */
3417 223018873 : && !(TREE_CODE (t) == CALL_EXPR && CALL_FROM_THUNK_P (t)))
3418 : {
3419 527 : if (!ctx->quiet)
3420 6 : error_at (cp_expr_loc_or_input_loc (x),
3421 : "dereferencing a null pointer");
3422 527 : *non_constant_p = true;
3423 : }
3424 : /* Don't VERIFY_CONSTANT here. */
3425 222843722 : if (*non_constant_p && ctx->quiet)
3426 : break;
3427 : /* Just discard ellipsis args after checking their constantitude. */
3428 148219643 : if (!parms)
3429 400 : continue;
3430 :
3431 148219243 : if (!*non_constant_p)
3432 : {
3433 : /* Make sure the binding has the same type as the parm. But
3434 : only for constant args. */
3435 148218469 : if (TREE_ADDRESSABLE (type))
3436 : {
3437 26088 : if (!same_type_p (type, TREE_TYPE (arg)))
3438 : {
3439 9 : arg = build_fold_addr_expr (arg);
3440 9 : arg = cp_fold_convert (build_reference_type (type), arg);
3441 9 : arg = convert_from_reference (arg);
3442 : }
3443 : }
3444 148192381 : else if (!TYPE_REF_P (type))
3445 105897754 : arg = adjust_temp_type (type, arg);
3446 148218469 : if (!TREE_CONSTANT (arg))
3447 97654836 : *non_constant_args = true;
3448 50563633 : else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
3449 : /* The destructor needs to see any modifications the callee makes
3450 : to the argument. */
3451 0 : *non_constant_args = true;
3452 : /* If arg is or contains address of a heap artificial variable or
3453 : of a static variable being constructed, avoid caching the
3454 : function call, as those variables might be modified by the
3455 : function, or might be modified by the callers in between
3456 : the cached function and just read by the function. */
3457 50563633 : else if (!*non_constant_args
3458 50563633 : && cp_walk_tree (&arg, addr_of_non_const_var, ctx->global,
3459 : NULL))
3460 449245 : *non_constant_args = true;
3461 :
3462 : /* For virtual calls, adjust the this argument, so that it is
3463 : the object on which the method is called, rather than
3464 : one of its bases. */
3465 148218469 : if (i == 0 && DECL_VIRTUAL_P (fun))
3466 : {
3467 27541 : tree addr = arg;
3468 27541 : STRIP_NOPS (addr);
3469 27541 : if (TREE_CODE (addr) == ADDR_EXPR)
3470 : {
3471 27504 : tree obj = TREE_OPERAND (addr, 0);
3472 27504 : while (TREE_CODE (obj) == COMPONENT_REF
3473 11861 : && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))
3474 39443 : && !same_type_ignoring_top_level_qualifiers_p
3475 11768 : (TREE_TYPE (obj), DECL_CONTEXT (fun)))
3476 171 : obj = TREE_OPERAND (obj, 0);
3477 27504 : if (obj != TREE_OPERAND (addr, 0))
3478 168 : arg = build_fold_addr_expr_with_type (obj,
3479 : TREE_TYPE (arg));
3480 : }
3481 : }
3482 148218469 : TREE_VEC_ELT (binds, i) = arg;
3483 : }
3484 148219243 : parms = TREE_CHAIN (parms);
3485 : }
3486 :
3487 : return binds;
3488 : }
3489 :
3490 : static int
3491 110113303 : push_cx_call_context (tree call)
3492 : {
3493 110113303 : ++call_stack_tick;
3494 110113303 : if (!EXPR_HAS_LOCATION (call))
3495 76449 : SET_EXPR_LOCATION (call, input_location);
3496 110113303 : call_stack.safe_push (call);
3497 110113303 : int len = call_stack.length ();
3498 110113303 : if (len > max_constexpr_depth)
3499 33 : return false;
3500 : return len;
3501 : }
3502 :
3503 : static void
3504 110113299 : pop_cx_call_context (void)
3505 : {
3506 110113299 : ++call_stack_tick;
3507 110113299 : call_stack.pop ();
3508 110113299 : }
3509 :
3510 : vec<tree>
3511 259623 : cx_error_context (void)
3512 : {
3513 259623 : vec<tree> r = vNULL;
3514 259623 : if (call_stack_tick != last_cx_error_tick
3515 259623 : && !call_stack.is_empty ())
3516 : r = call_stack;
3517 259623 : last_cx_error_tick = call_stack_tick;
3518 259623 : return r;
3519 : }
3520 :
3521 : /* E is an operand of a failed assertion, fold it either with or without
3522 : constexpr context. */
3523 :
3524 : static tree
3525 829 : fold_operand (tree e, const constexpr_ctx *ctx)
3526 : {
3527 829 : if (ctx)
3528 : {
3529 32 : bool new_non_constant_p = false, new_overflow_p = false;
3530 32 : tree jmp_target = NULL_TREE;
3531 32 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
3532 : &new_non_constant_p,
3533 : &new_overflow_p, &jmp_target);
3534 : }
3535 : else
3536 797 : e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true);
3537 829 : return e;
3538 : }
3539 :
3540 : /* If we have a condition in conjunctive normal form (CNF), find the first
3541 : failing clause. In other words, given an expression like
3542 :
3543 : true && true && false && true && false
3544 :
3545 : return the first 'false'. EXPR is the expression. */
3546 :
3547 : static tree
3548 332 : find_failing_clause_r (const constexpr_ctx *ctx, tree expr)
3549 : {
3550 437 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3551 : {
3552 : /* First check the left side... */
3553 192 : tree e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 0));
3554 192 : if (e == NULL_TREE)
3555 : /* ...if we didn't find a false clause, check the right side. */
3556 105 : e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 1));
3557 : return e;
3558 : }
3559 245 : tree e = contextual_conv_bool (expr, tf_none);
3560 245 : e = fold_operand (e, ctx);
3561 245 : if (integer_zerop (e))
3562 : /* This is the failing clause. */
3563 140 : return expr;
3564 : return NULL_TREE;
3565 : }
3566 :
3567 : /* Wrapper for find_failing_clause_r. */
3568 :
3569 : tree
3570 1986 : find_failing_clause (const constexpr_ctx *ctx, tree expr)
3571 : {
3572 1986 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3573 140 : if (tree e = find_failing_clause_r (ctx, expr))
3574 1986 : expr = e;
3575 1986 : return expr;
3576 : }
3577 :
3578 : /* Emit additional diagnostics for failing condition BAD.
3579 : Used by finish_static_assert and IFN_ASSUME constexpr diagnostics.
3580 : If SHOW_EXPR_P is true, print the condition (because it was
3581 : instantiation-dependent). */
3582 :
3583 : void
3584 1986 : diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p,
3585 : const constexpr_ctx *ctx /* = nullptr */)
3586 : {
3587 : /* Nobody wants to see the artificial (bool) cast. */
3588 1986 : bad = tree_strip_nop_conversions (bad);
3589 1986 : if (TREE_CODE (bad) == CLEANUP_POINT_EXPR)
3590 3 : bad = TREE_OPERAND (bad, 0);
3591 :
3592 1986 : auto_diagnostic_nesting_level sentinel;
3593 :
3594 : /* Actually explain the failure if this is a concept check or a
3595 : requires-expression. */
3596 1986 : if (concept_check_p (bad) || TREE_CODE (bad) == REQUIRES_EXPR)
3597 334 : diagnose_constraints (cloc, bad, NULL_TREE);
3598 : /* Similarly if this is a standard trait. */
3599 1652 : else if (maybe_diagnose_standard_trait (cloc, bad))
3600 : ;
3601 1297 : else if (COMPARISON_CLASS_P (bad)
3602 1297 : && (ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))
3603 76 : || REFLECTION_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))))
3604 : {
3605 292 : tree op0 = fold_operand (TREE_OPERAND (bad, 0), ctx);
3606 292 : tree op1 = fold_operand (TREE_OPERAND (bad, 1), ctx);
3607 292 : tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
3608 292 : inform (cloc, "the comparison reduces to %qE", cond);
3609 : }
3610 1005 : else if (show_expr_p)
3611 755 : inform (cloc, "%qE evaluates to false", bad);
3612 1986 : }
3613 :
3614 : /* Process an assert/assume of ORIG_ARG. If it's not supposed to be evaluated,
3615 : do it without changing the current evaluation state. If it evaluates to
3616 : false, complain and return false; otherwise, return true. */
3617 :
3618 : static bool
3619 173602 : cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg,
3620 : location_t loc, bool evaluated,
3621 : bool *non_constant_p, bool *overflow_p)
3622 : {
3623 173602 : if (*non_constant_p)
3624 : return true;
3625 :
3626 173602 : tree eval, jmp_target = NULL_TREE;
3627 173602 : if (!evaluated)
3628 : {
3629 173602 : if (!potential_rvalue_constant_expression (arg))
3630 16 : return true;
3631 :
3632 173586 : constexpr_ctx new_ctx = *ctx;
3633 173586 : new_ctx.quiet = true;
3634 173586 : bool new_non_constant_p = false, new_overflow_p = false;
3635 : /* Avoid modification of existing values. */
3636 173586 : modifiable_tracker ms (new_ctx.global);
3637 173586 : eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3638 : &new_non_constant_p,
3639 : &new_overflow_p, &jmp_target);
3640 173586 : }
3641 : else
3642 0 : eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3643 : non_constant_p,
3644 : overflow_p, &jmp_target);
3645 173586 : if (jmp_target)
3646 : return true;
3647 :
3648 173586 : if (!*non_constant_p && integer_zerop (eval))
3649 : {
3650 42 : if (!ctx->quiet)
3651 : {
3652 : /* See if we can find which clause was failing
3653 : (for logical AND). */
3654 13 : tree bad = find_failing_clause (ctx, arg);
3655 : /* If not, or its location is unusable, fall back to the
3656 : previous location. */
3657 13 : location_t cloc = cp_expr_loc_or_loc (bad, loc);
3658 :
3659 : /* Report the error. */
3660 13 : auto_diagnostic_group d;
3661 13 : error_at (cloc, msg);
3662 13 : diagnose_failing_condition (bad, cloc, true, ctx);
3663 13 : return bad;
3664 13 : }
3665 29 : *non_constant_p = true;
3666 29 : return false;
3667 : }
3668 :
3669 : return true;
3670 : }
3671 :
3672 : /* Evaluate a call T to a GCC internal function when possible and return
3673 : the evaluated result or, under the control of CTX, give an error, set
3674 : NON_CONSTANT_P, and return the unevaluated call T otherwise. */
3675 :
3676 : static tree
3677 389025 : cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
3678 : value_cat lval,
3679 : bool *non_constant_p, bool *overflow_p,
3680 : tree *jump_target)
3681 : {
3682 389025 : enum tree_code opcode = ERROR_MARK;
3683 :
3684 389025 : switch (CALL_EXPR_IFN (t))
3685 : {
3686 166 : case IFN_UBSAN_NULL:
3687 166 : case IFN_UBSAN_BOUNDS:
3688 166 : case IFN_UBSAN_VPTR:
3689 166 : case IFN_FALLTHROUGH:
3690 166 : return void_node;
3691 :
3692 173602 : case IFN_ASSUME:
3693 173602 : if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0),
3694 : G_("failed %<assume%> attribute assumption"),
3695 173602 : EXPR_LOCATION (t), /*eval*/false,
3696 : non_constant_p, overflow_p))
3697 : return t;
3698 173573 : return void_node;
3699 :
3700 : case IFN_ADD_OVERFLOW:
3701 : opcode = PLUS_EXPR;
3702 : break;
3703 385 : case IFN_SUB_OVERFLOW:
3704 385 : opcode = MINUS_EXPR;
3705 385 : break;
3706 207466 : case IFN_MUL_OVERFLOW:
3707 207466 : opcode = MULT_EXPR;
3708 207466 : break;
3709 :
3710 96 : case IFN_LAUNDER:
3711 96 : return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3712 : vc_prvalue, non_constant_p,
3713 96 : overflow_p, jump_target);
3714 :
3715 0 : case IFN_DEFERRED_INIT:
3716 0 : return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
3717 :
3718 176 : case IFN_BSWAP:
3719 176 : case IFN_BITREVERSE:
3720 176 : {
3721 176 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3722 : vc_prvalue, non_constant_p,
3723 : overflow_p, jump_target);
3724 176 : if (*jump_target)
3725 : return NULL_TREE;
3726 176 : if (*non_constant_p)
3727 : return t;
3728 104 : location_t loc = cp_expr_loc_or_input_loc (t);
3729 104 : if (TREE_CODE (arg) != INTEGER_CST
3730 104 : || !INTEGRAL_TYPE_P (TREE_TYPE (arg))
3731 104 : || !TYPE_UNSIGNED (TREE_TYPE (arg))
3732 208 : || (CALL_EXPR_IFN (t) == IFN_BSWAP
3733 30 : && (TYPE_PRECISION (TREE_TYPE (arg)) % 8) != 0))
3734 : {
3735 0 : if (!ctx->quiet)
3736 0 : error_at (loc, "call to internal function %qE", t);
3737 0 : *non_constant_p = true;
3738 0 : return t;
3739 : }
3740 104 : return fold_build_builtin_bswapg_bitreverseg (loc, CALL_EXPR_IFN (t),
3741 104 : arg);
3742 : }
3743 :
3744 6634 : case IFN_VEC_CONVERT:
3745 6634 : {
3746 6634 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3747 : vc_prvalue, non_constant_p,
3748 : overflow_p, jump_target);
3749 6634 : if (*jump_target)
3750 : return NULL_TREE;
3751 6634 : if (TREE_CODE (arg) == VECTOR_CST)
3752 6237 : if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
3753 : return r;
3754 : }
3755 : /* FALLTHRU */
3756 :
3757 402 : default:
3758 402 : if (!ctx->quiet)
3759 0 : error_at (cp_expr_loc_or_input_loc (t),
3760 : "call to internal function %qE", t);
3761 402 : *non_constant_p = true;
3762 402 : return t;
3763 : }
3764 :
3765 : /* Evaluate constant arguments using OPCODE and return a complex
3766 : number containing the result and the overflow bit. */
3767 208351 : tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval,
3768 : non_constant_p, overflow_p,
3769 : jump_target);
3770 208351 : tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval,
3771 : non_constant_p, overflow_p,
3772 : jump_target);
3773 208351 : if (*jump_target)
3774 : return NULL_TREE;
3775 208351 : if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3776 : {
3777 2 : location_t loc = cp_expr_loc_or_input_loc (t);
3778 2 : tree type = TREE_TYPE (TREE_TYPE (t));
3779 2 : tree result = fold_binary_loc (loc, opcode, type,
3780 : fold_convert_loc (loc, type, arg0),
3781 : fold_convert_loc (loc, type, arg1));
3782 2 : tree ovf
3783 2 : = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1));
3784 : /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */
3785 2 : if (TREE_OVERFLOW (result))
3786 0 : TREE_OVERFLOW (result) = 0;
3787 :
3788 2 : return build_complex (TREE_TYPE (t), result, ovf);
3789 : }
3790 :
3791 208349 : *non_constant_p = true;
3792 208349 : return t;
3793 : }
3794 :
3795 : /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates. */
3796 :
3797 : static void
3798 6000952 : clear_no_implicit_zero (tree ctor)
3799 : {
3800 6000952 : if (CONSTRUCTOR_NO_CLEARING (ctor))
3801 : {
3802 1745093 : CONSTRUCTOR_NO_CLEARING (ctor) = false;
3803 7387798 : for (auto &e: CONSTRUCTOR_ELTS (ctor))
3804 2321121 : if (TREE_CODE (e.value) == CONSTRUCTOR)
3805 729752 : clear_no_implicit_zero (e.value);
3806 : }
3807 6000952 : }
3808 :
3809 : /* Complain about a const object OBJ being modified in a constant expression.
3810 : EXPR is the MODIFY_EXPR expression performing the modification. */
3811 :
3812 : static void
3813 65 : modifying_const_object_error (tree expr, tree obj)
3814 : {
3815 65 : location_t loc = cp_expr_loc_or_input_loc (expr);
3816 65 : auto_diagnostic_group d;
3817 130 : error_at (loc, "modifying a const object %qE is not allowed in "
3818 65 : "a constant expression", TREE_OPERAND (expr, 0));
3819 :
3820 : /* Find the underlying object that was declared as const. */
3821 65 : location_t decl_loc = UNKNOWN_LOCATION;
3822 207 : for (tree probe = obj; decl_loc == UNKNOWN_LOCATION; )
3823 77 : switch (TREE_CODE (probe))
3824 : {
3825 39 : case BIT_FIELD_REF:
3826 39 : case COMPONENT_REF:
3827 39 : {
3828 39 : tree elt = TREE_OPERAND (probe, 1);
3829 39 : if (CP_TYPE_CONST_P (TREE_TYPE (elt)))
3830 27 : decl_loc = DECL_SOURCE_LOCATION (elt);
3831 39 : probe = TREE_OPERAND (probe, 0);
3832 : }
3833 39 : break;
3834 :
3835 0 : case ARRAY_REF:
3836 0 : case REALPART_EXPR:
3837 0 : case IMAGPART_EXPR:
3838 0 : probe = TREE_OPERAND (probe, 0);
3839 0 : break;
3840 :
3841 38 : default:
3842 38 : decl_loc = location_of (probe);
3843 38 : break;
3844 : }
3845 65 : inform (decl_loc, "originally declared %<const%> here");
3846 65 : }
3847 :
3848 : /* Return true if FNDECL is a replaceable global allocation function that
3849 : should be usable during constant expression evaluation. */
3850 :
3851 : static inline bool
3852 38871472 : cxx_replaceable_global_alloc_fn (tree fndecl)
3853 : {
3854 38871472 : return (cxx_dialect >= cxx20
3855 36805973 : && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))
3856 2247653 : && CP_DECL_CONTEXT (fndecl) == global_namespace
3857 41118728 : && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)
3858 929072 : || DECL_IS_OPERATOR_DELETE_P (fndecl)));
3859 : }
3860 :
3861 : /* Return true if FNDECL is a placement new function that should be
3862 : usable during constant expression evaluation of std::construct_at. */
3863 :
3864 : static inline bool
3865 37386944 : cxx_placement_new_fn (tree fndecl)
3866 : {
3867 37386944 : return (cxx_dialect >= cxx20 && std_placement_new_fn_p (fndecl));
3868 : }
3869 :
3870 : /* Return true if FNDECL is std::construct_at. */
3871 :
3872 : static inline bool
3873 2340446 : is_std_construct_at (tree fndecl)
3874 : {
3875 2340446 : if (!decl_in_std_namespace_p (fndecl))
3876 : return false;
3877 :
3878 2296118 : tree name = DECL_NAME (fndecl);
3879 2296118 : return name && id_equal (name, "construct_at");
3880 : }
3881 :
3882 : /* Overload for the above taking constexpr_call*. */
3883 :
3884 : static inline bool
3885 2098911 : is_std_construct_at (const constexpr_call *call)
3886 : {
3887 2098911 : return (call
3888 1936514 : && call->fundef
3889 4035425 : && is_std_construct_at (call->fundef->decl));
3890 : }
3891 :
3892 : /* True if CTX is an instance of std::NAME class. */
3893 :
3894 : bool
3895 12411008 : is_std_class (tree ctx, const char *name)
3896 : {
3897 12411008 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3898 : return false;
3899 :
3900 12410386 : tree decl = TYPE_MAIN_DECL (ctx);
3901 12410386 : tree dname = DECL_NAME (decl);
3902 12410386 : if (dname == NULL_TREE || !id_equal (dname, name))
3903 : return false;
3904 :
3905 880591 : return decl_in_std_namespace_p (decl);
3906 : }
3907 :
3908 : /* True if CTX is an instance of std::allocator. */
3909 :
3910 : bool
3911 716081 : is_std_allocator (tree ctx)
3912 : {
3913 716081 : return is_std_class (ctx, "allocator");
3914 : }
3915 :
3916 : /* Return true if FNDECL is std::allocator<T>::allocate. */
3917 :
3918 : static bool
3919 107589 : is_std_allocator_allocate (tree fndecl)
3920 : {
3921 107589 : tree name = DECL_NAME (fndecl);
3922 107589 : if (name == NULL_TREE || !id_equal (name, "allocate"))
3923 : return false;
3924 :
3925 99010 : return is_std_allocator (DECL_CONTEXT (fndecl));
3926 : }
3927 :
3928 : /* Overload for the above taking constexpr_call*. */
3929 :
3930 : static inline bool
3931 118268 : is_std_allocator_allocate (const constexpr_call *call)
3932 : {
3933 118268 : return (call
3934 107589 : && call->fundef
3935 225857 : && is_std_allocator_allocate (call->fundef->decl));
3936 : }
3937 :
3938 : /* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
3939 :
3940 : static bool
3941 662321 : is_std_allocator_allocate_deallocate (tree fndecl)
3942 : {
3943 662321 : tree name = DECL_NAME (fndecl);
3944 662321 : if (name == NULL_TREE
3945 662321 : || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
3946 : return false;
3947 :
3948 615439 : return is_std_allocator (DECL_CONTEXT (fndecl));
3949 : }
3950 :
3951 : /* Overload for the above taking constexpr_call*. */
3952 :
3953 : static inline bool
3954 496228 : is_std_allocator_allocate_deallocate (const constexpr_call *call)
3955 : {
3956 496228 : return (call
3957 298376 : && call->fundef
3958 794604 : && is_std_allocator_allocate_deallocate (call->fundef->decl));
3959 : }
3960 :
3961 : /* Return true if FNDECL is std::source_location::current. */
3962 :
3963 : static inline bool
3964 58804 : is_std_source_location_current (tree fndecl)
3965 : {
3966 58804 : if (!decl_in_std_namespace_p (fndecl))
3967 : return false;
3968 :
3969 39617 : tree name = DECL_NAME (fndecl);
3970 39617 : if (name == NULL_TREE || !id_equal (name, "current"))
3971 : return false;
3972 :
3973 159 : tree ctx = DECL_CONTEXT (fndecl);
3974 159 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3975 : return false;
3976 :
3977 159 : name = DECL_NAME (TYPE_MAIN_DECL (ctx));
3978 159 : return name && id_equal (name, "source_location");
3979 : }
3980 :
3981 : /* Overload for the above taking constexpr_call*. */
3982 :
3983 : static inline bool
3984 86160 : is_std_source_location_current (const constexpr_call *call)
3985 : {
3986 86160 : return (call
3987 58804 : && call->fundef
3988 144964 : && is_std_source_location_current (call->fundef->decl));
3989 : }
3990 :
3991 : /* Return true if FNDECL is __dynamic_cast. */
3992 :
3993 : static inline bool
3994 37075626 : cxx_dynamic_cast_fn_p (tree fndecl)
3995 : {
3996 37075626 : return (cxx_dialect >= cxx20
3997 35010122 : && id_equal (DECL_NAME (fndecl), "__dynamic_cast")
3998 6788 : && CP_DECL_CONTEXT (fndecl) == abi_node
3999 : /* Only consider implementation-detail __dynamic_cast calls that
4000 : correspond to a dynamic_cast, and ignore direct calls to
4001 : abi::__dynamic_cast. */
4002 37082414 : && DECL_ARTIFICIAL (fndecl));
4003 : }
4004 :
4005 : /* Often, we have an expression in the form of address + offset, e.g.
4006 : "&_ZTV1A + 16". Extract the object from it, i.e. "_ZTV1A". */
4007 :
4008 : static tree
4009 5840 : extract_obj_from_addr_offset (tree expr)
4010 : {
4011 5840 : if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
4012 2786 : expr = TREE_OPERAND (expr, 0);
4013 5840 : STRIP_NOPS (expr);
4014 5840 : if (TREE_CODE (expr) == ADDR_EXPR)
4015 5829 : expr = TREE_OPERAND (expr, 0);
4016 5840 : return expr;
4017 : }
4018 :
4019 : /* Given a PATH like
4020 :
4021 : g.D.2181.D.2154.D.2102.D.2093
4022 :
4023 : find a component with type TYPE. Return NULL_TREE if not found, and
4024 : error_mark_node if the component is not accessible. If STOP is non-null,
4025 : this function will return NULL_TREE if STOP is found before TYPE. */
4026 :
4027 : static tree
4028 2831 : get_component_with_type (tree path, tree type, tree stop)
4029 : {
4030 7921 : while (true)
4031 : {
4032 5376 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path), type))
4033 : /* Found it. */
4034 : return path;
4035 3761 : else if (stop
4036 3761 : && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path),
4037 : stop)))
4038 : return NULL_TREE;
4039 3716 : else if (TREE_CODE (path) == COMPONENT_REF
4040 3716 : && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1)))
4041 : {
4042 : /* We need to check that the component we're accessing is in fact
4043 : accessible. */
4044 3716 : if (TREE_PRIVATE (TREE_OPERAND (path, 1))
4045 3716 : || TREE_PROTECTED (TREE_OPERAND (path, 1)))
4046 1171 : return error_mark_node;
4047 2545 : path = TREE_OPERAND (path, 0);
4048 : }
4049 : else
4050 : return NULL_TREE;
4051 : }
4052 : }
4053 :
4054 : /* Evaluate a call to __dynamic_cast (permitted by P1327R1).
4055 :
4056 : The declaration of __dynamic_cast is:
4057 :
4058 : void* __dynamic_cast (const void* __src_ptr,
4059 : const __class_type_info* __src_type,
4060 : const __class_type_info* __dst_type,
4061 : ptrdiff_t __src2dst);
4062 :
4063 : where src2dst has the following possible values
4064 :
4065 : >-1: src_type is a unique public non-virtual base of dst_type
4066 : dst_ptr + src2dst == src_ptr
4067 : -1: unspecified relationship
4068 : -2: src_type is not a public base of dst_type
4069 : -3: src_type is a multiple public non-virtual base of dst_type */
4070 :
4071 : static tree
4072 3173 : cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
4073 : bool *non_constant_p, bool *overflow_p,
4074 : tree *jump_target)
4075 : {
4076 : /* T will be something like
4077 : __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8)
4078 : dismantle it. */
4079 3173 : gcc_assert (call_expr_nargs (call) == 4);
4080 3173 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
4081 3173 : tree obj = CALL_EXPR_ARG (call, 0);
4082 3173 : tree type = CALL_EXPR_ARG (call, 2);
4083 3173 : HOST_WIDE_INT hint = int_cst_value (CALL_EXPR_ARG (call, 3));
4084 3173 : location_t loc = cp_expr_loc_or_input_loc (call);
4085 :
4086 : /* Get the target type of the dynamic_cast. */
4087 3173 : gcc_assert (TREE_CODE (type) == ADDR_EXPR);
4088 3173 : type = TREE_OPERAND (type, 0);
4089 3173 : type = TREE_TYPE (DECL_NAME (type));
4090 :
4091 : /* TYPE can only be either T* or T&. We can't know which of these it
4092 : is by looking at TYPE, but OBJ will be "(T*) x" in the first case,
4093 : and something like "(T*)(T&)(T*) x" in the second case.
4094 : This is true for the reference cases in C++ < 26 or when exceptions
4095 : aren't enabled, in that case we should diagnose errors. For C++26
4096 : with exceptions we should silently evaluate to null pointer and
4097 : let the callers call __cxa_bad_cast () later to throw an exception. */
4098 3173 : bool fail_for_non_constant_p = false;
4099 12899 : while (CONVERT_EXPR_P (obj) || TREE_CODE (obj) == SAVE_EXPR)
4100 : {
4101 9726 : if (cxx_dialect < cxx26 || !flag_exceptions)
4102 5557 : fail_for_non_constant_p |= TYPE_REF_P (TREE_TYPE (obj));
4103 9726 : obj = TREE_OPERAND (obj, 0);
4104 : }
4105 :
4106 : /* Evaluate the object so that we know its dynamic type. */
4107 3173 : obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p,
4108 : overflow_p, jump_target);
4109 3173 : if (*non_constant_p)
4110 : return call;
4111 3054 : if (*jump_target)
4112 : return NULL_TREE;
4113 :
4114 : /* For dynamic_cast from classes with virtual bases we can get something
4115 : like (virt_base *)(&d + 16) as OBJ. Try to convert that into
4116 : d.D.1234 using cxx_fold_indirect_ref. */
4117 3054 : if (cxx_dialect >= cxx26 && CONVERT_EXPR_P (obj))
4118 : {
4119 1206 : tree objo = obj;
4120 1206 : STRIP_NOPS (objo);
4121 1206 : if (TREE_CODE (objo) == POINTER_PLUS_EXPR)
4122 : {
4123 1152 : objo = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (TREE_TYPE (obj)),
4124 : obj, NULL, jump_target);
4125 1152 : if (objo)
4126 1152 : obj = build_fold_addr_expr (objo);
4127 : }
4128 : }
4129 :
4130 : /* We expect OBJ to be in form of &d.D.2102 when HINT == 0,
4131 : but when HINT is > 0, it can also be something like
4132 : &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET. */
4133 3054 : obj = extract_obj_from_addr_offset (obj);
4134 3054 : const tree objtype = TREE_TYPE (obj);
4135 : /* If OBJ doesn't refer to a base field, we're done. */
4136 6029 : if (tree t = (TREE_CODE (obj) == COMPONENT_REF
4137 3054 : ? TREE_OPERAND (obj, 1) : obj))
4138 3054 : if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t))
4139 : {
4140 79 : if (fail_for_non_constant_p)
4141 : {
4142 55 : if (!ctx->quiet)
4143 : {
4144 2 : auto_diagnostic_group d;
4145 2 : error_at (loc, "reference %<dynamic_cast%> failed");
4146 2 : inform (loc, "dynamic type %qT of its operand does "
4147 : "not have a base class of type %qT",
4148 : objtype, type);
4149 2 : }
4150 55 : *non_constant_p = true;
4151 : }
4152 79 : return integer_zero_node;
4153 : }
4154 :
4155 : /* [class.cdtor] When a dynamic_cast is used in a constructor ...
4156 : or in a destructor ... if the operand of the dynamic_cast refers
4157 : to the object under construction or destruction, this object is
4158 : considered to be a most derived object that has the type of the
4159 : constructor or destructor's class. */
4160 2975 : tree vtable = build_vfield_ref (obj, objtype);
4161 2975 : vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue,
4162 : non_constant_p, overflow_p,
4163 : jump_target);
4164 2975 : if (*non_constant_p)
4165 : return call;
4166 2798 : if (*jump_target)
4167 : return NULL_TREE;
4168 : /* With -fsanitize=vptr, we initialize all vtable pointers to null,
4169 : so it's possible that we got a null pointer now. */
4170 2798 : if (integer_zerop (vtable))
4171 : {
4172 12 : if (!ctx->quiet)
4173 3 : error_at (loc, "virtual table pointer is used uninitialized");
4174 12 : *non_constant_p = true;
4175 12 : return integer_zero_node;
4176 : }
4177 : /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */
4178 2786 : vtable = extract_obj_from_addr_offset (vtable);
4179 2786 : const tree mdtype = DECL_CONTEXT (vtable);
4180 :
4181 : /* Given dynamic_cast<T>(v),
4182 :
4183 : [expr.dynamic.cast] If C is the class type to which T points or refers,
4184 : the runtime check logically executes as follows:
4185 :
4186 : If, in the most derived object pointed (referred) to by v, v points
4187 : (refers) to a public base class subobject of a C object, and if only
4188 : one object of type C is derived from the subobject pointed (referred)
4189 : to by v the result points (refers) to that C object.
4190 :
4191 : In this case, HINT >= 0 or -3. */
4192 2786 : if (hint >= 0 || hint == -3)
4193 : {
4194 : /* Look for a component with type TYPE. */
4195 687 : tree t = get_component_with_type (obj, type, mdtype);
4196 : /* If not accessible, give an error. */
4197 687 : if (t == error_mark_node)
4198 : {
4199 198 : if (fail_for_non_constant_p)
4200 : {
4201 108 : if (!ctx->quiet)
4202 : {
4203 12 : auto_diagnostic_group d;
4204 12 : error_at (loc, "reference %<dynamic_cast%> failed");
4205 12 : inform (loc, "static type %qT of its operand is a "
4206 : "non-public base class of dynamic type %qT",
4207 : objtype, type);
4208 :
4209 12 : }
4210 108 : *non_constant_p = true;
4211 : }
4212 198 : return integer_zero_node;
4213 : }
4214 489 : else if (t)
4215 : /* The result points to the TYPE object. */
4216 444 : return cp_build_addr_expr (t, complain);
4217 : /* Else, TYPE was not found, because the HINT turned out to be wrong.
4218 : Fall through to the normal processing. */
4219 : }
4220 :
4221 : /* Otherwise, if v points (refers) to a public base class subobject of the
4222 : most derived object, and the type of the most derived object has a base
4223 : class, of type C, that is unambiguous and public, the result points
4224 : (refers) to the C subobject of the most derived object.
4225 :
4226 : But it can also be an invalid case. */
4227 :
4228 : /* Get the most derived object. */
4229 2144 : obj = get_component_with_type (obj, mdtype, NULL_TREE);
4230 2144 : if (obj == error_mark_node)
4231 : {
4232 973 : if (fail_for_non_constant_p)
4233 : {
4234 350 : if (!ctx->quiet)
4235 : {
4236 38 : auto_diagnostic_group d;
4237 38 : error_at (loc, "reference %<dynamic_cast%> failed");
4238 38 : inform (loc, "static type %qT of its operand is a non-public"
4239 : " base class of dynamic type %qT", objtype, mdtype);
4240 38 : }
4241 350 : *non_constant_p = true;
4242 : }
4243 973 : return integer_zero_node;
4244 : }
4245 : else
4246 1171 : gcc_assert (obj);
4247 :
4248 : /* Check that the type of the most derived object has a base class
4249 : of type TYPE that is unambiguous and public. */
4250 1171 : base_kind b_kind;
4251 1171 : tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none);
4252 1171 : if (!binfo || binfo == error_mark_node)
4253 : {
4254 441 : if (fail_for_non_constant_p)
4255 : {
4256 134 : if (!ctx->quiet)
4257 : {
4258 16 : auto_diagnostic_group d;
4259 16 : error_at (loc, "reference %<dynamic_cast%> failed");
4260 16 : if (b_kind == bk_ambig)
4261 6 : inform (loc, "%qT is an ambiguous base class of dynamic "
4262 : "type %qT of its operand", type, mdtype);
4263 : else
4264 10 : inform (loc, "dynamic type %qT of its operand does not "
4265 : "have an unambiguous public base class %qT",
4266 : mdtype, type);
4267 16 : }
4268 134 : *non_constant_p = true;
4269 : }
4270 441 : return integer_zero_node;
4271 : }
4272 : /* If so, return the TYPE subobject of the most derived object. */
4273 730 : obj = convert_to_base_statically (obj, binfo);
4274 730 : return cp_build_addr_expr (obj, complain);
4275 : }
4276 :
4277 : /* Data structure used by replace_decl and replace_decl_r. */
4278 :
4279 : struct replace_decl_data
4280 : {
4281 : /* The _DECL we want to replace. */
4282 : tree decl;
4283 : /* The replacement for DECL. */
4284 : tree replacement;
4285 : /* Trees we've visited. */
4286 : hash_set<tree> *pset;
4287 : /* Whether we've performed any replacements. */
4288 : bool changed;
4289 : };
4290 :
4291 : /* Helper function for replace_decl, called through cp_walk_tree. */
4292 :
4293 : static tree
4294 17011384 : replace_decl_r (tree *tp, int *walk_subtrees, void *data)
4295 : {
4296 17011384 : replace_decl_data *d = (replace_decl_data *) data;
4297 :
4298 : /* We could be replacing
4299 : &<retval>.bar -> &foo.bar
4300 : where foo is a static VAR_DECL, so we need to recompute TREE_CONSTANT
4301 : on the ADDR_EXPR around it. */
4302 17011384 : if (TREE_CODE (*tp) == ADDR_EXPR)
4303 : {
4304 1528520 : d->pset->add (*tp);
4305 1528520 : auto save_changed = d->changed;
4306 1528520 : d->changed = false;
4307 1528520 : cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr);
4308 1528520 : if (d->changed)
4309 : {
4310 1855 : cxx_mark_addressable (*tp);
4311 1855 : recompute_tree_invariant_for_addr_expr (*tp);
4312 : }
4313 : else
4314 1526665 : d->changed = save_changed;
4315 1528520 : *walk_subtrees = 0;
4316 : }
4317 15482864 : else if (*tp == d->decl)
4318 : {
4319 2095 : *tp = unshare_expr (d->replacement);
4320 2095 : d->changed = true;
4321 2095 : *walk_subtrees = 0;
4322 : }
4323 15480769 : else if (TYPE_P (*tp)
4324 15480769 : || d->pset->add (*tp))
4325 2838257 : *walk_subtrees = 0;
4326 :
4327 17011384 : return NULL_TREE;
4328 : }
4329 :
4330 : /* Replace every occurrence of DECL with (an unshared copy of)
4331 : REPLACEMENT within the expression *TP. Returns true iff a
4332 : replacement was performed. */
4333 :
4334 : bool
4335 2266739 : replace_decl (tree *tp, tree decl, tree replacement)
4336 : {
4337 2266739 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
4338 : (TREE_TYPE (decl), TREE_TYPE (replacement)));
4339 2266739 : hash_set<tree> pset;
4340 2266739 : replace_decl_data data = { decl, replacement, &pset, false };
4341 2266739 : cp_walk_tree (tp, replace_decl_r, &data, NULL);
4342 2266739 : return data.changed;
4343 2266739 : }
4344 :
4345 : /* Evaluate the call T to virtual function thunk THUNK_FNDECL. */
4346 :
4347 : static tree
4348 44 : cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl,
4349 : value_cat lval,
4350 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
4351 : {
4352 44 : tree function = THUNK_TARGET (thunk_fndecl);
4353 :
4354 44 : if (THUNK_VIRTUAL_OFFSET (thunk_fndecl))
4355 : {
4356 13 : if (!ctx->quiet)
4357 : {
4358 3 : if (!DECL_DECLARED_CONSTEXPR_P (function))
4359 : {
4360 0 : error ("call to non-%<constexpr%> function %qD", function);
4361 0 : explain_invalid_constexpr_fn (function);
4362 : }
4363 : else
4364 : /* virtual_offset is only set for virtual bases, which make the
4365 : class non-literal, so we don't need to handle it here. */
4366 3 : error ("calling constexpr member function %qD through virtual "
4367 : "base subobject", function);
4368 : }
4369 13 : *non_constant_p = true;
4370 13 : return t;
4371 : }
4372 :
4373 31 : tree new_call = copy_node (t);
4374 31 : CALL_EXPR_FN (new_call) = function;
4375 31 : TREE_TYPE (new_call) = TREE_TYPE (TREE_TYPE (function));
4376 :
4377 31 : tree offset = size_int (THUNK_FIXED_OFFSET (thunk_fndecl));
4378 :
4379 31 : if (DECL_THIS_THUNK_P (thunk_fndecl))
4380 : {
4381 : /* 'this'-adjusting thunk. */
4382 19 : tree this_arg = CALL_EXPR_ARG (t, 0);
4383 19 : this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg),
4384 : this_arg, offset);
4385 19 : CALL_EXPR_ARG (new_call, 0) = this_arg;
4386 : }
4387 : else
4388 : {
4389 : /* Return-adjusting thunk. As in expand_thunk, adjust a pointer only
4390 : if it is non-null. */
4391 12 : tree call = new_call;
4392 12 : if (TYPE_PTR_P (TREE_TYPE (call)))
4393 12 : call = save_expr (call);
4394 12 : new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (call), call, offset);
4395 12 : if (TYPE_PTR_P (TREE_TYPE (call)))
4396 12 : new_call = build_if_nonnull (call, new_call, tf_none);
4397 : }
4398 :
4399 31 : tree result = cxx_eval_constant_expression (ctx, new_call, lval,
4400 : non_constant_p, overflow_p,
4401 : jump_target);
4402 31 : if (!*non_constant_p
4403 27 : && !*overflow_p
4404 27 : && !*jump_target
4405 27 : && result != void_node
4406 27 : && INDIRECT_TYPE_P (TREE_TYPE (t))
4407 55 : && !(same_type_ignoring_top_level_qualifiers_p
4408 24 : (TREE_TYPE (result), TREE_TYPE (t))))
4409 15 : result = adjust_temp_type (TREE_TYPE (t), result);
4410 : return result;
4411 : }
4412 :
4413 : /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set
4414 : its TREE_READONLY flag according to READONLY_P. Used for constexpr
4415 : 'tors to detect modifying const objects in a constexpr context. */
4416 :
4417 : static void
4418 11189455 : cxx_set_object_constness (const constexpr_ctx *ctx, tree object,
4419 : bool readonly_p, bool *non_constant_p,
4420 : bool *overflow_p, tree *jump_target)
4421 : {
4422 22378910 : if (CLASS_TYPE_P (TREE_TYPE (object))
4423 22378910 : && CP_TYPE_CONST_P (TREE_TYPE (object)))
4424 : {
4425 : /* Subobjects might not be stored in ctx->global->values but we
4426 : can get its CONSTRUCTOR by evaluating *this. */
4427 1045845 : tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue,
4428 : non_constant_p, overflow_p,
4429 : jump_target);
4430 1045845 : if (!*non_constant_p
4431 12192657 : && !throws (jump_target)
4432 2049047 : && TREE_CODE (e) == CONSTRUCTOR)
4433 1003202 : TREE_READONLY (e) = readonly_p;
4434 : }
4435 11189455 : }
4436 :
4437 : /* Allocate an exception for OBJECT and throw it. */
4438 :
4439 : tree
4440 3234 : cxa_allocate_and_throw_exception (location_t loc, const constexpr_ctx *ctx,
4441 : tree object)
4442 : {
4443 3234 : tree type = TREE_TYPE (object);
4444 : /* This simulates a call to __cxa_allocate_exception. We need
4445 : (struct exception *) &heap -- memory on the heap so that
4446 : it can survive the stack being unwound. */
4447 3234 : tree arr = build_array_of_n_type (type, 1);
4448 3234 : tree var = cxa_allocate_exception (loc, ctx, arr, size_zero_node);
4449 3234 : DECL_NAME (var) = heap_identifier;
4450 3234 : ctx->global->put_value (var, NULL_TREE);
4451 :
4452 : /* *(struct exception *) &heap = exc{ ... } */
4453 3234 : tree ptr = build_nop (build_pointer_type (type), build_address (var));
4454 3234 : object = cp_build_init_expr (cp_build_fold_indirect_ref (ptr), object);
4455 3234 : bool non_constant_p = false, overflow_p = false;
4456 3234 : tree jump_target = NULL_TREE;
4457 3234 : cxx_eval_constant_expression (ctx, object, vc_prvalue, &non_constant_p,
4458 : &overflow_p, &jump_target);
4459 3234 : if (non_constant_p)
4460 : {
4461 0 : if (!ctx->quiet)
4462 0 : error_at (loc, "couldn%'t throw %qT", type);
4463 : return NULL_TREE;
4464 : }
4465 :
4466 : /* Now we can __cxa_throw. */
4467 3234 : DECL_EXCEPTION_REFCOUNT (var)
4468 3234 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (var), size_one_node);
4469 3234 : ++ctx->global->uncaught_exceptions;
4470 :
4471 3234 : return var;
4472 : }
4473 :
4474 : /* Subroutine of cxx_eval_constant_expression.
4475 : Evaluate the call expression tree T in the context of OLD_CALL expression
4476 : evaluation. */
4477 :
4478 : static tree
4479 207853872 : cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
4480 : value_cat lval,
4481 : bool *non_constant_p, bool *overflow_p,
4482 : tree *jump_target)
4483 : {
4484 207853872 : location_t loc = cp_expr_loc_or_input_loc (t);
4485 207853872 : tree fun = get_function_named_in_call (t);
4486 :
4487 207853872 : if (fun == NULL_TREE)
4488 389025 : return cxx_eval_internal_function (ctx, t, lval,
4489 : non_constant_p, overflow_p,
4490 389025 : jump_target);
4491 :
4492 207464847 : if (TREE_CODE (fun) != FUNCTION_DECL)
4493 : {
4494 : /* Might be a constexpr function pointer. */
4495 420376 : fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue,
4496 : non_constant_p, overflow_p,
4497 : jump_target);
4498 420376 : if (*jump_target)
4499 : return NULL_TREE;
4500 420376 : STRIP_NOPS (fun);
4501 420376 : if (TREE_CODE (fun) == ADDR_EXPR)
4502 30588 : fun = TREE_OPERAND (fun, 0);
4503 : /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
4504 : indirection, the called expression is a pointer into the
4505 : virtual table which should contain FDESC_EXPR. Extract the
4506 : FUNCTION_DECL from there. */
4507 : else if (TARGET_VTABLE_USES_DESCRIPTORS
4508 : && TREE_CODE (fun) == POINTER_PLUS_EXPR
4509 : && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
4510 : && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
4511 : {
4512 : tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
4513 : if (VAR_P (d)
4514 : && DECL_VTABLE_OR_VTT_P (d)
4515 : && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
4516 : && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
4517 : && DECL_INITIAL (d)
4518 : && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
4519 : {
4520 : tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
4521 : TYPE_SIZE_UNIT (vtable_entry_type));
4522 : HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
4523 : if (idx >= 0)
4524 : {
4525 : tree fdesc
4526 : = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
4527 : if (TREE_CODE (fdesc) == FDESC_EXPR
4528 : && integer_zerop (TREE_OPERAND (fdesc, 1)))
4529 : fun = TREE_OPERAND (fdesc, 0);
4530 : }
4531 : }
4532 : }
4533 : }
4534 207464847 : if (TREE_CODE (fun) != FUNCTION_DECL)
4535 : {
4536 389788 : if (!ctx->quiet && !*non_constant_p)
4537 0 : error_at (loc, "expression %qE does not designate a %<constexpr%> "
4538 : "function", fun);
4539 389788 : *non_constant_p = true;
4540 389788 : return t;
4541 : }
4542 207075059 : tree orig_fun = fun;
4543 207075059 : if (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun))
4544 24633467 : fun = DECL_CLONED_FUNCTION (fun);
4545 :
4546 207075059 : if (is_ubsan_builtin_p (fun))
4547 58 : return void_node;
4548 :
4549 207075001 : if (fndecl_built_in_p (fun))
4550 20795617 : return cxx_eval_builtin_function_call (ctx, t, fun,
4551 : lval, non_constant_p, overflow_p,
4552 20795615 : jump_target);
4553 186279384 : if (DECL_THUNK_P (fun))
4554 44 : return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p,
4555 44 : jump_target);
4556 186279340 : if (metafunction_p (fun))
4557 : {
4558 : /* To be able to evaluate a metafunction, we may have to instantiate
4559 : constexpr functions. If we're not allowed to instantiate, leave
4560 : this for later. Don't evaluate metafunctions at all when mce_unknown,
4561 : otherwise we might fold those prematurely. See
4562 : g++.dg/reflect/p2996-17.C. */
4563 81717 : if (uid_sensitive_constexpr_evaluation_p ()
4564 81151 : || ctx->manifestly_const_eval == mce_unknown)
4565 : {
4566 21737 : *non_constant_p = true;
4567 21737 : return t;
4568 : }
4569 59980 : ctx->global->state_dependent = true;
4570 59980 : tree e = process_metafunction (ctx, fun, t, non_constant_p, overflow_p,
4571 : jump_target);
4572 59980 : if (*jump_target)
4573 : return NULL_TREE;
4574 56734 : if (*non_constant_p)
4575 : return t;
4576 55664 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
4577 : non_constant_p, overflow_p,
4578 : jump_target);
4579 55664 : if (*jump_target)
4580 : return NULL_TREE;
4581 55664 : if (*non_constant_p)
4582 : return t;
4583 55654 : return e;
4584 : }
4585 186197623 : bool non_constexpr_call = false;
4586 186197623 : if (!maybe_constexpr_fn (fun))
4587 : {
4588 905820 : if (TREE_CODE (t) == CALL_EXPR
4589 898195 : && cxx_replaceable_global_alloc_fn (fun)
4590 1570956 : && (CALL_FROM_NEW_OR_DELETE_P (t)
4591 329344 : || is_std_allocator_allocate_deallocate (ctx->call)))
4592 : {
4593 494640 : const bool new_op_p = IDENTIFIER_NEW_OP_P (DECL_NAME (fun));
4594 494640 : const int nargs = call_expr_nargs (t);
4595 494640 : tree arg0 = NULL_TREE;
4596 784173 : for (int i = 0; i < nargs; ++i)
4597 : {
4598 495709 : tree arg = CALL_EXPR_ARG (t, i);
4599 495709 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4600 : non_constant_p, overflow_p,
4601 : jump_target);
4602 495709 : if (*jump_target)
4603 : return NULL_TREE;
4604 : /* Deleting a non-constant pointer has a better error message
4605 : below. */
4606 495699 : if (new_op_p || i != 0)
4607 416590 : VERIFY_CONSTANT (arg);
4608 210424 : if (i == 0)
4609 : arg0 = arg;
4610 : }
4611 288464 : gcc_assert (arg0);
4612 288464 : if (new_op_p)
4613 : {
4614 209355 : if (!tree_fits_uhwi_p (arg0))
4615 : {
4616 : /* We should not get here; the VERIFY_CONSTANT above
4617 : should have already caught it. */
4618 0 : gcc_checking_assert (false);
4619 : if (!ctx->quiet)
4620 : error_at (loc, "cannot allocate array: size not constant");
4621 : *non_constant_p = true;
4622 : return t;
4623 : }
4624 418710 : tree type = build_array_type_nelts (char_type_node,
4625 209355 : tree_to_uhwi (arg0));
4626 209355 : tree var = build_decl (loc, VAR_DECL,
4627 209355 : (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4628 : & OVL_OP_FLAG_VEC)
4629 : ? heap_vec_uninit_identifier
4630 : : heap_uninit_identifier,
4631 209355 : type);
4632 209355 : DECL_ARTIFICIAL (var) = 1;
4633 209355 : ctx->global->heap_vars.safe_push (var);
4634 209355 : ctx->global->put_value (var, NULL_TREE);
4635 209355 : return fold_convert (ptr_type_node, build_address (var));
4636 : }
4637 : else
4638 : {
4639 79109 : STRIP_NOPS (arg0);
4640 79109 : if (TREE_CODE (arg0) == ADDR_EXPR
4641 79109 : && VAR_P (TREE_OPERAND (arg0, 0)))
4642 : {
4643 79109 : tree var = TREE_OPERAND (arg0, 0);
4644 79109 : if (DECL_NAME (var) == heap_uninit_identifier
4645 79109 : || DECL_NAME (var) == heap_identifier)
4646 : {
4647 78935 : if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4648 : & OVL_OP_FLAG_VEC)
4649 : {
4650 9 : if (!ctx->quiet)
4651 : {
4652 3 : auto_diagnostic_group d;
4653 3 : error_at (loc, "array deallocation of object "
4654 : "allocated with non-array "
4655 : "allocation");
4656 3 : inform (DECL_SOURCE_LOCATION (var),
4657 : "allocation performed here");
4658 3 : }
4659 9 : *non_constant_p = true;
4660 9 : return t;
4661 : }
4662 78926 : DECL_NAME (var) = heap_deleted_identifier;
4663 78926 : ctx->global->destroy_value (var);
4664 78926 : ctx->global->heap_dealloc_count++;
4665 78926 : return void_node;
4666 : }
4667 174 : else if (DECL_NAME (var) == heap_vec_uninit_identifier
4668 174 : || DECL_NAME (var) == heap_vec_identifier)
4669 : {
4670 150 : if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4671 : & OVL_OP_FLAG_VEC) == 0)
4672 : {
4673 9 : if (!ctx->quiet)
4674 : {
4675 3 : auto_diagnostic_group d;
4676 3 : error_at (loc, "non-array deallocation of "
4677 : "object allocated with array "
4678 : "allocation");
4679 3 : inform (DECL_SOURCE_LOCATION (var),
4680 : "allocation performed here");
4681 3 : }
4682 9 : *non_constant_p = true;
4683 9 : return t;
4684 : }
4685 141 : DECL_NAME (var) = heap_deleted_identifier;
4686 141 : ctx->global->destroy_value (var);
4687 141 : ctx->global->heap_dealloc_count++;
4688 141 : return void_node;
4689 : }
4690 24 : else if (DECL_NAME (var) == heap_deleted_identifier)
4691 : {
4692 15 : if (!ctx->quiet)
4693 6 : error_at (loc, "deallocation of already deallocated "
4694 : "storage");
4695 15 : *non_constant_p = true;
4696 15 : return t;
4697 : }
4698 : }
4699 9 : if (!ctx->quiet)
4700 3 : error_at (loc, "deallocation of storage that was "
4701 : "not previously allocated");
4702 9 : *non_constant_p = true;
4703 9 : return t;
4704 : }
4705 : }
4706 : /* Allow placement new in std::construct_at, just return the second
4707 : argument. */
4708 411180 : if (TREE_CODE (t) == CALL_EXPR
4709 403555 : && cxx_placement_new_fn (fun)
4710 592242 : && is_std_construct_at (ctx->call))
4711 : {
4712 45975 : const int nargs = call_expr_nargs (t);
4713 45975 : tree arg1 = NULL_TREE;
4714 137925 : for (int i = 0; i < nargs; ++i)
4715 : {
4716 91950 : tree arg = CALL_EXPR_ARG (t, i);
4717 91950 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4718 : non_constant_p, overflow_p,
4719 : jump_target);
4720 91950 : if (*jump_target)
4721 : return NULL_TREE;
4722 91950 : if (i == 1)
4723 : arg1 = arg;
4724 : else
4725 91950 : VERIFY_CONSTANT (arg);
4726 : }
4727 45975 : gcc_assert (arg1);
4728 : return arg1;
4729 : }
4730 365205 : else if (cxx_dynamic_cast_fn_p (fun))
4731 3173 : return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p,
4732 3173 : jump_target);
4733 362032 : else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun))
4734 28106 : return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun,
4735 : non_constant_p, overflow_p,
4736 28106 : jump_target);
4737 :
4738 : /* Calls to non-constexpr functions can be diagnosed right away
4739 : before C++26, though in C++26 evaluation of the arguments might
4740 : throw and if caught it could be still constant expression.
4741 : So for C++26 this is diagnosed only after
4742 : cxx_bind_parameters_in_call. */
4743 333926 : if (cxx_dialect >= cxx26)
4744 : non_constexpr_call = true;
4745 : else
4746 : {
4747 292919 : if (!ctx->quiet)
4748 : {
4749 208 : if (!lambda_static_thunk_p (fun))
4750 208 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4751 208 : explain_invalid_constexpr_fn (fun);
4752 : }
4753 292919 : *non_constant_p = true;
4754 292919 : return t;
4755 : }
4756 : }
4757 :
4758 185332810 : constexpr_ctx new_ctx = *ctx;
4759 185332810 : ctx = &new_ctx;
4760 208487791 : if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
4761 189335418 : && TREE_CODE (t) == AGGR_INIT_EXPR)
4762 : {
4763 : /* We want to have an initialization target for an AGGR_INIT_EXPR.
4764 : If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
4765 2828 : new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
4766 2828 : tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
4767 2828 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
4768 2828 : ctx->global->put_value (new_ctx.object, ctor);
4769 : }
4770 : /* An immediate invocation is manifestly constant evaluated including the
4771 : arguments of the call, so use mce_true even for the argument
4772 : evaluation. */
4773 370665620 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
4774 3466105 : new_ctx.manifestly_const_eval = mce_true;
4775 :
4776 : /* We used to shortcut trivial constructor/op= here, but nowadays
4777 : we can only get a trivial function here with -fno-elide-constructors. */
4778 185332946 : gcc_checking_assert (!trivial_fn_p (fun)
4779 : || !flag_elide_constructors
4780 : /* Or it's a call from maybe_thunk_body (111075). */
4781 : || (TREE_CODE (t) == CALL_EXPR ? CALL_FROM_THUNK_P (t)
4782 : : AGGR_INIT_FROM_THUNK_P (t))
4783 : /* We don't elide constructors when processing
4784 : a noexcept-expression. */
4785 : || cp_noexcept_operand);
4786 :
4787 185332810 : bool non_constant_args = false;
4788 185332810 : constexpr_call new_call;
4789 185332810 : new_call.bindings
4790 185332810 : = cxx_bind_parameters_in_call (ctx, t, fun, orig_fun, non_constant_p,
4791 : overflow_p, &non_constant_args,
4792 : jump_target);
4793 :
4794 : /* We build up the bindings list before we know whether we already have this
4795 : call cached. If we don't end up saving these bindings, ggc_free them when
4796 : this function exits. */
4797 185332810 : class free_bindings
4798 : {
4799 : tree *bindings;
4800 : public:
4801 185332810 : free_bindings (tree &b): bindings (&b) { }
4802 185332806 : ~free_bindings () { if (bindings) ggc_free (*bindings); }
4803 4675757 : void preserve () { bindings = NULL; }
4804 185332810 : } fb (new_call.bindings);
4805 :
4806 185332810 : if (*jump_target)
4807 : return NULL_TREE;
4808 185332726 : if (*non_constant_p)
4809 : return t;
4810 110707879 : if (non_constexpr_call)
4811 : {
4812 6432 : if (!ctx->quiet)
4813 : {
4814 436 : if (!lambda_static_thunk_p (fun))
4815 436 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4816 436 : explain_invalid_constexpr_fn (fun);
4817 : }
4818 6432 : *non_constant_p = true;
4819 6432 : return t;
4820 : }
4821 :
4822 : /* We can't defer instantiating the function any longer. */
4823 110701447 : if (!DECL_INITIAL (fun)
4824 3152424 : && (DECL_TEMPLOID_INSTANTIATION (fun) || DECL_DEFAULTED_FN (fun))
4825 110701447 : && !uid_sensitive_constexpr_evaluation_p ())
4826 : {
4827 2909860 : location_t save_loc = input_location;
4828 2909860 : input_location = loc;
4829 2909860 : ++function_depth;
4830 2909860 : if (ctx->manifestly_const_eval == mce_true)
4831 369208 : FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true;
4832 2909860 : if (DECL_TEMPLOID_INSTANTIATION (fun))
4833 2909846 : instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
4834 : else
4835 14 : synthesize_method (fun);
4836 2909860 : --function_depth;
4837 2909860 : input_location = save_loc;
4838 : }
4839 :
4840 : /* If in direct recursive call, optimize definition search. */
4841 110701447 : if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun)
4842 29287 : new_call.fundef = ctx->call->fundef;
4843 : else
4844 : {
4845 110672160 : new_call.fundef = retrieve_constexpr_fundef (fun);
4846 110672160 : if (new_call.fundef == NULL || new_call.fundef->body == NULL
4847 110099900 : || new_call.fundef->result == error_mark_node
4848 110084022 : || fun == current_function_decl)
4849 : {
4850 588144 : if (!ctx->quiet)
4851 : {
4852 : /* We need to check for current_function_decl here in case we're
4853 : being called during cp_fold_function, because at that point
4854 : DECL_INITIAL is set properly and we have a fundef but we
4855 : haven't lowered invisirefs yet (c++/70344). */
4856 187 : if (DECL_INITIAL (fun) == error_mark_node
4857 187 : || fun == current_function_decl)
4858 15 : error_at (loc, "%qD called in a constant expression before its "
4859 : "definition is complete", fun);
4860 172 : else if (DECL_INITIAL (fun))
4861 : {
4862 : /* The definition of fun was somehow unsuitable. But pretend
4863 : that lambda static thunks don't exist. */
4864 134 : if (!lambda_static_thunk_p (fun))
4865 122 : error_at (loc, "%qD called in a constant expression", fun);
4866 134 : explain_invalid_constexpr_fn (fun);
4867 : }
4868 : else
4869 38 : error_at (loc, "%qD used before its definition", fun);
4870 : }
4871 588144 : *non_constant_p = true;
4872 588144 : return t;
4873 : }
4874 : }
4875 :
4876 : /* Don't complain about problems evaluating an ill-formed function. */
4877 110113303 : if (function *f = DECL_STRUCT_FUNCTION (fun))
4878 110113303 : if (f->language->erroneous)
4879 978 : new_ctx.quiet = true;
4880 :
4881 110113303 : int depth_ok = push_cx_call_context (t);
4882 :
4883 : /* Remember the object we are constructing or destructing. */
4884 110113303 : tree new_obj = NULL_TREE;
4885 220226606 : if (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))
4886 : {
4887 : /* In a cdtor, it should be the first `this' argument.
4888 : At this point it has already been evaluated in the call
4889 : to cxx_bind_parameters_in_call. */
4890 13826987 : new_obj = TREE_VEC_ELT (new_call.bindings, 0);
4891 13826987 : bool empty_base = false;
4892 13826987 : new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj,
4893 : &empty_base, jump_target);
4894 13826987 : if (*jump_target)
4895 0 : return NULL_TREE;
4896 : /* If we're initializing an empty class, don't set constness, because
4897 : cxx_fold_indirect_ref will return the wrong object to set constness
4898 : of. */
4899 13826987 : if (empty_base)
4900 : new_obj = NULL_TREE;
4901 6893932 : else if (ctx->call && ctx->call->fundef
4902 25035394 : && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl))
4903 : {
4904 3612821 : tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0);
4905 3612821 : STRIP_NOPS (cur_obj);
4906 3612821 : if (TREE_CODE (cur_obj) == ADDR_EXPR)
4907 3610338 : cur_obj = TREE_OPERAND (cur_obj, 0);
4908 3612821 : if (new_obj == cur_obj)
4909 : /* We're calling the target constructor of a delegating
4910 : constructor, or accessing a base subobject through a
4911 : NOP_EXPR as part of a call to a base constructor, so
4912 : there is no new (sub)object. */
4913 13826987 : new_obj = NULL_TREE;
4914 : }
4915 : }
4916 :
4917 110113303 : tree result = NULL_TREE;
4918 :
4919 110113303 : constexpr_call *entry = NULL;
4920 110113303 : if (depth_ok && !non_constant_args && ctx->strict)
4921 : {
4922 37135456 : new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
4923 37135456 : new_call.hash
4924 37135456 : = iterative_hash_template_arg (new_call.bindings, new_call.hash);
4925 :
4926 : /* If we have seen this call before, we are done. */
4927 37135456 : maybe_initialize_constexpr_call_table ();
4928 37135456 : bool insert = depth_ok < constexpr_cache_depth;
4929 37135456 : constexpr_call **slot
4930 50499326 : = constexpr_call_table->find_slot (&new_call,
4931 : insert ? INSERT : NO_INSERT);
4932 37135456 : entry = slot ? *slot : NULL;
4933 32581062 : if (entry == NULL)
4934 : {
4935 : /* Only cache up to constexpr_cache_depth to limit memory use. */
4936 9230151 : if (insert)
4937 : {
4938 : /* We need to keep a pointer to the entry, not just the slot, as
4939 : the slot can move during evaluation of the body. */
4940 4675757 : *slot = entry = ggc_alloc<constexpr_call> ();
4941 4675757 : *entry = new_call;
4942 4675757 : entry->result (ctx->manifestly_const_eval) = unknown_type_node;
4943 4675757 : fb.preserve ();
4944 :
4945 : /* Unshare args going into the hash table to separate them
4946 : from the caller's context, for better GC and to avoid
4947 : problems with verify_gimple. */
4948 4675757 : tree bound = new_call.bindings;
4949 7562233 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
4950 : {
4951 2886476 : tree &arg = TREE_VEC_ELT (bound, i);
4952 2886476 : arg = unshare_expr_without_location (arg);
4953 : }
4954 : }
4955 : }
4956 : /* Calls that are in progress have their result set to unknown_type_node,
4957 : so that we can detect circular dependencies. Now that we only cache
4958 : up to constexpr_cache_depth this won't catch circular dependencies that
4959 : start deeper, but they'll hit the recursion or ops limit. */
4960 27905305 : else if (entry->result (ctx->manifestly_const_eval) == unknown_type_node)
4961 : {
4962 6 : if (!ctx->quiet)
4963 0 : error ("call has circular dependency");
4964 6 : *non_constant_p = true;
4965 6 : entry->result (ctx->manifestly_const_eval) = result = error_mark_node;
4966 : }
4967 : else
4968 27905299 : result = entry->result (ctx->manifestly_const_eval);
4969 : }
4970 :
4971 110113270 : if (!depth_ok)
4972 : {
4973 33 : if (!ctx->quiet)
4974 3 : error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
4975 : "%<-fconstexpr-depth=%> to increase the maximum)",
4976 : max_constexpr_depth);
4977 33 : *non_constant_p = true;
4978 33 : result = error_mark_node;
4979 : }
4980 : else
4981 : {
4982 110113270 : bool cacheable = !!entry;
4983 110113270 : if (result && result != error_mark_node)
4984 : /* OK */;
4985 87356815 : else if (!DECL_SAVED_TREE (fun))
4986 : {
4987 : /* When at_eof >= 3, cgraph has started throwing away
4988 : DECL_SAVED_TREE, so fail quietly. FIXME we get here because of
4989 : late code generation for VEC_INIT_EXPR, which needs to be
4990 : completely reconsidered. */
4991 0 : gcc_assert (at_eof >= 3 && ctx->quiet);
4992 0 : *non_constant_p = true;
4993 : }
4994 87356815 : else if (tree copy = get_fundef_copy (new_call.fundef))
4995 : {
4996 87356806 : tree body, parms, res;
4997 87356806 : releasing_vec ctors;
4998 :
4999 : /* Reuse or create a new unshared copy of this function's body. */
5000 87356806 : body = TREE_PURPOSE (copy);
5001 87356806 : parms = TREE_VALUE (copy);
5002 87356806 : res = TREE_TYPE (copy);
5003 :
5004 : /* Associate the bindings with the remapped parms. */
5005 87356806 : tree bound = new_call.bindings;
5006 87356806 : tree remapped = parms;
5007 214002208 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
5008 : {
5009 126645402 : tree arg = TREE_VEC_ELT (bound, i);
5010 126645402 : if (entry)
5011 : {
5012 : /* Unshare again so the callee doesn't change the
5013 : argument values in the hash table. XXX Could we unshare
5014 : lazily in cxx_eval_store_expression? */
5015 3127734 : arg = unshare_constructor (arg);
5016 3127734 : if (TREE_CODE (arg) == CONSTRUCTOR)
5017 883592 : vec_safe_push (ctors, arg);
5018 : }
5019 126645402 : ctx->global->put_value (remapped, arg);
5020 126645402 : remapped = DECL_CHAIN (remapped);
5021 : }
5022 87356806 : if (remapped)
5023 : {
5024 : /* We shouldn't have any parms without args, but fail gracefully
5025 : in error recovery. */
5026 6 : gcc_checking_assert (seen_error ());
5027 6 : *non_constant_p = true;
5028 : }
5029 : /* Add the RESULT_DECL to the values map, too. */
5030 87356806 : gcc_assert (!DECL_BY_REFERENCE (res));
5031 87356806 : ctx->global->put_value (res, NULL_TREE);
5032 :
5033 : /* Remember the current call we're evaluating. */
5034 87356806 : constexpr_ctx call_ctx = *ctx;
5035 87356806 : call_ctx.call = &new_call;
5036 87356806 : unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
5037 87356806 : unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
5038 87356806 : bool save_state_dependent = ctx->global->state_dependent;
5039 :
5040 : /* Make sure we fold std::is_constant_evaluated to true in an
5041 : immediate function. */
5042 174713612 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
5043 1454227 : call_ctx.manifestly_const_eval = mce_true;
5044 :
5045 : /* If this is a constexpr destructor, the object's const and volatile
5046 : semantics are no longer in effect; see [class.dtor]p5. */
5047 98546261 : if (new_obj && DECL_DESTRUCTOR_P (fun))
5048 1242276 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false,
5049 : non_constant_p, overflow_p, jump_target);
5050 :
5051 : /* If this is a constructor, we are beginning the lifetime of the
5052 : object we are initializing. */
5053 87356806 : if (new_obj
5054 22378910 : && DECL_CONSTRUCTOR_P (fun)
5055 9947179 : && TREE_CODE (new_obj) == COMPONENT_REF
5056 90195664 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE)
5057 : {
5058 8932 : tree ctor = build_constructor (TREE_TYPE (new_obj), NULL);
5059 8932 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
5060 8932 : tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj),
5061 : new_obj, ctor);
5062 8932 : cxx_eval_constant_expression (ctx, activate,
5063 : lval, non_constant_p, overflow_p,
5064 : jump_target);
5065 8932 : ggc_free (activate);
5066 8932 : if (*jump_target)
5067 0 : return NULL_TREE;
5068 : }
5069 :
5070 87356806 : ctx->global->state_dependent = false;
5071 :
5072 87356806 : tree jmp_target = NULL_TREE;
5073 87356806 : cxx_eval_constant_expression (&call_ctx, body,
5074 : vc_discard, non_constant_p, overflow_p,
5075 : &jmp_target);
5076 :
5077 87356802 : if (!*non_constant_p && throws (&jmp_target))
5078 : {
5079 3683 : result = NULL_TREE;
5080 3683 : cacheable = false;
5081 3683 : *jump_target = jmp_target;
5082 : }
5083 87353119 : else if (!*non_constant_p && TREE_THIS_VOLATILE (fun))
5084 : {
5085 : /* Return from a [[noreturn]] function. */
5086 11 : if (!ctx->quiet)
5087 5 : error ("%<[[noreturn]]%> call returns");
5088 11 : *non_constant_p = true;
5089 : }
5090 174706216 : else if (DECL_CONSTRUCTOR_P (fun))
5091 : /* This can be null for a subobject constructor call, in
5092 : which case what we care about is the initialization
5093 : side-effects rather than the value. We could get at the
5094 : value by evaluating *this, but we don't bother; there's
5095 : no need to put such a call in the hash table. */
5096 12417029 : result = lval ? ctx->object : ctx->ctor;
5097 74936079 : else if (VOID_TYPE_P (TREE_TYPE (res)))
5098 7339144 : result = void_node;
5099 : else
5100 : {
5101 67596935 : result = ctx->global->get_value (res);
5102 11014318 : if (result == NULL_TREE && !*non_constant_p
5103 67597155 : && !DECL_DESTRUCTOR_P (fun))
5104 : {
5105 110 : if (!ctx->quiet)
5106 6 : error ("%<constexpr%> call flows off the end "
5107 : "of the function");
5108 110 : *non_constant_p = true;
5109 : }
5110 : }
5111 :
5112 87356802 : if (ctx->global->state_dependent)
5113 59921 : cacheable = false;
5114 87356802 : ctx->global->state_dependent |= save_state_dependent;
5115 :
5116 : /* At this point, the object's constructor will have run, so
5117 : the object is no longer under construction, and its possible
5118 : 'const' semantics now apply. Make a note of this fact by
5119 : marking the CONSTRUCTOR TREE_READONLY. */
5120 98546257 : if (new_obj && DECL_CONSTRUCTOR_P (fun))
5121 9947179 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true,
5122 : non_constant_p, overflow_p, jump_target);
5123 :
5124 : /* Remove the parms/result from the values map. */
5125 87356802 : destroy_value_checked (ctx, res, non_constant_p);
5126 301359010 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
5127 126645406 : destroy_value_checked (ctx, parm, non_constant_p);
5128 :
5129 : /* Free any parameter CONSTRUCTORs we aren't returning directly. */
5130 88240394 : while (!ctors->is_empty ())
5131 : {
5132 883592 : tree c = ctors->pop ();
5133 883592 : if (c != result)
5134 883592 : free_constructor (c);
5135 : }
5136 :
5137 : /* Make the unshared function copy we used available for re-use. */
5138 87356802 : save_fundef_copy (fun, copy);
5139 :
5140 : /* If the call allocated some heap object that hasn't been
5141 : deallocated during the call, or if it deallocated some heap
5142 : object it has not allocated, the call isn't really stateless
5143 : for the constexpr evaluation and should not be cached.
5144 : It is fine if the call allocates something and deallocates it
5145 : too. */
5146 87356802 : if (cacheable
5147 97176461 : && (save_heap_alloc_count != ctx->global->heap_vars.length ()
5148 9815158 : || (save_heap_dealloc_count
5149 9815158 : != ctx->global->heap_dealloc_count)))
5150 : {
5151 4501 : tree heap_var;
5152 4501 : unsigned int i;
5153 4501 : if ((ctx->global->heap_vars.length ()
5154 4501 : - ctx->global->heap_dealloc_count)
5155 4501 : != save_heap_alloc_count - save_heap_dealloc_count)
5156 : cacheable = false;
5157 : else
5158 139075 : FOR_EACH_VEC_ELT_FROM (ctx->global->heap_vars, i, heap_var,
5159 : save_heap_alloc_count)
5160 136450 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
5161 : {
5162 : cacheable = false;
5163 : break;
5164 : }
5165 : }
5166 :
5167 : /* Rewrite all occurrences of the function's RESULT_DECL with the
5168 : current object under construction. */
5169 87356802 : if (!*non_constant_p
5170 72630147 : && ctx->object
5171 17232449 : && CLASS_TYPE_P (TREE_TYPE (res))
5172 90551199 : && !is_empty_class (TREE_TYPE (res)))
5173 : {
5174 2266593 : if (!same_type_ignoring_top_level_qualifiers_p
5175 2266593 : (TREE_TYPE (res), TREE_TYPE (ctx->object)))
5176 0 : *non_constant_p = true;
5177 2266593 : else if (replace_decl (&result, res, ctx->object))
5178 : {
5179 1791 : cacheable = false;
5180 1791 : result = cxx_eval_constant_expression (ctx, result, lval,
5181 : non_constant_p,
5182 : overflow_p,
5183 : jump_target);
5184 1791 : if (*jump_target)
5185 : {
5186 0 : cacheable = false;
5187 0 : result = NULL_TREE;
5188 : }
5189 : }
5190 : }
5191 :
5192 : /* Only cache a permitted result of a constant expression. */
5193 87355011 : if (cacheable && !reduced_constant_expression_p (result))
5194 : cacheable = false;
5195 :
5196 : /* Only cache a result without contract violations. */
5197 82299541 : if (cacheable && ctx->global->contract_statement)
5198 82596769 : cacheable = false;
5199 87356802 : }
5200 : else
5201 : /* Couldn't get a function copy to evaluate. */
5202 9 : *non_constant_p = true;
5203 :
5204 110113266 : if (result == error_mark_node)
5205 6 : *non_constant_p = true;
5206 110113266 : if (*non_constant_p || *overflow_p)
5207 14726820 : result = error_mark_node;
5208 95386446 : else if (!result)
5209 3959716 : result = void_node;
5210 110113266 : if (entry)
5211 : {
5212 65162120 : entry->result (ctx->manifestly_const_eval)
5213 32581060 : = cacheable ? result : error_mark_node;
5214 :
5215 32581060 : if (result != error_mark_node
5216 27590325 : && ctx->manifestly_const_eval == mce_unknown)
5217 : {
5218 : /* Evaluation succeeded and was independent of whether we're in a
5219 : manifestly constant-evaluated context, so we can also reuse
5220 : this result when evaluating this call with a fixed context. */
5221 1931203 : if (!entry->result (mce_true))
5222 717217 : entry->result (mce_true) = entry->result (mce_unknown);
5223 1931203 : if (!entry->result (mce_false))
5224 684004 : entry->result (mce_false) = entry->result (mce_unknown);
5225 : }
5226 : }
5227 : }
5228 :
5229 : /* The result of a constexpr function must be completely initialized.
5230 :
5231 : However, in C++20, a constexpr constructor doesn't necessarily have
5232 : to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
5233 : in order to detect reading an uninitialized object in constexpr instead
5234 : of value-initializing it. (reduced_constant_expression_p is expected to
5235 : take care of clearing the flag.) */
5236 110113299 : if (TREE_CODE (result) == CONSTRUCTOR
5237 110113299 : && (cxx_dialect < cxx20
5238 21493212 : || !DECL_CONSTRUCTOR_P (fun)))
5239 5271200 : clear_no_implicit_zero (result);
5240 :
5241 110113299 : pop_cx_call_context ();
5242 :
5243 : /* A virtual call with a zero-offset covariant return needs no thunk, so
5244 : constant evaluation can evaluate the final overrider directly. The
5245 : result then has the overrider's return type rather than the static type
5246 : of the call. Adjust after caching so a direct call can reuse the result
5247 : with its original type. */
5248 110113299 : if (!*non_constant_p
5249 95386602 : && !*overflow_p
5250 95386446 : && !*jump_target
5251 95382763 : && DECL_VIRTUAL_P (fun)
5252 26597 : && result != void_node
5253 2209 : && INDIRECT_TYPE_P (TREE_TYPE (t))
5254 110114344 : && !(same_type_ignoring_top_level_qualifiers_p
5255 1045 : (TREE_TYPE (result), TREE_TYPE (t))))
5256 11 : result = adjust_temp_type (TREE_TYPE (t), result);
5257 :
5258 110113299 : return result;
5259 185332806 : }
5260 :
5261 : /* Return true if T is a valid constant initializer. If a CONSTRUCTOR
5262 : initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
5263 : cleared. If called recursively on a FIELD_DECL's CONSTRUCTOR, SZ
5264 : is DECL_SIZE of the FIELD_DECL, otherwise NULL.
5265 : UNION_ELEMENTAL_SUBOBJECT is true when recursing on union elemental
5266 : subobjects.
5267 : FIXME speed this up, it's taking 16% of compile time on sieve testcase. */
5268 :
5269 : bool
5270 1253773942 : reduced_constant_expression_p (tree t, tree sz /* = NULL_TREE */,
5271 : bool union_elemental_subobject /* = false */)
5272 : {
5273 1253773942 : if (t == NULL_TREE)
5274 : return false;
5275 :
5276 1248788621 : switch (TREE_CODE (t))
5277 : {
5278 : case PTRMEM_CST:
5279 : case REFLECT_EXPR:
5280 : /* Even if we can't lower this yet, it's constant. */
5281 : return true;
5282 :
5283 : case OMP_DECLARE_MAPPER:
5284 : return true;
5285 :
5286 64395236 : case CONSTRUCTOR:
5287 : /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
5288 64395236 : tree field;
5289 64395236 : if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
5290 : /* A constant vector would be folded to VECTOR_CST.
5291 : A CONSTRUCTOR of scalar type means uninitialized. */
5292 : return false;
5293 64378657 : if (CONSTRUCTOR_NO_CLEARING (t))
5294 : {
5295 3521376 : if (union_elemental_subobject
5296 5262 : && cxx_dialect >= cxx26
5297 1955 : && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
5298 3522578 : && CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (t))
5299 : field = NULL_TREE;
5300 3521008 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
5301 : {
5302 : /* There must be a valid constant initializer at every array
5303 : index. */
5304 6125 : tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
5305 6125 : tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
5306 6125 : tree cursor = min;
5307 96909 : for (auto &e: CONSTRUCTOR_ELTS (t))
5308 : {
5309 78753 : if (!reduced_constant_expression_p
5310 78753 : (e.value, NULL_TREE, union_elemental_subobject))
5311 : return false;
5312 78594 : if (array_index_cmp (cursor, e.index) != 0)
5313 : return false;
5314 78534 : if (TREE_CODE (e.index) == RANGE_EXPR)
5315 0 : cursor = TREE_OPERAND (e.index, 1);
5316 78534 : if (TREE_CODE (e.value) == RAW_DATA_CST)
5317 0 : cursor
5318 0 : = int_const_binop (PLUS_EXPR, cursor,
5319 0 : size_int (RAW_DATA_LENGTH (e.value)));
5320 : else
5321 78534 : cursor = int_const_binop (PLUS_EXPR, cursor,
5322 78534 : size_one_node);
5323 : }
5324 5906 : if (find_array_ctor_elt (t, max) == -1)
5325 : return false;
5326 5635 : goto ok;
5327 : }
5328 3514883 : else if (cxx_dialect >= cxx20
5329 3514883 : && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
5330 : {
5331 : /* A union can have at most one active member. A union with no
5332 : active member has no constituent values, so all constituent
5333 : values are constant. */
5334 : field = NULL_TREE;
5335 : union_elemental_subobject = true;
5336 : }
5337 : else
5338 : {
5339 3511307 : field = next_subobject_field (TYPE_FIELDS (TREE_TYPE (t)));
5340 3511307 : union_elemental_subobject = false;
5341 : }
5342 : }
5343 : else
5344 : {
5345 60857281 : field = NULL_TREE;
5346 60857281 : if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
5347 : union_elemental_subobject = true;
5348 59896592 : else if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE)
5349 57023016 : union_elemental_subobject = false;
5350 : }
5351 606113161 : for (auto &e: CONSTRUCTOR_ELTS (t))
5352 : {
5353 : /* If VAL is null, we're in the middle of initializing this
5354 : element. */
5355 473343212 : if (!reduced_constant_expression_p (e.value,
5356 473343212 : (e.index
5357 473343176 : && (TREE_CODE (e.index)
5358 : == FIELD_DECL))
5359 59804400 : ? DECL_SIZE (e.index)
5360 : : NULL_TREE,
5361 : union_elemental_subobject))
5362 : return false;
5363 : /* We want to remove initializers for empty fields in a struct to
5364 : avoid confusing output_constructor. */
5365 472764366 : if (is_empty_field (e.index)
5366 472764366 : && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
5367 : return false;
5368 : /* Check for non-empty fields between initialized fields when
5369 : CONSTRUCTOR_NO_CLEARING. */
5370 471635916 : for (; field && e.index != field;
5371 385219 : field = next_subobject_field (DECL_CHAIN (field)))
5372 389995 : if (!is_really_empty_class (TREE_TYPE (field),
5373 : /*ignore_vptr*/false))
5374 : return false;
5375 471245921 : if (field)
5376 4001078 : field = next_subobject_field (DECL_CHAIN (field));
5377 : }
5378 : /* There could be a non-empty field at the end. */
5379 62564735 : for (; field; field = next_subobject_field (DECL_CHAIN (field)))
5380 296314 : if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false))
5381 : {
5382 : /* Ignore FIELD_DECLs with bit positions beyond DECL_SIZE of
5383 : the parent FIELD_DECL (if any) for classes with virtual
5384 : bases. */
5385 6820 : if (cxx_dialect >= cxx26
5386 4339 : && sz
5387 7342 : && tree_int_cst_le (sz, bit_position (field)))
5388 : break;
5389 : return false;
5390 : }
5391 62268421 : ok:
5392 62274448 : if (CONSTRUCTOR_NO_CLEARING (t))
5393 : /* All the fields are initialized. */
5394 3387693 : CONSTRUCTOR_NO_CLEARING (t) = false;
5395 : return true;
5396 :
5397 1184124068 : default:
5398 : /* FIXME are we calling this too much? */
5399 1184124068 : return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
5400 : }
5401 : }
5402 :
5403 : /* *TP was not deemed constant by reduced_constant_expression_p. Explain
5404 : why and suggest what could be done about it. */
5405 :
5406 : static tree
5407 1608 : verify_constant_explain_r (tree *tp, int *walk_subtrees, void *)
5408 : {
5409 1608 : bool ref_p = false;
5410 :
5411 : /* No need to look into types or unevaluated operands. */
5412 1608 : if (TYPE_P (*tp) || unevaluated_p (TREE_CODE (*tp)))
5413 : {
5414 0 : *walk_subtrees = false;
5415 0 : return NULL_TREE;
5416 : }
5417 :
5418 1608 : switch (TREE_CODE (*tp))
5419 : {
5420 106 : CASE_CONVERT:
5421 106 : if (TREE_CODE (TREE_OPERAND (*tp, 0)) != ADDR_EXPR)
5422 : break;
5423 87 : ref_p = TYPE_REF_P (TREE_TYPE (*tp));
5424 87 : *tp = TREE_OPERAND (*tp, 0);
5425 219 : gcc_fallthrough ();
5426 219 : case ADDR_EXPR:
5427 219 : {
5428 219 : tree op = TREE_OPERAND (*tp, 0);
5429 219 : if (VAR_P (op)
5430 118 : && DECL_DECLARED_CONSTEXPR_P (op)
5431 41 : && !TREE_STATIC (op)
5432 : /* ??? We should also say something about temporaries. */
5433 257 : && !DECL_ARTIFICIAL (op))
5434 : {
5435 33 : if (ref_p)
5436 12 : inform (location_of (*tp), "reference to %qD is not a constant "
5437 : "expression", op);
5438 : else
5439 21 : inform (location_of (*tp), "pointer to %qD is not a constant "
5440 : "expression", op);
5441 33 : const location_t op_loc = DECL_SOURCE_LOCATION (op);
5442 33 : rich_location richloc (line_table, op_loc);
5443 33 : richloc.add_fixit_insert_before (op_loc, "static ");
5444 33 : inform (&richloc,
5445 : "address of non-static constexpr variable %qD may differ on "
5446 : "each invocation of the enclosing function; add %<static%> "
5447 : "to give it a constant address", op);
5448 33 : }
5449 : break;
5450 : }
5451 : default:
5452 : break;
5453 : }
5454 :
5455 : return NULL_TREE;
5456 : }
5457 :
5458 : /* Some expressions may have constant operands but are not constant
5459 : themselves, such as 1/0. Call this function to check for that
5460 : condition.
5461 :
5462 : We only call this in places that require an arithmetic constant, not in
5463 : places where we might have a non-constant expression that can be a
5464 : component of a constant expression, such as the address of a constexpr
5465 : variable that might be dereferenced later. */
5466 :
5467 : static bool
5468 678401068 : verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
5469 : bool *overflow_p)
5470 : {
5471 665339503 : if (!*non_constant_p && !reduced_constant_expression_p (t)
5472 681348150 : && t != void_node)
5473 : {
5474 2946636 : if (!allow_non_constant)
5475 : {
5476 424 : auto_diagnostic_group d;
5477 581 : error_at (cp_expr_loc_or_input_loc (t),
5478 : "%q+E is not a constant expression", t);
5479 424 : cp_walk_tree_without_duplicates (&t, verify_constant_explain_r,
5480 : nullptr);
5481 424 : }
5482 2946636 : *non_constant_p = true;
5483 : }
5484 678401068 : if (TREE_OVERFLOW_P (t))
5485 : {
5486 678 : if (!allow_non_constant)
5487 : {
5488 155 : permerror (input_location, "overflow in constant expression");
5489 : /* If we're being permissive (and are in an enforcing
5490 : context), ignore the overflow. */
5491 155 : if (flag_permissive)
5492 75 : return *non_constant_p;
5493 : }
5494 603 : *overflow_p = true;
5495 : }
5496 678400993 : return *non_constant_p;
5497 : }
5498 :
5499 : /* Check whether the shift operation with code CODE and type TYPE on LHS
5500 : and RHS is undefined. If it is, give an error with an explanation,
5501 : and return true; return false otherwise. */
5502 :
5503 : static bool
5504 80692572 : cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
5505 : enum tree_code code, tree type, tree lhs, tree rhs)
5506 : {
5507 80692572 : if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
5508 5587963 : || TREE_CODE (lhs) != INTEGER_CST
5509 5587687 : || TREE_CODE (rhs) != INTEGER_CST)
5510 : return false;
5511 :
5512 5587687 : tree lhstype = TREE_TYPE (lhs);
5513 5587687 : unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
5514 :
5515 : /* [expr.shift] The behavior is undefined if the right operand
5516 : is negative, or greater than or equal to the length in bits
5517 : of the promoted left operand. */
5518 5587687 : if (tree_int_cst_sgn (rhs) == -1)
5519 : {
5520 126 : if (!ctx->quiet)
5521 35 : permerror (loc, "right operand of shift expression %q+E is negative",
5522 : build2_loc (loc, code, type, lhs, rhs));
5523 126 : return (!flag_permissive || ctx->quiet);
5524 : }
5525 5587561 : if (compare_tree_int (rhs, uprec) >= 0)
5526 : {
5527 200 : if (!ctx->quiet)
5528 34 : permerror (loc, "right operand of shift expression %q+E is greater "
5529 : "than or equal to the precision %wu of the left operand",
5530 : build2_loc (loc, code, type, lhs, rhs), uprec);
5531 200 : return (!flag_permissive || ctx->quiet);
5532 : }
5533 :
5534 : /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
5535 : if E1 has a signed type and non-negative value, and E1x2^E2 is
5536 : representable in the corresponding unsigned type of the result type,
5537 : then that value, converted to the result type, is the resulting value;
5538 : otherwise, the behavior is undefined.
5539 : For C++20:
5540 : The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
5541 : 2^N, where N is the range exponent of the type of the result. */
5542 5587361 : if (code == LSHIFT_EXPR
5543 4671522 : && !TYPE_OVERFLOW_WRAPS (lhstype)
5544 2214652 : && cxx_dialect >= cxx11
5545 7781962 : && cxx_dialect < cxx20)
5546 : {
5547 54040 : if (tree_int_cst_sgn (lhs) == -1)
5548 : {
5549 74 : if (!ctx->quiet)
5550 18 : permerror (loc,
5551 : "left operand of shift expression %q+E is negative",
5552 : build2_loc (loc, code, type, lhs, rhs));
5553 74 : return (!flag_permissive || ctx->quiet);
5554 : }
5555 : /* For signed x << y the following:
5556 : (unsigned) x >> ((prec (lhs) - 1) - y)
5557 : if > 1, is undefined. The right-hand side of this formula
5558 : is the highest bit of the LHS that can be set (starting from 0),
5559 : so that the shift doesn't overflow. We then right-shift the LHS
5560 : to see whether any other bit is set making the original shift
5561 : undefined -- the result is not representable in the corresponding
5562 : unsigned type. */
5563 53966 : tree t = build_int_cst (unsigned_type_node, uprec - 1);
5564 53966 : t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
5565 53966 : tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
5566 53966 : t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
5567 53966 : if (tree_int_cst_lt (integer_one_node, t))
5568 : {
5569 41 : if (!ctx->quiet)
5570 7 : permerror (loc, "shift expression %q+E overflows",
5571 : build2_loc (loc, code, type, lhs, rhs));
5572 41 : return (!flag_permissive || ctx->quiet);
5573 : }
5574 : }
5575 : return false;
5576 : }
5577 :
5578 : /* Subroutine of cxx_eval_constant_expression.
5579 : Attempt to reduce the unary expression tree T to a compile time value.
5580 : If successful, return the value. Otherwise issue a diagnostic
5581 : and return error_mark_node. */
5582 :
5583 : static tree
5584 26066249 : cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
5585 : bool /*lval*/,
5586 : bool *non_constant_p, bool *overflow_p,
5587 : tree *jump_target)
5588 : {
5589 26066249 : tree r;
5590 26066249 : tree orig_arg = TREE_OPERAND (t, 0);
5591 26066249 : tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue,
5592 : non_constant_p, overflow_p,
5593 : jump_target);
5594 26066247 : if (*jump_target)
5595 : return NULL_TREE;
5596 26066245 : VERIFY_CONSTANT (arg);
5597 20789458 : location_t loc = EXPR_LOCATION (t);
5598 20789458 : enum tree_code code = TREE_CODE (t);
5599 20789458 : tree type = TREE_TYPE (t);
5600 20789458 : r = fold_unary_loc (loc, code, type, arg);
5601 20789458 : if (r == NULL_TREE)
5602 : {
5603 17 : if (arg == orig_arg)
5604 : r = t;
5605 : else
5606 13 : r = build1_loc (loc, code, type, arg);
5607 : }
5608 20789458 : VERIFY_CONSTANT (r);
5609 : return r;
5610 : }
5611 :
5612 : /* Helper function for cxx_eval_binary_expression. Try to optimize
5613 : original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
5614 : generic folding should be used. */
5615 :
5616 : static tree
5617 10975089 : cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
5618 : tree lhs, tree rhs, bool *non_constant_p,
5619 : bool *overflow_p, tree *jump_target)
5620 : {
5621 10975089 : STRIP_NOPS (lhs);
5622 10975089 : if (TREE_CODE (lhs) != ADDR_EXPR)
5623 : return NULL_TREE;
5624 :
5625 10105470 : lhs = TREE_OPERAND (lhs, 0);
5626 :
5627 : /* &A[i] p+ j => &A[i + j] */
5628 10105470 : if (TREE_CODE (lhs) == ARRAY_REF
5629 210593 : && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
5630 210593 : && TREE_CODE (rhs) == INTEGER_CST
5631 210593 : && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
5632 10316063 : && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
5633 : {
5634 210593 : tree orig_type = TREE_TYPE (t);
5635 210593 : location_t loc = EXPR_LOCATION (t);
5636 210593 : tree type = TREE_TYPE (lhs);
5637 :
5638 210593 : t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
5639 210593 : tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
5640 210593 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
5641 : non_constant_p, overflow_p,
5642 : jump_target);
5643 210593 : if (*non_constant_p)
5644 : return NULL_TREE;
5645 210581 : if (*jump_target)
5646 : return NULL_TREE;
5647 : /* Don't fold an out-of-bound access. */
5648 210581 : if (!tree_int_cst_le (t, nelts))
5649 : return NULL_TREE;
5650 210581 : rhs = cp_fold_convert (ssizetype, rhs);
5651 : /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
5652 : constexpr int A[1]; ... (char *)&A[0] + 1 */
5653 210581 : if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
5654 210581 : rhs, TYPE_SIZE_UNIT (type))))
5655 : return NULL_TREE;
5656 : /* Make sure to treat the second operand of POINTER_PLUS_EXPR
5657 : as signed. */
5658 210549 : rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
5659 210549 : TYPE_SIZE_UNIT (type));
5660 210549 : t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
5661 210549 : t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
5662 : t, NULL_TREE, NULL_TREE);
5663 210549 : t = cp_build_addr_expr (t, tf_warning_or_error);
5664 210549 : t = cp_fold_convert (orig_type, t);
5665 210549 : return cxx_eval_constant_expression (ctx, t, vc_prvalue,
5666 : non_constant_p, overflow_p,
5667 210549 : jump_target);
5668 : }
5669 :
5670 : return NULL_TREE;
5671 : }
5672 :
5673 : /* Try to fold expressions like
5674 : (struct S *) (&a[0].D.2378 + 12)
5675 : into
5676 : &MEM <struct T> [(void *)&a + 12B]
5677 : This is something normally done by gimple_fold_stmt_to_constant_1
5678 : on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
5679 : dereference the address because some details are lost.
5680 : For pointer comparisons we want such folding though so that
5681 : match.pd address_compare optimization works. */
5682 :
5683 : static tree
5684 12319086 : cxx_maybe_fold_addr_pointer_plus (tree t)
5685 : {
5686 24638172 : while (CONVERT_EXPR_P (t)
5687 13030104 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
5688 711018 : t = TREE_OPERAND (t, 0);
5689 12319086 : if (TREE_CODE (t) != POINTER_PLUS_EXPR)
5690 : return NULL_TREE;
5691 10613400 : tree op0 = TREE_OPERAND (t, 0);
5692 10613400 : tree op1 = TREE_OPERAND (t, 1);
5693 10613400 : if (TREE_CODE (op1) != INTEGER_CST)
5694 : return NULL_TREE;
5695 10613400 : while (CONVERT_EXPR_P (op0)
5696 21223252 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
5697 10609852 : op0 = TREE_OPERAND (op0, 0);
5698 10613400 : if (TREE_CODE (op0) != ADDR_EXPR)
5699 : return NULL_TREE;
5700 10613400 : op1 = fold_convert (ptr_type_node, op1);
5701 10613400 : tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
5702 10613400 : return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
5703 : }
5704 :
5705 : /* Subroutine of cxx_eval_constant_expression.
5706 : Like cxx_eval_unary_expression, except for binary expressions. */
5707 :
5708 : static tree
5709 112954598 : cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
5710 : value_cat lval,
5711 : bool *non_constant_p, bool *overflow_p,
5712 : tree *jump_target)
5713 : {
5714 112954598 : tree r = NULL_TREE;
5715 112954598 : tree orig_lhs = TREE_OPERAND (t, 0);
5716 112954598 : tree orig_rhs = TREE_OPERAND (t, 1);
5717 112954598 : tree lhs, rhs;
5718 :
5719 112954598 : if (TREE_CODE (t) == POINTER_PLUS_EXPR
5720 12757983 : && CONVERT_EXPR_P (orig_lhs)
5721 6742293 : && (lhs = TREE_OPERAND (orig_lhs, 0))
5722 6742293 : && INDIRECT_TYPE_P (TREE_TYPE (lhs))
5723 6742293 : && (TREE_CODE (orig_lhs) != NOP_EXPR || !REINTERPRET_CAST_P (orig_lhs))
5724 119696862 : && is_properly_derived_from (TREE_TYPE (TREE_TYPE (orig_lhs)),
5725 6742264 : TREE_TYPE (TREE_TYPE (lhs))))
5726 : /* fold_unary_loc and match.pd can optimize
5727 : (type *) (ptr p+ off) into ((type *) ptr) p+ off, which can break
5728 : static_cast constexpr diagnostics, because ptr before the p+
5729 : cast to type * can be invalid while the original valid.
5730 : Evaluate it as (type *) (ptr p+ off) instead. */
5731 : {
5732 42 : tree cast = copy_node (orig_lhs);
5733 42 : tree pplus = copy_node (t);
5734 42 : TREE_OPERAND (cast, 0) = pplus;
5735 42 : TREE_OPERAND (pplus, 0) = lhs;
5736 42 : TREE_TYPE (pplus) = TREE_TYPE (lhs);
5737 42 : lhs = cxx_eval_constant_expression (ctx, cast, vc_prvalue,
5738 : non_constant_p, overflow_p,
5739 : jump_target);
5740 42 : if (lhs != cast)
5741 : {
5742 24 : ggc_free (cast);
5743 24 : ggc_free (pplus);
5744 : }
5745 42 : if (*non_constant_p)
5746 : return t;
5747 42 : return lhs;
5748 : }
5749 :
5750 112954556 : lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue,
5751 : non_constant_p, overflow_p,
5752 : jump_target);
5753 : /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
5754 : subtraction. */
5755 112954554 : if (*non_constant_p)
5756 : return t;
5757 90988774 : if (*jump_target)
5758 : return NULL_TREE;
5759 90988679 : rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue,
5760 : non_constant_p, overflow_p,
5761 : jump_target);
5762 90988679 : if (*non_constant_p)
5763 : return t;
5764 89817502 : if (*jump_target)
5765 : return NULL_TREE;
5766 :
5767 89817496 : location_t loc = EXPR_LOCATION (t);
5768 89817496 : enum tree_code code = TREE_CODE (t);
5769 89817496 : tree type = TREE_TYPE (t);
5770 :
5771 89817496 : if (code == EQ_EXPR || code == NE_EXPR)
5772 : {
5773 18558877 : bool is_code_eq = (code == EQ_EXPR);
5774 :
5775 18558877 : if (TREE_CODE (lhs) == PTRMEM_CST
5776 217 : && TREE_CODE (rhs) == PTRMEM_CST)
5777 : {
5778 76 : tree lmem = PTRMEM_CST_MEMBER (lhs);
5779 76 : tree rmem = PTRMEM_CST_MEMBER (rhs);
5780 76 : bool eq;
5781 76 : if (TREE_CODE (lmem) == TREE_CODE (rmem)
5782 76 : && TREE_CODE (lmem) == FIELD_DECL
5783 76 : && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
5784 103 : && same_type_p (DECL_CONTEXT (lmem),
5785 : DECL_CONTEXT (rmem)))
5786 : /* If both refer to (possibly different) members of the same union
5787 : (12.3), they compare equal. */
5788 : eq = true;
5789 : else
5790 49 : eq = cp_tree_equal (lhs, rhs);
5791 76 : r = constant_boolean_node (eq == is_code_eq, type);
5792 76 : }
5793 18558801 : else if ((TREE_CODE (lhs) == PTRMEM_CST
5794 18558660 : || TREE_CODE (rhs) == PTRMEM_CST)
5795 18558801 : && (null_member_pointer_value_p (lhs)
5796 141 : || null_member_pointer_value_p (rhs)))
5797 141 : r = constant_boolean_node (!is_code_eq, type);
5798 18558660 : else if (TREE_CODE (lhs) == PTRMEM_CST)
5799 0 : lhs = cplus_expand_constant (lhs);
5800 18558660 : else if (TREE_CODE (rhs) == PTRMEM_CST)
5801 0 : rhs = cplus_expand_constant (rhs);
5802 37117320 : else if (REFLECTION_TYPE_P (TREE_TYPE (lhs))
5803 18562606 : && REFLECTION_TYPE_P (TREE_TYPE (rhs)))
5804 : {
5805 3946 : const bool eq = compare_reflections (lhs, rhs);
5806 3946 : r = constant_boolean_node (eq == is_code_eq, type);
5807 : }
5808 : }
5809 0 : if (r == NULL_TREE
5810 89813333 : && TREE_CODE_CLASS (code) == tcc_comparison
5811 39460199 : && POINTER_TYPE_P (TREE_TYPE (lhs)))
5812 : {
5813 6159543 : if (tree lhso = cxx_maybe_fold_addr_pointer_plus (lhs))
5814 5160417 : lhs = fold_convert (TREE_TYPE (lhs), lhso);
5815 6159543 : if (tree rhso = cxx_maybe_fold_addr_pointer_plus (rhs))
5816 5452983 : rhs = fold_convert (TREE_TYPE (rhs), rhso);
5817 : }
5818 10975244 : if (code == POINTER_PLUS_EXPR && !*non_constant_p
5819 100792740 : && integer_zerop (lhs) && !integer_zerop (rhs))
5820 : {
5821 155 : if (!ctx->quiet)
5822 45 : error ("arithmetic involving a null pointer in %qE", lhs);
5823 155 : *non_constant_p = true;
5824 155 : return t;
5825 : }
5826 89817341 : else if (code == POINTER_PLUS_EXPR)
5827 : {
5828 10975089 : r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
5829 : overflow_p, jump_target);
5830 10975089 : if (*jump_target)
5831 : return NULL_TREE;
5832 : }
5833 78842252 : else if (code == SPACESHIP_EXPR)
5834 : {
5835 27416 : r = genericize_spaceship (loc, type, lhs, rhs);
5836 27416 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
5837 27416 : overflow_p, jump_target);
5838 : }
5839 :
5840 89789925 : if (r == NULL_TREE)
5841 : {
5842 89575213 : if (ctx->manifestly_const_eval == mce_true
5843 68527027 : && (flag_constexpr_fp_except
5844 68527024 : || TREE_CODE (type) != REAL_TYPE))
5845 : {
5846 68473115 : auto ofcc = make_temp_override (folding_cxx_constexpr, true);
5847 68473115 : r = fold_binary_initializer_loc (loc, code, type, lhs, rhs);
5848 68473115 : }
5849 : else
5850 21102098 : r = fold_binary_loc (loc, code, type, lhs, rhs);
5851 : }
5852 :
5853 89575213 : if (r == NULL_TREE
5854 9097451 : && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
5855 100 : && TREE_CODE (lhs) == INTEGER_CST
5856 98 : && TREE_CODE (rhs) == INTEGER_CST
5857 98887376 : && wi::neg_p (wi::to_wide (rhs)))
5858 : {
5859 : /* For diagnostics and -fpermissive emulate previous behavior of
5860 : handling shifts by negative amount. */
5861 98 : tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
5862 98 : if (nrhs)
5863 119 : r = fold_binary_loc (loc,
5864 : code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
5865 : type, lhs, nrhs);
5866 : }
5867 :
5868 89789925 : if (r == NULL_TREE)
5869 : {
5870 9097353 : if (lhs == orig_lhs && rhs == orig_rhs)
5871 : r = t;
5872 : else
5873 3150161 : r = build2_loc (loc, code, type, lhs, rhs);
5874 : }
5875 80692572 : else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
5876 433 : *non_constant_p = true;
5877 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
5878 : a local array in a constexpr function. */
5879 89789925 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
5880 71966686 : if (!ptr)
5881 71966686 : VERIFY_CONSTANT (r);
5882 : return r;
5883 : }
5884 :
5885 : /* Subroutine of cxx_eval_constant_expression.
5886 : Attempt to evaluate condition expressions. */
5887 :
5888 : static tree
5889 39526542 : cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
5890 : value_cat lval,
5891 : bool *non_constant_p, bool *overflow_p,
5892 : tree *jump_target)
5893 : {
5894 39526542 : tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5895 : vc_prvalue,
5896 : non_constant_p, overflow_p,
5897 : jump_target);
5898 39526542 : if (*jump_target)
5899 : return NULL_TREE;
5900 39526518 : VERIFY_CONSTANT (val);
5901 37209187 : if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
5902 : {
5903 : /* Evaluate the condition as if it was
5904 : if (__builtin_is_constant_evaluated ()), i.e. defer it if not
5905 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
5906 : without manifestly_const_eval even expressions or parts thereof which
5907 : will later be manifestly const_eval evaluated), otherwise fold it to
5908 : true. */
5909 1076285 : if (ctx->manifestly_const_eval == mce_unknown)
5910 : {
5911 973760 : *non_constant_p = true;
5912 973760 : return t;
5913 : }
5914 102525 : val = constant_boolean_node (ctx->manifestly_const_eval == mce_true,
5915 : boolean_type_node);
5916 : }
5917 : /* Don't VERIFY_CONSTANT the other operands. */
5918 36235427 : const bool zero_p = integer_zerop (val);
5919 36235427 : if (zero_p)
5920 22818781 : val = TREE_OPERAND (t, 2);
5921 : else
5922 13416646 : val = TREE_OPERAND (t, 1);
5923 36235427 : if (TREE_CODE (t) == IF_STMT && !val)
5924 9955756 : val = void_node;
5925 :
5926 : /* P2564: If we aren't in immediate function context (including a manifestly
5927 : constant-evaluated expression), check any uses of immediate functions in
5928 : the arm we're discarding. But don't do this inside a call; we already
5929 : checked when parsing the function. */
5930 36235427 : if (ctx->manifestly_const_eval != mce_true
5931 5126927 : && !in_immediate_context ()
5932 5028903 : && !ctx->call
5933 37046466 : && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2),
5934 811039 : ctx->manifestly_const_eval))
5935 : {
5936 7 : *non_constant_p = true;
5937 7 : return t;
5938 : }
5939 :
5940 : /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still
5941 : serve as the initializer for the same object as the outer TARGET_EXPR,
5942 : as in
5943 : A a = true ? A{} : A{};
5944 : so strip the inner TARGET_EXPR so we don't materialize a temporary. */
5945 36235420 : if (TREE_CODE (val) == TARGET_EXPR)
5946 5342 : val = TARGET_EXPR_INITIAL (val);
5947 36235420 : return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
5948 36235420 : overflow_p, jump_target);
5949 : }
5950 :
5951 : /* Subroutine of cxx_eval_constant_expression.
5952 : Attempt to evaluate vector condition expressions. Unlike
5953 : cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
5954 : ternary arithmetics operation, where all 3 arguments have to be
5955 : evaluated as constants and then folding computes the result from
5956 : them. */
5957 :
5958 : static tree
5959 11755 : cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
5960 : bool *non_constant_p, bool *overflow_p,
5961 : tree *jump_target)
5962 : {
5963 11755 : tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5964 : vc_prvalue,
5965 : non_constant_p, overflow_p,
5966 : jump_target);
5967 11755 : if (*jump_target)
5968 : return NULL_TREE;
5969 11755 : VERIFY_CONSTANT (arg1);
5970 8227 : tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
5971 : vc_prvalue,
5972 : non_constant_p, overflow_p,
5973 : jump_target);
5974 8227 : if (*jump_target)
5975 : return NULL_TREE;
5976 8227 : VERIFY_CONSTANT (arg2);
5977 7097 : tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
5978 : vc_prvalue,
5979 : non_constant_p, overflow_p,
5980 : jump_target);
5981 7097 : if (*jump_target)
5982 : return NULL_TREE;
5983 7097 : VERIFY_CONSTANT (arg3);
5984 7097 : location_t loc = EXPR_LOCATION (t);
5985 7097 : tree type = TREE_TYPE (t);
5986 7097 : tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5987 7097 : if (r == NULL_TREE)
5988 : {
5989 0 : if (arg1 == TREE_OPERAND (t, 0)
5990 0 : && arg2 == TREE_OPERAND (t, 1)
5991 0 : && arg3 == TREE_OPERAND (t, 2))
5992 : r = t;
5993 : else
5994 0 : r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5995 : }
5996 7097 : VERIFY_CONSTANT (r);
5997 : return r;
5998 : }
5999 :
6000 : /* Returns less than, equal to, or greater than zero if KEY is found to be
6001 : less than, to match, or to be greater than the constructor_elt's INDEX. */
6002 :
6003 : static int
6004 440312 : array_index_cmp (tree key, tree index)
6005 : {
6006 440312 : gcc_assert (TREE_CODE (key) == INTEGER_CST);
6007 :
6008 440312 : switch (TREE_CODE (index))
6009 : {
6010 437368 : case INTEGER_CST:
6011 437368 : return tree_int_cst_compare (key, index);
6012 2944 : case RANGE_EXPR:
6013 2944 : {
6014 2944 : tree lo = TREE_OPERAND (index, 0);
6015 2944 : tree hi = TREE_OPERAND (index, 1);
6016 2944 : if (tree_int_cst_lt (key, lo))
6017 : return -1;
6018 2648 : else if (tree_int_cst_lt (hi, key))
6019 : return 1;
6020 : else
6021 2648 : return 0;
6022 : }
6023 0 : default:
6024 0 : gcc_unreachable ();
6025 : }
6026 : }
6027 :
6028 : /* Extract a single INTEGER_CST from RAW_DATA_CST RAW_DATA at
6029 : relative index OFF. */
6030 :
6031 : static tree
6032 29559 : raw_data_cst_elt (tree raw_data, unsigned int off)
6033 : {
6034 29559 : return build_int_cst (TREE_TYPE (raw_data),
6035 29559 : TYPE_UNSIGNED (TREE_TYPE (raw_data))
6036 59118 : ? (HOST_WIDE_INT)
6037 29073 : RAW_DATA_UCHAR_ELT (raw_data, off)
6038 : : (HOST_WIDE_INT)
6039 486 : RAW_DATA_SCHAR_ELT (raw_data, off));
6040 : }
6041 :
6042 : /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
6043 : if none. If INSERT is true, insert a matching element rather than fail. */
6044 :
6045 : static HOST_WIDE_INT
6046 12558512 : find_array_ctor_elt (tree ary, tree dindex, bool insert)
6047 : {
6048 12558512 : if (tree_int_cst_sgn (dindex) < 0)
6049 : return -1;
6050 :
6051 12558512 : unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex);
6052 12558512 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary);
6053 12558512 : unsigned HOST_WIDE_INT len = vec_safe_length (elts);
6054 :
6055 16827249 : unsigned HOST_WIDE_INT end = len;
6056 16827249 : unsigned HOST_WIDE_INT begin = 0;
6057 :
6058 : /* If the last element of the CONSTRUCTOR has its own index, we can assume
6059 : that the same is true of the other elements and index directly. */
6060 12000843 : if (end > 0)
6061 : {
6062 11771886 : tree cindex = (*elts)[end - 1].index;
6063 11771886 : if (cindex == NULL_TREE)
6064 : {
6065 : /* Verify that if the last index is missing, all indexes
6066 : are missing and there is no RAW_DATA_CST. */
6067 21907 : if (flag_checking)
6068 220621 : for (unsigned int j = 0; j < len - 1; ++j)
6069 198714 : gcc_assert ((*elts)[j].index == NULL_TREE
6070 : && TREE_CODE ((*elts)[j].value) != RAW_DATA_CST);
6071 21907 : if (i < end)
6072 21907 : return i;
6073 : else
6074 : {
6075 0 : begin = end;
6076 0 : if (i == end)
6077 : /* If the element is to be added right at the end,
6078 : make sure it is added with cleared index too. */
6079 4826406 : dindex = NULL_TREE;
6080 0 : else if (insert)
6081 : /* Otherwise, in order not to break the assumption
6082 : that CONSTRUCTOR either has all indexes or none,
6083 : we need to add indexes to all elements. */
6084 0 : for (unsigned int j = 0; j < len; ++j)
6085 0 : (*elts)[j].index = build_int_cst (TREE_TYPE (dindex), j);
6086 : }
6087 : }
6088 11749979 : else if (TREE_CODE (cindex) == INTEGER_CST
6089 11749979 : && compare_tree_int (cindex, end - 1) == 0)
6090 : {
6091 11538888 : tree value = (*elts)[end - 1].value;
6092 11538888 : if (i < end)
6093 : {
6094 7710289 : if (i == end - 1 && TREE_CODE (value) == RAW_DATA_CST)
6095 : begin = end - 1;
6096 : else
6097 7710199 : return i;
6098 : }
6099 3828599 : else if (TREE_CODE (value) == RAW_DATA_CST
6100 3860755 : && wi::to_offset (dindex) < (wi::to_offset (cindex)
6101 32156 : + RAW_DATA_LENGTH (value)))
6102 16078 : begin = end - 1;
6103 : else
6104 3812521 : begin = end;
6105 : }
6106 : }
6107 :
6108 : /* Otherwise, find a matching index by means of a binary search. */
6109 5031188 : while (begin != end)
6110 : {
6111 361715 : unsigned HOST_WIDE_INT middle = (begin + end) / 2;
6112 361715 : constructor_elt &elt = (*elts)[middle];
6113 361715 : tree idx = elt.index;
6114 :
6115 361715 : int cmp = array_index_cmp (dindex, idx);
6116 361715 : if (cmp > 0
6117 66760 : && TREE_CODE (elt.value) == RAW_DATA_CST
6118 445523 : && wi::to_offset (dindex) < (wi::to_offset (idx)
6119 83808 : + RAW_DATA_LENGTH (elt.value)))
6120 29417 : cmp = 0;
6121 361715 : if (cmp < 0)
6122 : end = middle;
6123 194276 : else if (cmp > 0)
6124 37343 : begin = middle + 1;
6125 : else
6126 : {
6127 156933 : if (insert && TREE_CODE (elt.value) == RAW_DATA_CST)
6128 : {
6129 : /* We need to split the RAW_DATA_CST elt. */
6130 122 : constructor_elt e;
6131 122 : gcc_checking_assert (TREE_CODE (idx) != RANGE_EXPR);
6132 244 : unsigned int off = (wi::to_offset (dindex)
6133 244 : - wi::to_offset (idx)).to_uhwi ();
6134 122 : tree value = elt.value;
6135 122 : unsigned int len = RAW_DATA_LENGTH (value);
6136 122 : if (off > 1 && len >= off + 3)
6137 22 : value = copy_node (elt.value);
6138 122 : if (off)
6139 : {
6140 33 : if (off > 1)
6141 33 : RAW_DATA_LENGTH (elt.value) = off;
6142 : else
6143 0 : elt.value = raw_data_cst_elt (elt.value, 0);
6144 33 : e.index = size_binop (PLUS_EXPR, elt.index,
6145 : build_int_cst (TREE_TYPE (elt.index),
6146 : off));
6147 33 : e.value = NULL_TREE;
6148 33 : ++middle;
6149 33 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
6150 : }
6151 122 : (*elts)[middle].value = raw_data_cst_elt (value, off);
6152 122 : if (len >= off + 2)
6153 : {
6154 111 : e.index = (*elts)[middle].index;
6155 111 : e.index = size_binop (PLUS_EXPR, e.index,
6156 : build_one_cst (TREE_TYPE (e.index)));
6157 111 : if (len >= off + 3)
6158 : {
6159 111 : RAW_DATA_LENGTH (value) -= off + 1;
6160 111 : RAW_DATA_POINTER (value) += off + 1;
6161 111 : e.value = value;
6162 : }
6163 : else
6164 0 : e.value = raw_data_cst_elt (value, off + 1);
6165 111 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
6166 : }
6167 122 : return middle;
6168 : }
6169 35919 : if (insert && TREE_CODE (idx) == RANGE_EXPR)
6170 : {
6171 : /* We need to split the range. */
6172 361 : constructor_elt e;
6173 361 : tree lo = TREE_OPERAND (idx, 0);
6174 361 : tree hi = TREE_OPERAND (idx, 1);
6175 361 : tree value = elt.value;
6176 361 : dindex = fold_convert (sizetype, dindex);
6177 361 : if (tree_int_cst_lt (lo, dindex))
6178 : {
6179 : /* There are still some lower elts; shorten the range. */
6180 194 : tree new_hi = int_const_binop (MINUS_EXPR, dindex,
6181 97 : size_one_node);
6182 97 : if (tree_int_cst_equal (lo, new_hi))
6183 : /* Only one element left, no longer a range. */
6184 42 : elt.index = lo;
6185 : else
6186 55 : TREE_OPERAND (idx, 1) = new_hi;
6187 : /* Append the element we want to insert. */
6188 97 : ++middle;
6189 97 : e.index = dindex;
6190 97 : e.value = unshare_constructor (value);
6191 97 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
6192 : }
6193 : else
6194 : /* No lower elts, the range elt is now ours. */
6195 264 : elt.index = dindex;
6196 :
6197 361 : if (tree_int_cst_lt (dindex, hi))
6198 : {
6199 : /* There are still some higher elts; append a range. */
6200 506 : tree new_lo = int_const_binop (PLUS_EXPR, dindex,
6201 253 : size_one_node);
6202 253 : if (tree_int_cst_equal (new_lo, hi))
6203 : e.index = hi;
6204 : else
6205 153 : e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
6206 253 : e.value = unshare_constructor (value);
6207 253 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
6208 : }
6209 : }
6210 156811 : return middle;
6211 : }
6212 : }
6213 :
6214 4669473 : if (insert)
6215 : {
6216 4538807 : constructor_elt e = { dindex, NULL_TREE };
6217 4538807 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e);
6218 4538807 : return end;
6219 : }
6220 :
6221 : return -1;
6222 : }
6223 :
6224 : /* Return a pointer to the constructor_elt of CTOR which matches INDEX. If no
6225 : matching constructor_elt exists, then add one to CTOR.
6226 :
6227 : As an optimization, if POS_HINT is non-negative then it is used as a guess
6228 : for the (integer) index of the matching constructor_elt within CTOR.
6229 :
6230 : If POS_HINT is -2, it means do not insert. */
6231 :
6232 : static constructor_elt *
6233 42646194 : get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
6234 : {
6235 : /* Check the hint first. */
6236 4631776 : if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)
6237 47277970 : && CONSTRUCTOR_ELT (ctor, pos_hint)->index == index)
6238 : return CONSTRUCTOR_ELT (ctor, pos_hint);
6239 :
6240 38014430 : bool insertp = (pos_hint != -2);
6241 38014430 : tree type = TREE_TYPE (ctor);
6242 38014430 : if (TREE_CODE (type) == VECTOR_TYPE && index == NULL_TREE)
6243 : {
6244 27296 : gcc_assert (insertp);
6245 27296 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE);
6246 27296 : return &CONSTRUCTOR_ELTS (ctor)->last();
6247 : }
6248 37987134 : else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
6249 : {
6250 6223057 : if (TREE_CODE (index) == RANGE_EXPR)
6251 : {
6252 : /* Support for RANGE_EXPR index lookups is currently limited to
6253 : accessing an existing element via POS_HINT, or appending a new
6254 : element to the end of CTOR. ??? Support for other access
6255 : patterns may also be needed. */
6256 3 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
6257 3 : if (vec_safe_length (elts))
6258 : {
6259 3 : tree lo = TREE_OPERAND (index, 0);
6260 3 : gcc_assert (array_index_cmp (elts->last().index, lo) < 0);
6261 : }
6262 3 : gcc_assert (insertp);
6263 3 : CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE);
6264 3 : return &elts->last();
6265 : }
6266 :
6267 6223054 : HOST_WIDE_INT i = find_array_ctor_elt (ctor, index, insertp);
6268 6223054 : if (i < 0)
6269 : {
6270 2711 : gcc_assert (!insertp);
6271 : return nullptr;
6272 : }
6273 6220343 : constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i);
6274 6220343 : if (!insertp && cep->index && TREE_CODE (cep->index) == RANGE_EXPR)
6275 : {
6276 : /* Split a range even if we aren't inserting new entries. */
6277 0 : gcc_assert (!insertp);
6278 0 : i = find_array_ctor_elt (ctor, index, /*insert*/true);
6279 0 : gcc_assert (i >= 0);
6280 0 : cep = CONSTRUCTOR_ELT (ctor, i);
6281 : }
6282 6220343 : gcc_assert (cep->index == NULL_TREE
6283 : || TREE_CODE (cep->index) != RANGE_EXPR);
6284 : return cep;
6285 : }
6286 : else
6287 : {
6288 31764077 : gcc_assert (TREE_CODE (index) == FIELD_DECL
6289 : && (same_type_ignoring_top_level_qualifiers_p
6290 : (DECL_CONTEXT (index), TREE_TYPE (ctor))));
6291 :
6292 : /* We must keep the CONSTRUCTOR's ELTS in FIELD order.
6293 : Usually we meet initializers in that order, but it is
6294 : possible for base types to be placed not in program
6295 : order. */
6296 31764077 : tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
6297 31764077 : unsigned HOST_WIDE_INT idx = 0;
6298 31764077 : constructor_elt *cep = NULL;
6299 :
6300 : /* Check if we're changing the active member of a union. */
6301 585427 : if (TREE_CODE (type) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)
6302 32143328 : && CONSTRUCTOR_ELT (ctor, 0)->index != index)
6303 12486 : vec_safe_truncate (CONSTRUCTOR_ELTS (ctor), 0);
6304 : /* If the bit offset of INDEX is larger than that of the last
6305 : constructor_elt, then we can just immediately append a new
6306 : constructor_elt to the end of CTOR. */
6307 48351121 : else if (CONSTRUCTOR_NELTS (ctor)
6308 44487854 : && tree_int_cst_compare (bit_position (index),
6309 43524180 : bit_position (CONSTRUCTOR_ELTS (ctor)
6310 21762090 : ->last().index)) > 0)
6311 : {
6312 6138720 : idx = CONSTRUCTOR_NELTS (ctor);
6313 6138720 : goto insert;
6314 : }
6315 :
6316 : /* Otherwise, we need to iterate over CTOR to find or insert INDEX
6317 : appropriately. */
6318 :
6319 30413243 : for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor), idx, &cep);
6320 4787886 : idx++, fields = DECL_CHAIN (fields))
6321 : {
6322 20411256 : if (index == cep->index)
6323 15581272 : goto found;
6324 :
6325 : /* The field we're initializing must be on the field
6326 : list. Look to see if it is present before the
6327 : field the current ELT initializes. */
6328 51197009 : for (; fields != cep->index; fields = DECL_CHAIN (fields))
6329 46409123 : if (index == fields)
6330 42098 : goto insert;
6331 : }
6332 : /* We fell off the end of the CONSTRUCTOR, so insert a new
6333 : entry at the end. */
6334 :
6335 16182805 : insert:
6336 16182805 : if (!insertp)
6337 : return nullptr;
6338 :
6339 16182802 : {
6340 16182802 : constructor_elt ce = { index, NULL_TREE };
6341 :
6342 16182802 : vec_safe_insert (CONSTRUCTOR_ELTS (ctor), idx, ce);
6343 16182802 : cep = CONSTRUCTOR_ELT (ctor, idx);
6344 : }
6345 42646194 : found:;
6346 :
6347 : return cep;
6348 : }
6349 : }
6350 :
6351 : /* Under the control of CTX, issue a detailed diagnostic for
6352 : an out-of-bounds subscript INDEX into the expression ARRAY. */
6353 :
6354 : static void
6355 601 : diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index)
6356 : {
6357 601 : if (!ctx->quiet)
6358 : {
6359 120 : tree arraytype = TREE_TYPE (array);
6360 :
6361 : /* Convert the unsigned array subscript to a signed integer to avoid
6362 : printing huge numbers for small negative values. */
6363 120 : tree sidx = fold_convert (ssizetype, index);
6364 120 : STRIP_ANY_LOCATION_WRAPPER (array);
6365 120 : if (DECL_P (array))
6366 : {
6367 79 : auto_diagnostic_group d;
6368 79 : if (TYPE_DOMAIN (arraytype))
6369 73 : error_at (loc, "array subscript value %qE is outside the bounds "
6370 : "of array %qD of type %qT", sidx, array, arraytype);
6371 : else
6372 6 : error_at (loc, "nonzero array subscript %qE is used with array %qD of "
6373 : "type %qT with unknown bounds", sidx, array, arraytype);
6374 79 : inform (DECL_SOURCE_LOCATION (array), "declared here");
6375 79 : }
6376 41 : else if (TYPE_DOMAIN (arraytype))
6377 38 : error_at (loc, "array subscript value %qE is outside the bounds "
6378 : "of array type %qT", sidx, arraytype);
6379 : else
6380 3 : error_at (loc, "nonzero array subscript %qE is used with array of type %qT "
6381 : "with unknown bounds", sidx, arraytype);
6382 : }
6383 601 : }
6384 :
6385 : /* Return the number of elements for TYPE (which is an ARRAY_TYPE or
6386 : a VECTOR_TYPE). */
6387 :
6388 : static tree
6389 21131353 : get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
6390 : bool *non_constant_p, bool *overflow_p,
6391 : tree *jump_target)
6392 : {
6393 21131353 : tree nelts;
6394 21131353 : if (TREE_CODE (type) == ARRAY_TYPE)
6395 : {
6396 21131353 : if (TYPE_DOMAIN (type))
6397 21131093 : nelts = array_type_nelts_top (type);
6398 : else
6399 260 : nelts = size_zero_node;
6400 : }
6401 0 : else if (VECTOR_TYPE_P (type))
6402 0 : nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
6403 : else
6404 0 : gcc_unreachable ();
6405 :
6406 : /* For VLAs, the number of elements won't be an integer constant. */
6407 21131353 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
6408 : non_constant_p, overflow_p,
6409 : jump_target);
6410 21131353 : return nelts;
6411 : }
6412 :
6413 : /* Extract element INDEX consisting of CHARS_PER_ELT chars from
6414 : STRING_CST STRING. */
6415 :
6416 : static tree
6417 2000035 : extract_string_elt (tree string, unsigned chars_per_elt, unsigned index)
6418 : {
6419 2000035 : tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string)));
6420 2000035 : tree r;
6421 :
6422 2000035 : if (chars_per_elt == 1)
6423 1784924 : r = build_int_cst (type, TREE_STRING_POINTER (string)[index]);
6424 : else
6425 : {
6426 215111 : const unsigned char *ptr
6427 215111 : = ((const unsigned char *)TREE_STRING_POINTER (string)
6428 215111 : + index * chars_per_elt);
6429 215111 : r = native_interpret_expr (type, ptr, chars_per_elt);
6430 : }
6431 2000035 : return r;
6432 : }
6433 :
6434 : /* Subroutine of cxx_eval_array_reference. T is an ARRAY_REF; evaluate the
6435 : subscript, diagnose any problems with it, and return the result. */
6436 :
6437 : static tree
6438 21332744 : eval_and_check_array_index (const constexpr_ctx *ctx,
6439 : tree t, bool allow_one_past,
6440 : bool *non_constant_p, bool *overflow_p,
6441 : tree *jump_target)
6442 : {
6443 21332744 : location_t loc = cp_expr_loc_or_input_loc (t);
6444 21332744 : tree ary = TREE_OPERAND (t, 0);
6445 21332744 : t = TREE_OPERAND (t, 1);
6446 21332744 : tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue,
6447 : non_constant_p, overflow_p,
6448 : jump_target);
6449 21332744 : if (*jump_target)
6450 : return NULL_TREE;
6451 21332744 : VERIFY_CONSTANT (index);
6452 :
6453 21130557 : if (!tree_fits_shwi_p (index)
6454 21130557 : || tree_int_cst_sgn (index) < 0)
6455 : {
6456 112 : diag_array_subscript (loc, ctx, ary, index);
6457 112 : *non_constant_p = true;
6458 112 : return t;
6459 : }
6460 :
6461 21130445 : tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
6462 : overflow_p, jump_target);
6463 21130445 : if (*jump_target)
6464 : return NULL_TREE;
6465 21130445 : VERIFY_CONSTANT (nelts);
6466 21130361 : if (allow_one_past
6467 21130361 : ? !tree_int_cst_le (index, nelts)
6468 14336889 : : !tree_int_cst_lt (index, nelts))
6469 : {
6470 489 : diag_array_subscript (loc, ctx, ary, index);
6471 489 : *non_constant_p = true;
6472 489 : return t;
6473 : }
6474 :
6475 : return index;
6476 : }
6477 :
6478 : /* Subroutine of cxx_eval_constant_expression.
6479 : Attempt to reduce a reference to an array slot. */
6480 :
6481 : static tree
6482 15700971 : cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
6483 : value_cat lval,
6484 : bool *non_constant_p, bool *overflow_p,
6485 : tree *jump_target)
6486 : {
6487 15700971 : tree oldary = TREE_OPERAND (t, 0);
6488 15700971 : tree ary = cxx_eval_constant_expression (ctx, oldary,
6489 : lval,
6490 : non_constant_p, overflow_p,
6491 : jump_target);
6492 15700971 : if (*non_constant_p)
6493 : return t;
6494 15457647 : if (*jump_target)
6495 : return NULL_TREE;
6496 15457647 : if (!lval
6497 8662728 : && TREE_CODE (ary) == VIEW_CONVERT_EXPR
6498 144212 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
6499 15601859 : && (TYPE_MAIN_VARIANT (TREE_TYPE (t))
6500 144212 : == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))))
6501 144212 : ary = TREE_OPERAND (ary, 0);
6502 :
6503 15457647 : tree oldidx = TREE_OPERAND (t, 1);
6504 15457647 : tree index = eval_and_check_array_index (ctx, t, lval,
6505 : non_constant_p, overflow_p,
6506 : jump_target);
6507 15457647 : if (*non_constant_p)
6508 : return t;
6509 15254856 : if (*jump_target)
6510 : return NULL_TREE;
6511 :
6512 15254856 : if (lval && ary == oldary && index == oldidx)
6513 : return t;
6514 10233282 : else if (lval == vc_discard)
6515 : return t;
6516 10233282 : else if (lval)
6517 1771644 : return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
6518 :
6519 8461638 : unsigned len = 0, elem_nchars = 1;
6520 8461638 : tree elem_type = TREE_TYPE (TREE_TYPE (ary));
6521 8461638 : if (TREE_CODE (ary) == CONSTRUCTOR)
6522 6328573 : len = CONSTRUCTOR_NELTS (ary);
6523 2133065 : else if (TREE_CODE (ary) == STRING_CST)
6524 : {
6525 1988867 : elem_nchars = (TYPE_PRECISION (elem_type)
6526 1988867 : / TYPE_PRECISION (char_type_node));
6527 1988867 : len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
6528 : }
6529 144198 : else if (TREE_CODE (ary) == VECTOR_CST)
6530 : /* We don't create variable-length VECTOR_CSTs. */
6531 144198 : len = VECTOR_CST_NELTS (ary).to_constant ();
6532 : else
6533 : {
6534 : /* We can't do anything with other tree codes, so use
6535 : VERIFY_CONSTANT to complain and fail. */
6536 0 : VERIFY_CONSTANT (ary);
6537 0 : gcc_unreachable ();
6538 : }
6539 :
6540 8461638 : bool found;
6541 8461638 : HOST_WIDE_INT i = 0;
6542 8461638 : if (TREE_CODE (ary) == CONSTRUCTOR)
6543 : {
6544 6328573 : HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
6545 6328573 : found = (ix >= 0);
6546 6328573 : if (found)
6547 6201273 : i = ix;
6548 : }
6549 : else
6550 : {
6551 2133065 : i = tree_to_shwi (index);
6552 2133065 : found = (i < len);
6553 : }
6554 :
6555 8461638 : if (found)
6556 : {
6557 8333873 : tree r;
6558 8333873 : if (TREE_CODE (ary) == CONSTRUCTOR)
6559 : {
6560 6201273 : r = (*CONSTRUCTOR_ELTS (ary))[i].value;
6561 6201273 : if (TREE_CODE (r) == RAW_DATA_CST)
6562 : {
6563 29437 : tree ridx = (*CONSTRUCTOR_ELTS (ary))[i].index;
6564 29437 : gcc_checking_assert (ridx);
6565 29437 : unsigned int off
6566 29437 : = (wi::to_offset (index) - wi::to_offset (ridx)).to_uhwi ();
6567 29437 : r = raw_data_cst_elt (r, off);
6568 : }
6569 : }
6570 2132600 : else if (TREE_CODE (ary) == VECTOR_CST)
6571 144198 : r = VECTOR_CST_ELT (ary, i);
6572 : else
6573 1988402 : r = extract_string_elt (ary, elem_nchars, i);
6574 :
6575 2162037 : if (r)
6576 : /* Don't VERIFY_CONSTANT here. */
6577 : return r;
6578 :
6579 : /* Otherwise the element doesn't have a value yet. */
6580 : }
6581 :
6582 : /* Not found. */
6583 :
6584 127765 : if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
6585 90 : return build_constructor (elem_type, NULL);
6586 :
6587 127675 : if (TREE_CODE (ary) == CONSTRUCTOR
6588 127675 : && CONSTRUCTOR_NO_CLEARING (ary))
6589 : {
6590 : /* 'ary' is part of the aggregate initializer we're currently
6591 : building; if there's no initializer for this element yet,
6592 : that's an error. */
6593 51 : if (!ctx->quiet)
6594 16 : error ("accessing uninitialized array element");
6595 51 : *non_constant_p = true;
6596 51 : return t;
6597 : }
6598 :
6599 : /* If it's within the array bounds but doesn't have an explicit
6600 : initializer, it's initialized from {}. But use build_value_init
6601 : directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */
6602 127624 : tree val;
6603 127624 : constexpr_ctx new_ctx;
6604 127624 : if (CP_AGGREGATE_TYPE_P (elem_type))
6605 : {
6606 504 : tree empty_ctor = build_constructor (init_list_type_node, NULL);
6607 504 : val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
6608 : }
6609 : else
6610 127120 : val = build_value_init (elem_type, tf_warning_or_error);
6611 :
6612 : /* Create a new constructor only if we don't already have a suitable one. */
6613 127624 : const bool new_ctor = (!SCALAR_TYPE_P (elem_type)
6614 128154 : && (!ctx->ctor
6615 45 : || !same_type_ignoring_top_level_qualifiers_p
6616 45 : (elem_type, TREE_TYPE (ctx->ctor))));
6617 : if (new_ctor)
6618 : {
6619 521 : new_ctx = *ctx;
6620 : /* We clear the object here. We used to replace it with T, but that
6621 : caused problems (101371, 108158); and anyway, T is the initializer,
6622 : not the target object. */
6623 521 : new_ctx.object = NULL_TREE;
6624 521 : new_ctx.ctor = build_constructor (elem_type, NULL);
6625 521 : ctx = &new_ctx;
6626 : }
6627 127624 : t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
6628 : overflow_p, jump_target);
6629 127624 : if (new_ctor && t != ctx->ctor)
6630 500 : free_constructor (ctx->ctor);
6631 : return t;
6632 : }
6633 :
6634 : /* Subroutine of cxx_eval_constant_expression.
6635 : Attempt to reduce a field access of a value of class type. */
6636 :
6637 : static tree
6638 116396779 : cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
6639 : value_cat lval,
6640 : bool *non_constant_p, bool *overflow_p,
6641 : tree *jump_target)
6642 : {
6643 116396779 : unsigned HOST_WIDE_INT i;
6644 116396779 : tree field;
6645 116396779 : tree value;
6646 116396779 : tree part = TREE_OPERAND (t, 1);
6647 116396779 : tree orig_whole = TREE_OPERAND (t, 0);
6648 116396779 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6649 : lval,
6650 : non_constant_p, overflow_p,
6651 : jump_target);
6652 116396779 : if (*non_constant_p)
6653 : return t;
6654 90248865 : if (*jump_target)
6655 : return NULL_TREE;
6656 90248853 : if (INDIRECT_REF_P (whole)
6657 90248853 : && integer_zerop (TREE_OPERAND (whole, 0)))
6658 : {
6659 177 : if (!ctx->quiet)
6660 39 : error ("dereferencing a null pointer in %qE", orig_whole);
6661 177 : *non_constant_p = true;
6662 177 : return t;
6663 : }
6664 :
6665 90248676 : if (TREE_CODE (whole) == PTRMEM_CST)
6666 1651 : whole = cplus_expand_constant (whole);
6667 90248676 : if (whole == orig_whole)
6668 : return t;
6669 61226261 : if (lval == vc_discard)
6670 : return t;
6671 61226213 : if (lval)
6672 21785835 : return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
6673 : whole, part, NULL_TREE);
6674 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6675 : CONSTRUCTOR. */
6676 39440378 : if (TREE_CODE (whole) != CONSTRUCTOR)
6677 : {
6678 0 : if (!ctx->quiet)
6679 0 : error ("%qE is not a constant expression", orig_whole);
6680 0 : *non_constant_p = true;
6681 0 : return t;
6682 : }
6683 39438883 : if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole))
6684 39442055 : && DECL_MUTABLE_P (part))
6685 : {
6686 144 : if (!ctx->quiet)
6687 16 : error ("mutable %qD is not usable in a constant expression", part);
6688 144 : *non_constant_p = true;
6689 144 : return t;
6690 : }
6691 :
6692 39440234 : bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole));
6693 59258173 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6694 : {
6695 : /* Use name match for PMF fields, as a variant will have a
6696 : different FIELD_DECL with a different type. */
6697 59032320 : if (pmf ? DECL_NAME (field) == DECL_NAME (part)
6698 : : field == part)
6699 : {
6700 39214381 : if (value == void_node)
6701 6 : goto uninit;
6702 39214375 : if (value)
6703 : {
6704 39214357 : STRIP_ANY_LOCATION_WRAPPER (value);
6705 39214357 : return value;
6706 : }
6707 : else
6708 : /* We're in the middle of initializing it. */
6709 : break;
6710 : }
6711 : }
6712 225871 : if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE)
6713 : {
6714 112 : if (CONSTRUCTOR_NELTS (whole) > 0)
6715 : {
6716 : /* DR 1188 says we don't have to deal with this. */
6717 97 : if (!ctx->quiet)
6718 : {
6719 20 : constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0);
6720 20 : if (cep->value == NULL_TREE)
6721 9 : error ("accessing uninitialized member %qD", part);
6722 : else
6723 11 : error ("accessing %qD member instead of active %qD member "
6724 : "in constant expression", part, cep->index);
6725 : }
6726 97 : *non_constant_p = true;
6727 97 : return t;
6728 : }
6729 15 : else if (!CONSTRUCTOR_NO_CLEARING (whole))
6730 : {
6731 : /* Value-initialized union, check if looking at the first member. */
6732 12 : tree first = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (whole)));
6733 12 : if (first != part)
6734 : {
6735 9 : if (!ctx->quiet)
6736 3 : error ("accessing %qD member instead of initialized %qD "
6737 : "member in constant expression", part, first);
6738 9 : *non_constant_p = true;
6739 9 : return t;
6740 : }
6741 : }
6742 : }
6743 :
6744 : /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
6745 : classes never get represented; throw together a value now. */
6746 225765 : if (is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
6747 209177 : return build_constructor (TREE_TYPE (t), NULL);
6748 :
6749 16588 : gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
6750 :
6751 16588 : if (CONSTRUCTOR_NO_CLEARING (whole))
6752 : {
6753 112 : uninit:
6754 : /* 'whole' is part of the aggregate initializer we're currently
6755 : building; if there's no initializer for this member yet, that's an
6756 : error. */
6757 118 : if (!ctx->quiet)
6758 23 : error ("accessing uninitialized member %qD", part);
6759 118 : *non_constant_p = true;
6760 118 : return t;
6761 : }
6762 :
6763 : /* If there's no explicit init for this field, it's value-initialized. */
6764 :
6765 16476 : if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
6766 : {
6767 : /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR
6768 : and copy the flags. */
6769 15869 : constructor_elt *e = get_or_insert_ctor_field (whole, part);
6770 15869 : e->value = value = build_constructor (TREE_TYPE (part), NULL);
6771 15869 : CONSTRUCTOR_ZERO_PADDING_BITS (value)
6772 15869 : = CONSTRUCTOR_ZERO_PADDING_BITS (whole);
6773 15869 : return value;
6774 : }
6775 :
6776 607 : value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
6777 607 : return cxx_eval_constant_expression (ctx, value,
6778 : lval,
6779 : non_constant_p, overflow_p,
6780 607 : jump_target);
6781 : }
6782 :
6783 : /* Subroutine of cxx_eval_constant_expression.
6784 : Attempt to reduce a field access of a value of class type that is
6785 : expressed as a BIT_FIELD_REF. */
6786 :
6787 : static tree
6788 40745 : cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
6789 : value_cat lval,
6790 : bool *non_constant_p, bool *overflow_p,
6791 : tree *jump_target)
6792 : {
6793 40745 : tree orig_whole = TREE_OPERAND (t, 0);
6794 40745 : tree retval, fldval, utype, mask;
6795 40745 : bool fld_seen = false;
6796 40745 : HOST_WIDE_INT istart, isize;
6797 40745 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6798 : lval,
6799 : non_constant_p, overflow_p,
6800 : jump_target);
6801 40745 : tree start, field, value;
6802 40745 : unsigned HOST_WIDE_INT i;
6803 :
6804 40745 : if (*jump_target)
6805 : return NULL_TREE;
6806 40745 : if (whole == orig_whole)
6807 : return t;
6808 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6809 : CONSTRUCTOR. */
6810 40596 : if (!*non_constant_p
6811 40596 : && TREE_CODE (whole) != VECTOR_CST
6812 0 : && TREE_CODE (whole) != CONSTRUCTOR)
6813 : {
6814 0 : if (!ctx->quiet)
6815 0 : error ("%qE is not a constant expression", orig_whole);
6816 0 : *non_constant_p = true;
6817 : }
6818 40596 : if (*non_constant_p)
6819 : return t;
6820 :
6821 40596 : if (TREE_CODE (whole) == VECTOR_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)))
6822 : {
6823 40596 : if (tree r = fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
6824 : TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)))
6825 : return r;
6826 0 : if (!ctx->quiet)
6827 0 : error ("%qE is not a constant expression", orig_whole);
6828 0 : *non_constant_p = true;
6829 0 : return t;
6830 : }
6831 :
6832 0 : start = TREE_OPERAND (t, 2);
6833 0 : istart = tree_to_shwi (start);
6834 0 : isize = tree_to_shwi (TREE_OPERAND (t, 1));
6835 0 : utype = TREE_TYPE (t);
6836 0 : if (!TYPE_UNSIGNED (utype))
6837 0 : utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
6838 0 : retval = build_int_cst (utype, 0);
6839 0 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6840 : {
6841 0 : tree bitpos = bit_position (field);
6842 0 : STRIP_ANY_LOCATION_WRAPPER (value);
6843 0 : if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
6844 : return value;
6845 0 : if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
6846 0 : && TREE_CODE (value) == INTEGER_CST
6847 0 : && tree_fits_shwi_p (bitpos)
6848 0 : && tree_fits_shwi_p (DECL_SIZE (field)))
6849 : {
6850 0 : HOST_WIDE_INT bit = tree_to_shwi (bitpos);
6851 0 : HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
6852 0 : HOST_WIDE_INT shift;
6853 0 : if (bit >= istart && bit + sz <= istart + isize)
6854 : {
6855 0 : fldval = fold_convert (utype, value);
6856 0 : mask = build_int_cst_type (utype, -1);
6857 0 : mask = fold_build2 (LSHIFT_EXPR, utype, mask,
6858 : size_int (TYPE_PRECISION (utype) - sz));
6859 0 : mask = fold_build2 (RSHIFT_EXPR, utype, mask,
6860 : size_int (TYPE_PRECISION (utype) - sz));
6861 0 : fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
6862 0 : shift = bit - istart;
6863 0 : if (BYTES_BIG_ENDIAN)
6864 : shift = TYPE_PRECISION (utype) - shift - sz;
6865 0 : fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
6866 : size_int (shift));
6867 0 : retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
6868 0 : fld_seen = true;
6869 : }
6870 : }
6871 : }
6872 0 : if (fld_seen)
6873 0 : return fold_convert (TREE_TYPE (t), retval);
6874 0 : gcc_unreachable ();
6875 : return error_mark_node;
6876 : }
6877 :
6878 : /* Helper for cxx_eval_bit_cast.
6879 : Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From
6880 : types and types of all subobjects have is_union_v<T>, is_pointer_v<T>,
6881 : is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static
6882 : data members of reference or std::meta::info type. */
6883 :
6884 : static bool
6885 56312 : check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
6886 : tree orig_type)
6887 : {
6888 57312 : if (TREE_CODE (type) == UNION_TYPE)
6889 : {
6890 63 : if (!ctx->quiet)
6891 : {
6892 21 : if (type == orig_type)
6893 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6894 : "a union type", "__builtin_bit_cast", type);
6895 : else
6896 15 : error_at (loc, "%qs is not a constant expression because %qT "
6897 : "contains a union type", "__builtin_bit_cast",
6898 : orig_type);
6899 : }
6900 : return true;
6901 : }
6902 : if (TREE_CODE (type) == POINTER_TYPE)
6903 : {
6904 57 : if (!ctx->quiet)
6905 : {
6906 18 : if (type == orig_type)
6907 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6908 : "a pointer type", "__builtin_bit_cast", type);
6909 : else
6910 12 : error_at (loc, "%qs is not a constant expression because %qT "
6911 : "contains a pointer type", "__builtin_bit_cast",
6912 : orig_type);
6913 : }
6914 : return true;
6915 : }
6916 : if (TREE_CODE (type) == REFERENCE_TYPE)
6917 : {
6918 0 : if (!ctx->quiet)
6919 : {
6920 0 : if (type == orig_type)
6921 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6922 : "a reference type", "__builtin_bit_cast", type);
6923 : else
6924 0 : error_at (loc, "%qs is not a constant expression because %qT "
6925 : "contains a reference type", "__builtin_bit_cast",
6926 : orig_type);
6927 : }
6928 : return true;
6929 : }
6930 39316 : if (TYPE_PTRMEM_P (type))
6931 : {
6932 36 : if (!ctx->quiet)
6933 : {
6934 12 : if (type == orig_type)
6935 12 : error_at (loc, "%qs is not a constant expression because %qT is "
6936 : "a pointer to member type", "__builtin_bit_cast",
6937 : type);
6938 : else
6939 0 : error_at (loc, "%qs is not a constant expression because %qT "
6940 : "contains a pointer to member type",
6941 : "__builtin_bit_cast", orig_type);
6942 : }
6943 : return true;
6944 : }
6945 57156 : if (TYPE_VOLATILE (type))
6946 : {
6947 0 : if (!ctx->quiet)
6948 : {
6949 0 : if (type == orig_type)
6950 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6951 : "volatile", "__builtin_bit_cast", type);
6952 : else
6953 0 : error_at (loc, "%qs is not a constant expression because %qT "
6954 : "contains a volatile subobject",
6955 : "__builtin_bit_cast", orig_type);
6956 : }
6957 : return true;
6958 : }
6959 57156 : if (REFLECTION_TYPE_P (type))
6960 : {
6961 22 : if (!ctx->quiet)
6962 : {
6963 6 : if (type == orig_type)
6964 4 : error_at (loc, "%qs is not a constant expression because its "
6965 : "type is %qs", "__builtin_bit_cast", "std::meta::info");
6966 : else
6967 2 : error_at (loc, "%qs is not a constant expression because %qT "
6968 : "contains %qs type",
6969 : "__builtin_bit_cast", orig_type, "std::meta::info");
6970 : }
6971 : return true;
6972 : }
6973 57134 : if (TREE_CODE (type) == RECORD_TYPE)
6974 2294092 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6975 2254890 : if (TREE_CODE (field) == FIELD_DECL
6976 2254890 : && check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
6977 : return true;
6978 57038 : if (TREE_CODE (type) == ARRAY_TYPE)
6979 1000 : return check_bit_cast_type (ctx, loc, TREE_TYPE (type), orig_type);
6980 : return false;
6981 : }
6982 :
6983 : /* Helper function for cxx_eval_bit_cast. For unsigned char or
6984 : std::byte members of CONSTRUCTOR (recursively) if they contain
6985 : some indeterminate bits (as set in MASK), remove the ctor elts,
6986 : mark the CONSTRUCTOR as CONSTRUCTOR_NO_CLEARING and clear the
6987 : bits in MASK. */
6988 :
6989 : static void
6990 9631 : clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask)
6991 : {
6992 9631 : if (TREE_CODE (t) != CONSTRUCTOR)
6993 : return;
6994 :
6995 : unsigned i, j = 0;
6996 : tree index, value;
6997 23564 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)
6998 : {
6999 13933 : tree type = TREE_TYPE (value);
7000 13933 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
7001 27427 : && DECL_BIT_FIELD_TYPE (index) != NULL_TREE)
7002 : {
7003 270 : if (is_byte_access_type_not_plain_char (DECL_BIT_FIELD_TYPE (index)))
7004 : {
7005 135 : HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (index));
7006 135 : gcc_assert (fldsz != 0);
7007 135 : HOST_WIDE_INT pos = int_byte_position (index);
7008 135 : HOST_WIDE_INT bpos
7009 135 : = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (index));
7010 135 : bpos %= BITS_PER_UNIT;
7011 135 : HOST_WIDE_INT end
7012 135 : = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
7013 135 : gcc_assert (end == 1 || end == 2);
7014 135 : unsigned char *p = mask + pos;
7015 135 : unsigned char mask_save[2];
7016 135 : mask_save[0] = mask[pos];
7017 135 : mask_save[1] = end == 2 ? mask[pos + 1] : 0;
7018 135 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
7019 : sorry_at (loc, "PDP11 bit-field handling unsupported"
7020 : " in %qs", "__builtin_bit_cast");
7021 135 : else if (BYTES_BIG_ENDIAN)
7022 : {
7023 : /* Big endian. */
7024 : if (bpos + fldsz <= BITS_PER_UNIT)
7025 : *p &= ~(((1 << fldsz) - 1)
7026 : << (BITS_PER_UNIT - bpos - fldsz));
7027 : else
7028 : {
7029 : gcc_assert (bpos);
7030 : *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
7031 : p++;
7032 : fldsz -= BITS_PER_UNIT - bpos;
7033 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
7034 : *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
7035 : }
7036 : }
7037 : else
7038 : {
7039 : /* Little endian. */
7040 135 : if (bpos + fldsz <= BITS_PER_UNIT)
7041 135 : *p &= ~(((1 << fldsz) - 1) << bpos);
7042 : else
7043 : {
7044 0 : gcc_assert (bpos);
7045 0 : *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
7046 0 : p++;
7047 0 : fldsz -= BITS_PER_UNIT - bpos;
7048 0 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
7049 0 : *p &= ~((1 << fldsz) - 1);
7050 : }
7051 : }
7052 135 : if (mask_save[0] != mask[pos]
7053 99 : || (end == 2 && mask_save[1] != mask[pos + 1]))
7054 : {
7055 36 : CONSTRUCTOR_NO_CLEARING (t) = 1;
7056 36 : continue;
7057 : }
7058 : }
7059 : }
7060 13663 : else if (is_byte_access_type_not_plain_char (type))
7061 : {
7062 228 : HOST_WIDE_INT pos;
7063 228 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7064 132 : pos = tree_to_shwi (index);
7065 : else
7066 96 : pos = int_byte_position (index);
7067 228 : if (mask[pos])
7068 : {
7069 48 : CONSTRUCTOR_NO_CLEARING (t) = 1;
7070 48 : mask[pos] = 0;
7071 48 : continue;
7072 : }
7073 : }
7074 13849 : if (TREE_CODE (value) == CONSTRUCTOR)
7075 : {
7076 7292 : HOST_WIDE_INT pos;
7077 7292 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7078 144 : pos = tree_to_shwi (index)
7079 72 : * tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))));
7080 : else
7081 7220 : pos = int_byte_position (index);
7082 7292 : clear_uchar_or_std_byte_in_mask (loc, value, mask + pos);
7083 : }
7084 13849 : if (i != j)
7085 : {
7086 180 : CONSTRUCTOR_ELT (t, j)->index = index;
7087 180 : CONSTRUCTOR_ELT (t, j)->value = value;
7088 : }
7089 13849 : ++j;
7090 : }
7091 19262 : if (CONSTRUCTOR_NELTS (t) != j)
7092 84 : vec_safe_truncate (CONSTRUCTOR_ELTS (t), j);
7093 : }
7094 :
7095 : /* Subroutine of cxx_eval_constant_expression.
7096 : Attempt to evaluate a BIT_CAST_EXPR. */
7097 :
7098 : static tree
7099 4047 : cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
7100 : bool *overflow_p, tree *jump_target)
7101 : {
7102 4047 : if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
7103 4047 : TREE_TYPE (t))
7104 12767 : || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0),
7105 3950 : EXPR_LOCATION (t)),
7106 3950 : TREE_TYPE (TREE_OPERAND (t, 0)),
7107 3950 : TREE_TYPE (TREE_OPERAND (t, 0))))
7108 : {
7109 178 : *non_constant_p = true;
7110 178 : return t;
7111 : }
7112 :
7113 3869 : tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue,
7114 : non_constant_p, overflow_p,
7115 : jump_target);
7116 3869 : if (*non_constant_p)
7117 : return t;
7118 2820 : if (*jump_target)
7119 : return NULL_TREE;
7120 :
7121 2820 : location_t loc = EXPR_LOCATION (t);
7122 2820 : if (BITS_PER_UNIT != 8 || CHAR_BIT != 8)
7123 : {
7124 : if (!ctx->quiet)
7125 : sorry_at (loc, "%qs cannot be constant evaluated on the target",
7126 : "__builtin_bit_cast");
7127 : *non_constant_p = true;
7128 : return t;
7129 : }
7130 :
7131 2820 : if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))))
7132 : {
7133 0 : if (!ctx->quiet)
7134 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7135 : "type is too large", "__builtin_bit_cast");
7136 0 : *non_constant_p = true;
7137 0 : return t;
7138 : }
7139 :
7140 2820 : HOST_WIDE_INT len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t)));
7141 2820 : if (len < 0 || (int) len != len)
7142 : {
7143 0 : if (!ctx->quiet)
7144 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7145 : "type is too large", "__builtin_bit_cast");
7146 0 : *non_constant_p = true;
7147 0 : return t;
7148 : }
7149 :
7150 2820 : unsigned char buf[64];
7151 2820 : unsigned char *ptr, *mask;
7152 2820 : size_t alen = (size_t) len * 2;
7153 2820 : if (alen <= sizeof (buf))
7154 : ptr = buf;
7155 : else
7156 329 : ptr = XNEWVEC (unsigned char, alen);
7157 2820 : mask = ptr + (size_t) len;
7158 : /* At the beginning consider everything indeterminate. */
7159 2820 : memset (mask, ~0, (size_t) len);
7160 :
7161 2820 : if (native_encode_initializer (op, ptr, len, 0, mask) != len)
7162 : {
7163 0 : if (!ctx->quiet)
7164 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7165 : "argument cannot be encoded", "__builtin_bit_cast");
7166 0 : *non_constant_p = true;
7167 0 : if (ptr != buf)
7168 0 : XDELETE (ptr);
7169 : return t;
7170 : }
7171 :
7172 2820 : tree r = NULL_TREE;
7173 2820 : if (can_native_interpret_type_p (TREE_TYPE (t)))
7174 : {
7175 481 : r = native_interpret_expr (TREE_TYPE (t), ptr, len);
7176 481 : if (is_byte_access_type_not_plain_char (TREE_TYPE (t)))
7177 : {
7178 52 : gcc_assert (len == 1);
7179 52 : if (mask[0])
7180 : {
7181 27 : memset (mask, 0, len);
7182 27 : r = build_constructor (TREE_TYPE (r), NULL);
7183 27 : CONSTRUCTOR_NO_CLEARING (r) = 1;
7184 : }
7185 : }
7186 : }
7187 2339 : else if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
7188 : {
7189 2339 : r = native_interpret_aggregate (TREE_TYPE (t), ptr, 0, len);
7190 2339 : if (r != NULL_TREE)
7191 : {
7192 2339 : clear_type_padding_in_mask (TREE_TYPE (t), mask);
7193 2339 : clear_uchar_or_std_byte_in_mask (loc, r, mask);
7194 2339 : if (CHECKING_P)
7195 : {
7196 2339 : tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue,
7197 : non_constant_p, overflow_p,
7198 : jump_target);
7199 2339 : gcc_checking_assert (e == r && !*jump_target);
7200 : r = e;
7201 : }
7202 : }
7203 : }
7204 :
7205 2820 : if (r != NULL_TREE)
7206 : {
7207 92041 : for (int i = 0; i < len; i++)
7208 89311 : if (mask[i])
7209 : {
7210 90 : if (!ctx->quiet)
7211 30 : error_at (loc, "%qs accessing uninitialized byte at offset %d",
7212 : "__builtin_bit_cast", i);
7213 90 : *non_constant_p = true;
7214 90 : r = t;
7215 90 : break;
7216 : }
7217 2820 : if (ptr != buf)
7218 329 : XDELETE (ptr);
7219 : return r;
7220 : }
7221 :
7222 0 : if (!ctx->quiet)
7223 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7224 : "argument cannot be interpreted", "__builtin_bit_cast");
7225 0 : *non_constant_p = true;
7226 0 : if (ptr != buf)
7227 0 : XDELETE (ptr);
7228 : return t;
7229 : }
7230 :
7231 : /* Subroutine of cxx_eval_constant_expression.
7232 : Evaluate a short-circuited logical expression T in the context
7233 : of a given constexpr CALL. BAILOUT_VALUE is the value for
7234 : early return. CONTINUE_VALUE is used here purely for
7235 : sanity check purposes. */
7236 :
7237 : static tree
7238 18692755 : cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
7239 : tree bailout_value, tree continue_value,
7240 : bool *non_constant_p, bool *overflow_p,
7241 : tree *jump_target)
7242 : {
7243 18692755 : tree r;
7244 18692755 : tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
7245 : vc_prvalue, non_constant_p,
7246 : overflow_p, jump_target);
7247 18692753 : if (*jump_target)
7248 : return NULL_TREE;
7249 18692744 : VERIFY_CONSTANT (lhs);
7250 13890026 : if (tree_int_cst_equal (lhs, bailout_value))
7251 : return lhs;
7252 11831128 : gcc_assert (tree_int_cst_equal (lhs, continue_value));
7253 11831128 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
7254 : vc_prvalue, non_constant_p,
7255 : overflow_p, jump_target);
7256 11831128 : if (*jump_target)
7257 : return NULL_TREE;
7258 11831128 : VERIFY_CONSTANT (r);
7259 : return r;
7260 : }
7261 :
7262 : /* REF is a COMPONENT_REF designating a particular field. V is a vector of
7263 : CONSTRUCTOR elements to initialize (part of) an object containing that
7264 : field. Return a pointer to the constructor_elt corresponding to the
7265 : initialization of the field. */
7266 :
7267 : static constructor_elt *
7268 0 : base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
7269 : {
7270 0 : tree aggr = TREE_OPERAND (ref, 0);
7271 0 : tree field = TREE_OPERAND (ref, 1);
7272 0 : HOST_WIDE_INT i;
7273 0 : constructor_elt *ce;
7274 :
7275 0 : gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
7276 :
7277 0 : if (TREE_CODE (aggr) == COMPONENT_REF)
7278 : {
7279 0 : constructor_elt *base_ce
7280 0 : = base_field_constructor_elt (v, aggr);
7281 0 : v = CONSTRUCTOR_ELTS (base_ce->value);
7282 : }
7283 :
7284 0 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
7285 0 : if (ce->index == field)
7286 0 : return ce;
7287 :
7288 0 : gcc_unreachable ();
7289 : return NULL;
7290 : }
7291 :
7292 : /* Some of the expressions fed to the constexpr mechanism are calls to
7293 : constructors, which have type void. In that case, return the type being
7294 : initialized by the constructor. */
7295 :
7296 : static tree
7297 613498004 : initialized_type (tree t)
7298 : {
7299 615163122 : if (TYPE_P (t))
7300 : return t;
7301 615162658 : tree type = TREE_TYPE (t);
7302 615162658 : if (TREE_CODE (t) == CALL_EXPR)
7303 : {
7304 : /* A constructor call has void type, so we need to look deeper. */
7305 74394398 : tree fn = get_function_named_in_call (t);
7306 74387913 : if (fn && TREE_CODE (fn) == FUNCTION_DECL
7307 148655470 : && DECL_CXX_CONSTRUCTOR_P (fn))
7308 4114769 : type = DECL_CONTEXT (fn);
7309 : }
7310 540768260 : else if (TREE_CODE (t) == COMPOUND_EXPR)
7311 1665118 : return initialized_type (TREE_OPERAND (t, 1));
7312 539103142 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
7313 885248 : type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
7314 613497540 : return cv_unqualified (type);
7315 : }
7316 :
7317 : /* We're about to initialize element INDEX of an array or class from VALUE.
7318 : Set up NEW_CTX appropriately by adjusting .object to refer to the
7319 : subobject and creating a new CONSTRUCTOR if the element is itself
7320 : a class or array. */
7321 :
7322 : static void
7323 4200211 : init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
7324 : tree index, tree &value)
7325 : {
7326 4200211 : new_ctx = *ctx;
7327 :
7328 4200211 : if (index && TREE_CODE (index) != INTEGER_CST
7329 3762979 : && TREE_CODE (index) != FIELD_DECL
7330 3 : && TREE_CODE (index) != RANGE_EXPR)
7331 : /* This won't have an element in the new CONSTRUCTOR. */
7332 : return;
7333 :
7334 4200211 : tree type = initialized_type (value);
7335 4200211 : if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
7336 : /* A non-aggregate member doesn't get its own CONSTRUCTOR. */
7337 : return;
7338 :
7339 1701027 : tree ctxtype = NULL_TREE;
7340 1701027 : if (ctx->ctor)
7341 1701010 : ctxtype = TREE_TYPE (ctx->ctor);
7342 17 : else if (ctx->object)
7343 14 : ctxtype = TREE_TYPE (ctx->object);
7344 : else
7345 : {
7346 : /* This can happen if the enclosing object is also an empty subobject
7347 : (c++/125315). */
7348 3 : gcc_checking_assert (is_empty_field (index));
7349 : return;
7350 : }
7351 :
7352 1701024 : if (VECTOR_TYPE_P (type)
7353 7417 : && VECTOR_TYPE_P (ctxtype)
7354 2596 : && index == NULL_TREE)
7355 : /* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
7356 : vector is constructed from smaller vectors, doesn't get its own
7357 : CONSTRUCTOR either. */
7358 : return;
7359 :
7360 : /* The sub-aggregate initializer might contain a placeholder;
7361 : update object to refer to the subobject and ctor to refer to
7362 : the (newly created) sub-initializer. */
7363 1698428 : if (ctx->object)
7364 : {
7365 1535115 : if (index == NULL_TREE || TREE_CODE (index) == RANGE_EXPR)
7366 : /* There's no well-defined subobject for this index. */
7367 3 : new_ctx.object = NULL_TREE;
7368 : else
7369 1535112 : new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
7370 : }
7371 :
7372 1698428 : if (is_empty_field (index)
7373 1698428 : && TREE_CODE (ctxtype) != UNION_TYPE)
7374 : /* Leave ctor null for an empty subobject of a non-union class, they aren't
7375 : represented in the result of evaluation. */
7376 1523051 : new_ctx.ctor = NULL_TREE;
7377 : else
7378 : {
7379 175377 : tree elt = build_constructor (type, NULL);
7380 175377 : CONSTRUCTOR_NO_CLEARING (elt) = true;
7381 175377 : new_ctx.ctor = elt;
7382 : }
7383 :
7384 1698428 : if (TREE_CODE (value) == TARGET_EXPR)
7385 : /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */
7386 119834 : value = TARGET_EXPR_INITIAL (value);
7387 : }
7388 :
7389 : /* We're about to process an initializer for a class or array TYPE. Make
7390 : sure that CTX is set up appropriately. */
7391 :
7392 : static void
7393 3394348 : verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
7394 : {
7395 : /* We don't bother building a ctor for an empty base subobject. */
7396 3394348 : if (is_empty_class (type))
7397 : return;
7398 :
7399 : /* We're in the middle of an initializer that might involve placeholders;
7400 : our caller should have created a CONSTRUCTOR for us to put the
7401 : initializer into. We will either return that constructor or T. */
7402 1889097 : gcc_assert (ctx->ctor);
7403 1889097 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
7404 : (type, TREE_TYPE (ctx->ctor)));
7405 : /* We used to check that ctx->ctor was empty, but that isn't the case when
7406 : the object is zero-initialized before calling the constructor. */
7407 1889097 : if (ctx->object)
7408 : {
7409 1673421 : tree otype = TREE_TYPE (ctx->object);
7410 1673421 : gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)
7411 : /* Handle flexible array members. */
7412 : || (TREE_CODE (otype) == ARRAY_TYPE
7413 : && TYPE_DOMAIN (otype) == NULL_TREE
7414 : && TREE_CODE (type) == ARRAY_TYPE
7415 : && (same_type_ignoring_top_level_qualifiers_p
7416 : (TREE_TYPE (type), TREE_TYPE (otype)))));
7417 : }
7418 1889097 : gcc_assert (!ctx->object || !DECL_P (ctx->object)
7419 : || ctx->global->get_value (ctx->object) == ctx->ctor);
7420 : }
7421 :
7422 : /* Subroutine of cxx_eval_constant_expression.
7423 : The expression tree T denotes a C-style array or a C-style
7424 : aggregate. Reduce it to a constant expression. */
7425 :
7426 : static tree
7427 3393440 : cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
7428 : value_cat lval,
7429 : bool *non_constant_p, bool *overflow_p,
7430 : tree *jump_target)
7431 : {
7432 3393440 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
7433 3393440 : bool changed = false;
7434 3393440 : gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
7435 3393440 : tree type = TREE_TYPE (t);
7436 :
7437 3393440 : constexpr_ctx new_ctx;
7438 3393440 : if (TYPE_PTRMEMFUNC_P (type) || VECTOR_TYPE_P (type))
7439 : {
7440 : /* We don't really need the ctx->ctor business for a PMF or
7441 : vector, but it's simpler to use the same code. */
7442 56001 : new_ctx = *ctx;
7443 56001 : new_ctx.ctor = build_constructor (type, NULL);
7444 56001 : new_ctx.object = NULL_TREE;
7445 56001 : ctx = &new_ctx;
7446 3393440 : };
7447 3393440 : verify_ctor_sanity (ctx, type);
7448 3393440 : vec<constructor_elt, va_gc> **p = nullptr;
7449 3393440 : if (ctx->ctor)
7450 : {
7451 3393423 : p = &CONSTRUCTOR_ELTS (ctx->ctor);
7452 6783395 : vec_alloc (*p, vec_safe_length (v));
7453 3393423 : if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t))
7454 16085 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1;
7455 : }
7456 :
7457 3393440 : unsigned i;
7458 3393440 : tree index, value;
7459 3393440 : bool constant_p = true;
7460 3393440 : bool side_effects_p = false;
7461 6860554 : FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
7462 : {
7463 4193770 : tree orig_value = value;
7464 4193770 : init_subob_ctx (ctx, new_ctx, index, value);
7465 : /* Like in cxx_eval_store_expression, omit entries for empty fields. */
7466 4193770 : bool no_slot = new_ctx.ctor == NULL_TREE;
7467 4193770 : int pos_hint = -1;
7468 4193770 : if (!ctx->ctor)
7469 : /* The enclosing object could be an empty subobject so we have no
7470 : CONSTRUCTOR (c++/125336). */
7471 17 : gcc_checking_assert (is_empty_class (type));
7472 4193753 : else if (new_ctx.ctor != ctx->ctor && !no_slot)
7473 : {
7474 : /* If we built a new CONSTRUCTOR, attach it now so that other
7475 : initializers can refer to it. */
7476 169237 : constructor_elt *cep = get_or_insert_ctor_field (ctx->ctor, index);
7477 169237 : cep->value = new_ctx.ctor;
7478 169237 : pos_hint = cep - (*p)->begin();
7479 169237 : }
7480 4024516 : else if (TREE_CODE (type) == UNION_TYPE)
7481 : /* Otherwise if we're constructing a non-aggregate union member, set
7482 : the active union member now so that we can later detect and diagnose
7483 : if its initializer attempts to activate another member. */
7484 1089 : get_or_insert_ctor_field (ctx->ctor, index);
7485 4193770 : tree elt = cxx_eval_constant_expression (&new_ctx, value,
7486 : lval,
7487 : non_constant_p, overflow_p,
7488 : jump_target);
7489 4193770 : if (*jump_target)
7490 : return NULL_TREE;
7491 : /* Don't VERIFY_CONSTANT here. */
7492 4193764 : if (ctx->quiet && *non_constant_p)
7493 : break;
7494 3467114 : if (elt != orig_value)
7495 1237711 : changed = true;
7496 :
7497 3467114 : if (!TREE_CONSTANT (elt))
7498 952816 : constant_p = false;
7499 3467114 : if (TREE_SIDE_EFFECTS (elt))
7500 281 : side_effects_p = true;
7501 3467114 : if (index && TREE_CODE (index) == COMPONENT_REF)
7502 : {
7503 : /* This is an initialization of a vfield inside a base
7504 : subaggregate that we already initialized; push this
7505 : initialization into the previous initialization. */
7506 0 : constructor_elt *inner = base_field_constructor_elt (*p, index);
7507 0 : inner->value = elt;
7508 0 : changed = true;
7509 0 : }
7510 3467114 : else if (no_slot)
7511 : /* This is an initializer for an empty field; now that we've
7512 : checked that it's constant, we can ignore it. */
7513 : changed = true;
7514 1945233 : else if (ctx->ctor)
7515 : {
7516 1945233 : if (TREE_CODE (type) == UNION_TYPE
7517 1945233 : && (*p)->last().index != index)
7518 : /* The initializer erroneously changed the active union member that
7519 : we're initializing. */
7520 7 : gcc_assert (*non_constant_p);
7521 : else
7522 : {
7523 : /* The initializer might have mutated the underlying CONSTRUCTOR,
7524 : so recompute the location of the target constructer_elt. */
7525 1945226 : constructor_elt *cep
7526 1945226 : = get_or_insert_ctor_field (ctx->ctor, index, pos_hint);
7527 1945226 : cep->value = elt;
7528 : }
7529 :
7530 : /* Adding or replacing an element might change the ctor's flags. */
7531 1945233 : TREE_CONSTANT (ctx->ctor) = constant_p;
7532 1945233 : TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
7533 : }
7534 : }
7535 3393434 : if (*non_constant_p)
7536 : return t;
7537 2666717 : if (!changed)
7538 : {
7539 268161 : if (VECTOR_TYPE_P (type))
7540 14408 : t = fold (t);
7541 : return t;
7542 : }
7543 2398556 : t = ctx->ctor;
7544 2398556 : if (!t)
7545 8 : t = build_constructor (type, NULL);
7546 : /* We're done building this CONSTRUCTOR, so now we can interpret an
7547 : element without an explicit initializer as value-initialized. */
7548 2398556 : CONSTRUCTOR_NO_CLEARING (t) = false;
7549 2398556 : TREE_CONSTANT (t) = constant_p;
7550 2398556 : TREE_SIDE_EFFECTS (t) = side_effects_p;
7551 2398556 : if (VECTOR_TYPE_P (type))
7552 11444 : t = fold (t);
7553 : return t;
7554 : }
7555 :
7556 : /* Subroutine of cxx_eval_constant_expression.
7557 : The expression tree T is a VEC_INIT_EXPR which denotes the desired
7558 : initialization of a non-static data member of array type. Reduce it to a
7559 : CONSTRUCTOR.
7560 :
7561 : Note that apart from value-initialization (when VALUE_INIT is true),
7562 : this is only intended to support value-initialization and the
7563 : initializations done by defaulted constructors for classes with
7564 : non-static data members of array type. In this case, VEC_INIT_EXPR_INIT
7565 : will either be NULL_TREE for the default constructor, or a COMPONENT_REF
7566 : for the copy/move constructor. */
7567 :
7568 : static tree
7569 908 : cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
7570 : bool value_init, value_cat lval,
7571 : bool *non_constant_p, bool *overflow_p,
7572 : tree *jump_target)
7573 : {
7574 908 : tree elttype = TREE_TYPE (atype);
7575 908 : verify_ctor_sanity (ctx, atype);
7576 908 : vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
7577 908 : bool pre_init = false;
7578 908 : unsigned HOST_WIDE_INT i;
7579 908 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7580 :
7581 908 : if (init && TREE_CODE (init) == CONSTRUCTOR)
7582 0 : return cxx_eval_bare_aggregate (ctx, init, lval,
7583 0 : non_constant_p, overflow_p, jump_target);
7584 :
7585 : /* We already checked access when building the VEC_INIT_EXPR. */
7586 908 : deferring_access_check_sentinel acs (dk_deferred);
7587 :
7588 : /* For the default constructor, build up a call to the default
7589 : constructor of the element type. We only need to handle class types
7590 : here, as for a constructor to be constexpr, all members must be
7591 : initialized, which for a defaulted default constructor means they must
7592 : be of a class type with a constexpr default constructor. */
7593 908 : if (TREE_CODE (elttype) == ARRAY_TYPE)
7594 : /* We only do this at the lowest level. */;
7595 854 : else if (value_init)
7596 : {
7597 338 : init = build_value_init (elttype, complain);
7598 338 : pre_init = true;
7599 : }
7600 516 : else if (!init)
7601 : {
7602 404 : releasing_vec argvec;
7603 404 : init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
7604 : &argvec, elttype, LOOKUP_NORMAL,
7605 : complain);
7606 404 : init = build_aggr_init_expr (elttype, init);
7607 404 : pre_init = true;
7608 404 : }
7609 :
7610 908 : bool zeroed_out = false;
7611 908 : if (!CONSTRUCTOR_NO_CLEARING (ctx->ctor))
7612 : {
7613 : /* We're initializing an array object that had been zero-initialized
7614 : earlier. Truncate ctx->ctor, and propagate its zeroed state by
7615 : clearing CONSTRUCTOR_NO_CLEARING on each of the aggregate element
7616 : initializers we append to it. */
7617 156 : gcc_checking_assert (initializer_zerop (ctx->ctor));
7618 156 : zeroed_out = true;
7619 156 : vec_safe_truncate (*p, 0);
7620 : }
7621 :
7622 908 : tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
7623 : overflow_p, jump_target);
7624 908 : if (*jump_target)
7625 : return NULL_TREE;
7626 908 : unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
7627 6678 : for (i = 0; i < max; ++i)
7628 : {
7629 6441 : tree idx = build_int_cst (size_type_node, i);
7630 6441 : tree eltinit;
7631 6441 : bool reuse = false;
7632 6441 : constexpr_ctx new_ctx;
7633 6905 : init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
7634 6441 : bool no_slot = new_ctx.ctor == NULL_TREE;
7635 6441 : if (new_ctx.ctor != ctx->ctor && !no_slot)
7636 : {
7637 6140 : if (zeroed_out)
7638 5445 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = false;
7639 6140 : CONSTRUCTOR_APPEND_ELT (*p, idx, new_ctx.ctor);
7640 : }
7641 6441 : if (TREE_CODE (elttype) == ARRAY_TYPE)
7642 : {
7643 : /* A multidimensional array; recurse. */
7644 186 : if (value_init || init == NULL_TREE)
7645 : {
7646 176 : eltinit = NULL_TREE;
7647 176 : reuse = i == 0;
7648 : }
7649 : else
7650 10 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7651 186 : eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit,
7652 : value_init, lval, non_constant_p,
7653 : overflow_p, jump_target);
7654 : }
7655 6255 : else if (pre_init)
7656 : {
7657 : /* Initializing an element using value or default initialization
7658 : we just pre-built above. */
7659 5977 : if (init == void_node)
7660 : /* Trivial default-init, don't do anything to the CONSTRUCTOR. */
7661 10 : return ctx->ctor;
7662 5967 : eltinit = init;
7663 5967 : if (CLASS_TYPE_P (elttype) && new_ctx.object)
7664 : /* Clarify what object is being initialized (118285). */
7665 5667 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7666 5967 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7667 : non_constant_p, overflow_p,
7668 : jump_target);
7669 5967 : reuse = i == 0;
7670 : }
7671 : else
7672 : {
7673 : /* Copying an element. */
7674 278 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7675 278 : if (!lvalue_p (init))
7676 232 : eltinit = move (eltinit);
7677 278 : eltinit = (perform_implicit_conversion_flags
7678 278 : (elttype, eltinit, complain,
7679 : LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
7680 271 : if (CLASS_TYPE_P (elttype)
7681 271 : && new_ctx.object
7682 526 : && !error_operand_p (eltinit))
7683 : /* Clarify what object is being initialized (118285). */
7684 244 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7685 278 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7686 : non_constant_p, overflow_p,
7687 : jump_target);
7688 : }
7689 6431 : if (*jump_target)
7690 : return NULL_TREE;
7691 6431 : if (*non_constant_p)
7692 : break;
7693 6251 : if (no_slot)
7694 : {
7695 : /* This is an initializer for an empty subobject; now that we've
7696 : checked that it's constant, we can ignore it. */
7697 0 : gcc_checking_assert (i == 0);
7698 : break;
7699 : }
7700 6251 : else if (new_ctx.ctor != ctx->ctor)
7701 : {
7702 : /* We appended this element above; update the value. */
7703 5957 : gcc_assert ((*p)->last().index == idx);
7704 5957 : (*p)->last().value = eltinit;
7705 : }
7706 : else
7707 294 : CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
7708 : /* Reuse the result of cxx_eval_constant_expression call
7709 : from the first iteration to all others if it is a constant
7710 : initializer that doesn't require relocations. */
7711 6251 : if (reuse
7712 6251 : && max > 1
7713 6251 : && (eltinit == NULL_TREE
7714 634 : || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
7715 634 : == null_pointer_node)))
7716 : {
7717 481 : if (new_ctx.ctor != ctx->ctor)
7718 201 : eltinit = new_ctx.ctor;
7719 481 : tree range = build2 (RANGE_EXPR, size_type_node,
7720 : build_int_cst (size_type_node, 1),
7721 481 : build_int_cst (size_type_node, max - 1));
7722 481 : CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
7723 481 : break;
7724 : }
7725 5770 : else if (i == 0)
7726 234 : vec_safe_reserve (*p, max);
7727 : }
7728 :
7729 898 : if (!*non_constant_p)
7730 : {
7731 718 : init = ctx->ctor;
7732 718 : CONSTRUCTOR_NO_CLEARING (init) = false;
7733 : }
7734 898 : return init;
7735 : }
7736 :
7737 : static tree
7738 794 : cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
7739 : value_cat lval,
7740 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
7741 : {
7742 794 : tree atype = TREE_TYPE (t);
7743 794 : tree init = VEC_INIT_EXPR_INIT (t);
7744 794 : bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
7745 794 : if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
7746 : ;
7747 83 : else if (CONSTRUCTOR_NELTS (init) == 0
7748 83 : && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
7749 : {
7750 : /* Handle {} as value-init. */
7751 : init = NULL_TREE;
7752 : value_init = true;
7753 : }
7754 : else
7755 : {
7756 : /* This is a more complicated case, like needing to loop over trailing
7757 : elements; call build_vec_init and evaluate the result. */
7758 72 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7759 72 : constexpr_ctx new_ctx = *ctx;
7760 72 : if (!ctx->object)
7761 : {
7762 : /* We want to have an initialization target for an VEC_INIT_EXPR.
7763 : If we don't already have one in CTX, use the VEC_INIT_EXPR_SLOT. */
7764 57 : new_ctx.object = VEC_INIT_EXPR_SLOT (t);
7765 57 : tree ctor = new_ctx.ctor = build_constructor (atype, NULL);
7766 57 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
7767 57 : ctx->global->put_value (new_ctx.object, ctor);
7768 57 : ctx = &new_ctx;
7769 : }
7770 72 : init = expand_vec_init_expr (ctx->object, t, complain);
7771 72 : return cxx_eval_constant_expression (ctx, init, lval, non_constant_p,
7772 : overflow_p, jump_target);
7773 : }
7774 722 : tree r = cxx_eval_vec_init_1 (ctx, atype, init, value_init,
7775 : lval, non_constant_p, overflow_p, jump_target);
7776 722 : if (*non_constant_p)
7777 : return t;
7778 : else
7779 568 : return r;
7780 : }
7781 :
7782 : /* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
7783 : where the desired type is an array of unknown bounds because the variable
7784 : has had its bounds deduced since the wrapping expression was created. */
7785 :
7786 : static bool
7787 451491264 : same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
7788 : {
7789 451491264 : while (TREE_CODE (type1) == ARRAY_TYPE
7790 144752 : && TREE_CODE (type2) == ARRAY_TYPE
7791 451491268 : && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
7792 : {
7793 2 : type1 = TREE_TYPE (type1);
7794 2 : type2 = TREE_TYPE (type2);
7795 : }
7796 451491264 : return same_type_ignoring_top_level_qualifiers_p (type1, type2);
7797 : }
7798 :
7799 : /* Try to determine the currently active union member for an expression
7800 : with UNION_TYPE. If it can be determined, return the FIELD_DECL,
7801 : otherwise return NULL_TREE. */
7802 :
7803 : static tree
7804 86 : cxx_union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target)
7805 : {
7806 86 : constexpr_ctx new_ctx = *ctx;
7807 86 : new_ctx.quiet = true;
7808 86 : bool non_constant_p = false, overflow_p = false;
7809 86 : tree ctor = cxx_eval_constant_expression (&new_ctx, t, vc_prvalue,
7810 : &non_constant_p,
7811 : &overflow_p, jump_target);
7812 86 : if (*jump_target)
7813 : return NULL_TREE;
7814 86 : if (TREE_CODE (ctor) == CONSTRUCTOR
7815 32 : && CONSTRUCTOR_NELTS (ctor) == 1
7816 20 : && CONSTRUCTOR_ELT (ctor, 0)->index
7817 106 : && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL)
7818 : return CONSTRUCTOR_ELT (ctor, 0)->index;
7819 : return NULL_TREE;
7820 : }
7821 :
7822 : /* Helper function for cxx_fold_indirect_ref_1, called recursively. */
7823 :
7824 : static tree
7825 15379890 : cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
7826 : tree op, unsigned HOST_WIDE_INT off, bool *empty_base,
7827 : tree *jump_target)
7828 : {
7829 24978390 : tree optype = TREE_TYPE (op);
7830 24978390 : unsigned HOST_WIDE_INT const_nunits;
7831 24978390 : if (off == 0 && similar_type_p (optype, type))
7832 : return op;
7833 15375121 : else if (cxx_dialect >= cxx26
7834 9438083 : && VAR_P (op)
7835 5441904 : && DECL_VTABLE_OR_VTT_P (op)
7836 15691 : && same_type_ignoring_top_level_qualifiers_p (type,
7837 : ptrdiff_type_node)
7838 15376466 : && POINTER_TYPE_P (strip_array_types (optype)))
7839 : {
7840 : /* We often read some virtual table elements using ptrdiff_t rather
7841 : than pointer type. */
7842 1345 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc,
7843 : strip_array_types (optype),
7844 : op, off, empty_base,
7845 : jump_target))
7846 1345 : return fold_convert (type, ret);
7847 : }
7848 15373776 : else if (TREE_CODE (optype) == COMPLEX_TYPE
7849 15373776 : && similar_type_p (type, TREE_TYPE (optype)))
7850 : {
7851 : /* *(foo *)&complexfoo => __real__ complexfoo */
7852 0 : if (off == 0)
7853 0 : return build1_loc (loc, REALPART_EXPR, type, op);
7854 : /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
7855 0 : else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
7856 0 : return build1_loc (loc, IMAGPART_EXPR, type, op);
7857 : }
7858 : /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF<vectorfoo,...> */
7859 15373776 : else if (VECTOR_TYPE_P (optype)
7860 0 : && similar_type_p (type, TREE_TYPE (optype))
7861 15373776 : && TYPE_VECTOR_SUBPARTS (optype).is_constant (&const_nunits))
7862 : {
7863 0 : unsigned HOST_WIDE_INT part_width = tree_to_uhwi (TYPE_SIZE_UNIT (type));
7864 0 : unsigned HOST_WIDE_INT max_offset = part_width * const_nunits;
7865 0 : if (off < max_offset && off % part_width == 0)
7866 : {
7867 0 : tree index = bitsize_int (off * BITS_PER_UNIT);
7868 0 : return build3_loc (loc, BIT_FIELD_REF, type, op,
7869 0 : TYPE_SIZE (type), index);
7870 : }
7871 : }
7872 : /* ((foo *)&fooarray)[x] => fooarray[x] */
7873 15373776 : else if (TREE_CODE (optype) == ARRAY_TYPE
7874 9598500 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
7875 24972276 : && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
7876 : {
7877 9598500 : tree type_domain = TYPE_DOMAIN (optype);
7878 9598500 : tree min_val = size_zero_node;
7879 9598500 : if (type_domain && TYPE_MIN_VALUE (type_domain))
7880 9598271 : min_val = TYPE_MIN_VALUE (type_domain);
7881 9598500 : unsigned HOST_WIDE_INT el_sz
7882 9598500 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
7883 9598500 : unsigned HOST_WIDE_INT idx = off / el_sz;
7884 9598500 : unsigned HOST_WIDE_INT rem = off % el_sz;
7885 9598500 : if (tree_fits_uhwi_p (min_val))
7886 : {
7887 9598500 : tree index = size_int (idx + tree_to_uhwi (min_val));
7888 9598500 : op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
7889 : NULL_TREE, NULL_TREE);
7890 9598500 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
7891 9598500 : empty_base, jump_target);
7892 : }
7893 : }
7894 : /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
7895 5775276 : else if (TREE_CODE (optype) == RECORD_TYPE
7896 5775276 : || TREE_CODE (optype) == UNION_TYPE)
7897 : {
7898 5766702 : if (TREE_CODE (optype) == UNION_TYPE)
7899 : /* For unions prefer the currently active member. */
7900 86 : if (tree field = cxx_union_active_member (ctx, op, jump_target))
7901 : {
7902 20 : unsigned HOST_WIDE_INT el_sz
7903 20 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7904 20 : if (off < el_sz)
7905 : {
7906 20 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7907 : op, field, NULL_TREE);
7908 20 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7909 : off, empty_base,
7910 : jump_target))
7911 : return ret;
7912 : }
7913 : }
7914 :
7915 : /* Handle conversion to "as base" type. */
7916 5766688 : if (CLASS_TYPE_P (optype)
7917 11533212 : && CLASSTYPE_AS_BASE (optype) == type)
7918 : return op;
7919 :
7920 : /* Handle conversion to an empty base class, which is represented with a
7921 : NOP_EXPR. Do this before spelunking into the non-empty subobjects,
7922 : which is likely to be a waste of time (109678). */
7923 5761211 : if (is_empty_class (type)
7924 5422298 : && CLASS_TYPE_P (optype)
7925 11183503 : && lookup_base (optype, type, ba_any, NULL, tf_none, off))
7926 : {
7927 2641586 : if (empty_base)
7928 2641581 : *empty_base = true;
7929 : return op;
7930 : }
7931 :
7932 3119625 : for (tree field = TYPE_FIELDS (optype);
7933 44519296 : field; field = DECL_CHAIN (field))
7934 44473396 : if (TREE_CODE (field) == FIELD_DECL
7935 3132157 : && TREE_TYPE (field) != error_mark_node
7936 47605553 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (field))))
7937 : {
7938 3132153 : tree pos = byte_position (field);
7939 3132153 : if (!tree_fits_uhwi_p (pos))
7940 0 : continue;
7941 3132153 : unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos);
7942 3132153 : unsigned HOST_WIDE_INT el_sz;
7943 3132153 : if (DECL_FIELD_IS_BASE (field)
7944 779414 : && CLASS_TYPE_P (optype)
7945 3911567 : && CLASSTYPE_VBASECLASSES (optype))
7946 7765 : el_sz = tree_to_uhwi (DECL_SIZE_UNIT (field));
7947 : else
7948 3124388 : el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7949 3132153 : if (upos <= off && off < upos + el_sz)
7950 : {
7951 3119426 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7952 : op, field, NULL_TREE);
7953 3119426 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7954 : off - upos,
7955 : empty_base,
7956 : jump_target))
7957 : return ret;
7958 : }
7959 : }
7960 : }
7961 :
7962 : return NULL_TREE;
7963 : }
7964 :
7965 : /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
7966 : match. We want to be less strict for simple *& folding; if we have a
7967 : non-const temporary that we access through a const pointer, that should
7968 : work. We handle this here rather than change fold_indirect_ref_1
7969 : because we're dealing with things like ADDR_EXPR of INTEGER_CST which
7970 : don't really make sense outside of constant expression evaluation. Also
7971 : we want to allow folding to COMPONENT_REF, which could cause trouble
7972 : with TBAA in fold_indirect_ref_1. */
7973 :
7974 : static tree
7975 197905947 : cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
7976 : tree op0, bool *empty_base, tree *jump_target)
7977 : {
7978 197905947 : tree sub = op0;
7979 197905947 : tree subtype;
7980 :
7981 : /* STRIP_NOPS, but stop if REINTERPRET_CAST_P. */
7982 407773055 : while (CONVERT_EXPR_P (sub) || TREE_CODE (sub) == NON_LVALUE_EXPR
7983 532350708 : || TREE_CODE (sub) == VIEW_CONVERT_EXPR)
7984 : {
7985 134061633 : if (TREE_CODE (sub) == NOP_EXPR
7986 134061633 : && REINTERPRET_CAST_P (sub))
7987 : return NULL_TREE;
7988 134061633 : sub = TREE_OPERAND (sub, 0);
7989 : }
7990 :
7991 197905947 : subtype = TREE_TYPE (sub);
7992 197905947 : if (!INDIRECT_TYPE_P (subtype))
7993 : return NULL_TREE;
7994 :
7995 : /* Canonicalizes the given OBJ/OFF pair by iteratively absorbing
7996 : the innermost component into the offset until it would make the
7997 : offset positive, so that cxx_fold_indirect_ref_1 can identify
7998 : more folding opportunities. */
7999 210164997 : auto canonicalize_obj_off = [] (tree& obj, tree& off) {
8000 12259099 : if (cxx_dialect >= cxx26)
8001 : {
8002 : /* For C++26, we need to fold *(B *)(&x.D.1234 + 32) used
8003 : to access virtual base members. */
8004 7369613 : tree nobj = obj;
8005 7369613 : while (TREE_CODE (nobj) == COMPONENT_REF
8006 7405587 : && DECL_FIELD_IS_BASE (TREE_OPERAND (nobj, 1)))
8007 35974 : nobj = TREE_OPERAND (nobj, 0);
8008 7369613 : if (nobj != obj
8009 28269 : && CLASS_TYPE_P (TREE_TYPE (nobj))
8010 7397882 : && CLASSTYPE_VBASECLASSES (TREE_TYPE (nobj)))
8011 2537 : while (obj != nobj)
8012 : {
8013 1424 : tree field = TREE_OPERAND (obj, 1);
8014 1424 : tree pos = byte_position (field);
8015 1424 : off = int_const_binop (PLUS_EXPR, off, pos);
8016 1424 : obj = TREE_OPERAND (obj, 0);
8017 : }
8018 : }
8019 15368617 : while (TREE_CODE (obj) == COMPONENT_REF
8020 : /* We need to preserve union member accesses so that we can
8021 : later properly diagnose accessing the wrong member. */
8022 6433449 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (obj, 0))) == RECORD_TYPE
8023 21576342 : && (tree_int_cst_sign_bit (off) || integer_zerop (off)))
8024 : {
8025 3294439 : tree field = TREE_OPERAND (obj, 1);
8026 3294439 : tree pos = byte_position (field);
8027 3294439 : if (integer_zerop (off) && integer_nonzerop (pos))
8028 : /* If the offset is already 0, keep going as long as the
8029 : component is at position 0. */
8030 : break;
8031 3109518 : off = int_const_binop (PLUS_EXPR, off, pos);
8032 3109518 : obj = TREE_OPERAND (obj, 0);
8033 : }
8034 12259099 : };
8035 :
8036 197905898 : if (TREE_CODE (sub) == ADDR_EXPR)
8037 : {
8038 88342880 : tree op = TREE_OPERAND (sub, 0);
8039 88342880 : tree optype = TREE_TYPE (op);
8040 :
8041 : /* *&CONST_DECL -> to the value of the const decl. */
8042 88342880 : if (TREE_CODE (op) == CONST_DECL)
8043 0 : return DECL_INITIAL (op);
8044 : /* *&p => p; make sure to handle *&"str"[cst] here. */
8045 88342880 : if (similar_type_p (optype, type))
8046 : {
8047 84424590 : tree fop = fold_read_from_constant_string (op);
8048 84424590 : if (fop)
8049 : return fop;
8050 : else
8051 84214739 : return op;
8052 : }
8053 : else
8054 : {
8055 3918290 : tree off = integer_zero_node;
8056 3918290 : canonicalize_obj_off (op, off);
8057 3918290 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op,
8058 : tree_to_uhwi (off), empty_base,
8059 : jump_target);
8060 : }
8061 : }
8062 109563018 : else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
8063 109563018 : && tree_fits_uhwi_p (TREE_OPERAND (sub, 1)))
8064 : {
8065 8940092 : tree op00 = TREE_OPERAND (sub, 0);
8066 8940092 : tree off = TREE_OPERAND (sub, 1);
8067 :
8068 8940092 : STRIP_NOPS (op00);
8069 8940092 : if (TREE_CODE (op00) == ADDR_EXPR)
8070 : {
8071 8340809 : tree obj = TREE_OPERAND (op00, 0);
8072 8340809 : canonicalize_obj_off (obj, off);
8073 8340809 : return cxx_fold_indirect_ref_1 (ctx, loc, type, obj,
8074 : tree_to_uhwi (off), empty_base,
8075 : jump_target);
8076 : }
8077 : }
8078 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
8079 100622926 : else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
8080 100622926 : && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
8081 : {
8082 0 : tree type_domain;
8083 0 : tree min_val = size_zero_node;
8084 0 : tree newsub
8085 0 : = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL,
8086 : jump_target);
8087 0 : if (*jump_target)
8088 : return NULL_TREE;
8089 0 : if (newsub)
8090 : sub = newsub;
8091 : else
8092 0 : sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
8093 0 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
8094 0 : if (type_domain && TYPE_MIN_VALUE (type_domain))
8095 0 : min_val = TYPE_MIN_VALUE (type_domain);
8096 0 : return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
8097 0 : NULL_TREE);
8098 : }
8099 :
8100 : return NULL_TREE;
8101 : }
8102 :
8103 : static tree
8104 104550846 : cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
8105 : value_cat lval,
8106 : bool *non_constant_p, bool *overflow_p,
8107 : tree *jump_target)
8108 : {
8109 104550846 : tree orig_op0 = TREE_OPERAND (t, 0);
8110 104550846 : bool empty_base = false;
8111 :
8112 : /* We can handle a MEM_REF like an INDIRECT_REF, if MEM_REF's second
8113 : operand is an integer-zero. Otherwise reject the MEM_REF for now. */
8114 :
8115 104550846 : if (TREE_CODE (t) == MEM_REF
8116 104550846 : && (!TREE_OPERAND (t, 1) || !integer_zerop (TREE_OPERAND (t, 1))))
8117 : {
8118 9 : gcc_assert (ctx->quiet);
8119 9 : *non_constant_p = true;
8120 9 : return t;
8121 : }
8122 :
8123 : /* First try to simplify it directly. */
8124 104550837 : tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
8125 : orig_op0, &empty_base, jump_target);
8126 104550837 : if (*jump_target)
8127 : return NULL_TREE;
8128 104550837 : if (!r)
8129 : {
8130 : /* If that didn't work, evaluate the operand first. */
8131 100532863 : tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
8132 : vc_prvalue, non_constant_p,
8133 : overflow_p, jump_target);
8134 100532863 : if (*jump_target)
8135 : return NULL_TREE;
8136 : /* Don't VERIFY_CONSTANT here. */
8137 100532809 : if (*non_constant_p)
8138 : return t;
8139 :
8140 79488283 : if (!lval && integer_zerop (op0))
8141 : {
8142 73 : if (!ctx->quiet)
8143 12 : error ("dereferencing a null pointer");
8144 73 : *non_constant_p = true;
8145 73 : return t;
8146 : }
8147 :
8148 79488210 : r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0,
8149 : &empty_base, jump_target);
8150 79488210 : if (*jump_target)
8151 : return NULL_TREE;
8152 79488210 : if (r == NULL_TREE)
8153 : {
8154 : /* We couldn't fold to a constant value. Make sure it's not
8155 : something we should have been able to fold. */
8156 697831 : tree sub = op0;
8157 697831 : STRIP_NOPS (sub);
8158 697831 : if (TREE_CODE (sub) == ADDR_EXPR)
8159 : {
8160 4135 : gcc_assert (!similar_type_p
8161 : (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
8162 : /* DR 1188 says we don't have to deal with this. */
8163 4135 : if (!ctx->quiet)
8164 : {
8165 9 : auto_diagnostic_group d;
8166 15 : error_at (cp_expr_loc_or_input_loc (t),
8167 : "accessing value of %qT object through a %qT "
8168 : "glvalue in a constant expression",
8169 9 : TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t));
8170 9 : tree ob = build_fold_indirect_ref (sub);
8171 9 : if (DECL_P (ob))
8172 : {
8173 9 : if (DECL_ARTIFICIAL (ob))
8174 2 : inform (DECL_SOURCE_LOCATION (ob),
8175 2 : "%qT object created here", TREE_TYPE (ob));
8176 : else
8177 7 : inform (DECL_SOURCE_LOCATION (ob),
8178 : "%q#D declared here", ob);
8179 : }
8180 9 : }
8181 4135 : *non_constant_p = true;
8182 4135 : return t;
8183 : }
8184 :
8185 693696 : if (lval == vc_glvalue && op0 != orig_op0)
8186 83459 : return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
8187 610237 : if (!lval)
8188 499384 : VERIFY_CONSTANT (t);
8189 : return t;
8190 : }
8191 : }
8192 :
8193 82808353 : r = cxx_eval_constant_expression (ctx, r,
8194 : lval, non_constant_p, overflow_p,
8195 : jump_target);
8196 82808351 : if (*jump_target)
8197 : return NULL_TREE;
8198 82808351 : if (*non_constant_p)
8199 : return t;
8200 :
8201 : /* If we're pulling out the value of an empty base, just return an empty
8202 : CONSTRUCTOR. */
8203 73721694 : if (empty_base && !lval)
8204 : {
8205 19451 : r = build_constructor (TREE_TYPE (t), NULL);
8206 19451 : TREE_CONSTANT (r) = true;
8207 : }
8208 :
8209 : return r;
8210 : }
8211 :
8212 : /* Complain about R, a DECL that is accessed outside its lifetime. */
8213 :
8214 : static void
8215 45 : outside_lifetime_error (location_t loc, tree r)
8216 : {
8217 45 : auto_diagnostic_group d;
8218 45 : if (DECL_NAME (r) == heap_deleted_identifier)
8219 : {
8220 : /* Provide a more accurate message for deleted variables. */
8221 14 : error_at (loc, "use of allocated storage after deallocation "
8222 : "in a constant expression");
8223 14 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8224 : }
8225 : else
8226 : {
8227 31 : error_at (loc, "accessing %qE outside its lifetime", r);
8228 31 : inform (DECL_SOURCE_LOCATION (r), "declared here");
8229 : }
8230 45 : }
8231 :
8232 : /* Complain about R, a VAR_DECL, not being usable in a constant expression.
8233 : FUNDEF_P is true if we're checking a constexpr function body.
8234 : Shared between potential_constant_expression and
8235 : cxx_eval_constant_expression. */
8236 :
8237 : static void
8238 352 : non_const_var_error (location_t loc, tree r, bool fundef_p)
8239 : {
8240 352 : auto_diagnostic_group d;
8241 352 : tree type = TREE_TYPE (r);
8242 352 : if (DECL_NAME (r) == heap_uninit_identifier
8243 352 : || DECL_NAME (r) == heap_identifier
8244 349 : || DECL_NAME (r) == heap_vec_uninit_identifier
8245 701 : || DECL_NAME (r) == heap_vec_identifier)
8246 : {
8247 3 : if (constexpr_error (loc, fundef_p, "the content of uninitialized "
8248 : "storage is not usable in a constant expression"))
8249 3 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8250 : return;
8251 : }
8252 349 : if (DECL_NAME (r) == heap_deleted_identifier)
8253 : {
8254 0 : if (constexpr_error (loc, fundef_p, "use of allocated storage after "
8255 : "deallocation in a constant expression"))
8256 0 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8257 : return;
8258 : }
8259 349 : if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
8260 : "a constant expression", r))
8261 : return;
8262 : /* Avoid error cascade. */
8263 342 : if (DECL_INITIAL (r) == error_mark_node)
8264 : return;
8265 326 : if (DECL_DECLARED_CONSTEXPR_P (r))
8266 3 : inform (DECL_SOURCE_LOCATION (r),
8267 : "%qD used in its own initializer", r);
8268 323 : else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
8269 : {
8270 223 : if (!CP_TYPE_CONST_P (type))
8271 194 : inform (DECL_SOURCE_LOCATION (r),
8272 : "%q#D is not const", r);
8273 29 : else if (CP_TYPE_VOLATILE_P (type))
8274 0 : inform (DECL_SOURCE_LOCATION (r),
8275 : "%q#D is volatile", r);
8276 29 : else if (!DECL_INITIAL (r)
8277 9 : || !TREE_CONSTANT (DECL_INITIAL (r))
8278 37 : || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
8279 29 : inform (DECL_SOURCE_LOCATION (r),
8280 : "%qD was not initialized with a constant "
8281 : "expression", r);
8282 : else
8283 0 : gcc_unreachable ();
8284 : }
8285 100 : else if (TYPE_REF_P (type))
8286 9 : inform (DECL_SOURCE_LOCATION (r),
8287 : "%qD was not initialized with a constant "
8288 : "expression", r);
8289 : else
8290 : {
8291 91 : if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
8292 91 : inform (DECL_SOURCE_LOCATION (r),
8293 : "%qD was not declared %<constexpr%>", r);
8294 : else
8295 0 : inform (DECL_SOURCE_LOCATION (r),
8296 : "%qD does not have integral or enumeration type",
8297 : r);
8298 : }
8299 352 : }
8300 :
8301 : /* Subroutine of cxx_eval_constant_expression.
8302 : Like cxx_eval_unary_expression, except for trinary expressions. */
8303 :
8304 : static tree
8305 43640 : cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
8306 : value_cat lval,
8307 : bool *non_constant_p, bool *overflow_p,
8308 : tree *jump_target)
8309 : {
8310 43640 : int i;
8311 43640 : tree args[3];
8312 43640 : tree val;
8313 :
8314 168053 : for (i = 0; i < 3; i++)
8315 : {
8316 126582 : args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
8317 : lval,
8318 : non_constant_p, overflow_p,
8319 : jump_target);
8320 126582 : if (*jump_target)
8321 : return NULL_TREE;
8322 126582 : VERIFY_CONSTANT (args[i]);
8323 : }
8324 :
8325 41471 : val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
8326 : args[0], args[1], args[2]);
8327 41471 : if (val == NULL_TREE)
8328 : return t;
8329 41471 : VERIFY_CONSTANT (val);
8330 : return val;
8331 : }
8332 :
8333 : /* True if T was declared in a function declared to be constexpr, and
8334 : therefore potentially constant in C++14. */
8335 :
8336 : bool
8337 90135368 : var_in_constexpr_fn (tree t)
8338 : {
8339 90135368 : tree ctx = DECL_CONTEXT (t);
8340 90135368 : return (ctx && TREE_CODE (ctx) == FUNCTION_DECL
8341 171704761 : && DECL_DECLARED_CONSTEXPR_P (ctx));
8342 : }
8343 :
8344 : /* True if a function might be constexpr: either a function that was
8345 : declared constexpr, or a C++17 lambda op(). */
8346 :
8347 : bool
8348 739749905 : maybe_constexpr_fn (tree t)
8349 : {
8350 739749905 : return (DECL_DECLARED_CONSTEXPR_P (t)
8351 226829182 : || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t))
8352 957927027 : || (flag_implicit_constexpr
8353 96 : && DECL_DECLARED_INLINE_P (STRIP_TEMPLATE (t))));
8354 : }
8355 :
8356 : /* True if T was declared in a function that might be constexpr: either a
8357 : function that was declared constexpr, or a C++17 lambda op(). */
8358 :
8359 : bool
8360 67070370 : var_in_maybe_constexpr_fn (tree t)
8361 : {
8362 134140093 : return (DECL_FUNCTION_SCOPE_P (t)
8363 122582787 : && maybe_constexpr_fn (DECL_CONTEXT (t)));
8364 : }
8365 :
8366 : /* We're assigning INIT to TARGET. In do_build_copy_constructor and
8367 : build_over_call we implement trivial copy of a class with tail padding using
8368 : assignment of character arrays, which is valid in normal code, but not in
8369 : constexpr evaluation. We don't need to worry about clobbering tail padding
8370 : in constexpr evaluation, so strip the type punning. */
8371 :
8372 : static void
8373 104251006 : maybe_simplify_trivial_copy (tree &target, tree &init)
8374 : {
8375 104251006 : if (TREE_CODE (target) == MEM_REF
8376 36160 : && TREE_CODE (init) == MEM_REF
8377 35992 : && TREE_TYPE (target) == TREE_TYPE (init)
8378 35992 : && TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
8379 104286998 : && TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
8380 : {
8381 35992 : target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
8382 35992 : init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
8383 : }
8384 104251006 : }
8385 :
8386 : /* Returns true if REF, which is a COMPONENT_REF, has any fields
8387 : of constant type. This does not check for 'mutable', so the
8388 : caller is expected to be mindful of that. */
8389 :
8390 : static bool
8391 419 : cref_has_const_field (tree ref)
8392 : {
8393 488 : while (TREE_CODE (ref) == COMPONENT_REF)
8394 : {
8395 479 : if (CP_TYPE_CONST_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
8396 : return true;
8397 69 : ref = TREE_OPERAND (ref, 0);
8398 : }
8399 : return false;
8400 : }
8401 :
8402 : /* Return true if we are modifying something that is const during constant
8403 : expression evaluation. CODE is the code of the statement, OBJ is the
8404 : object in question, MUTABLE_P is true if one of the subobjects were
8405 : declared mutable. */
8406 :
8407 : static bool
8408 107946581 : modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
8409 : {
8410 : /* If this is initialization, there's no problem. */
8411 107946581 : if (code == INIT_EXPR)
8412 : return false;
8413 :
8414 : /* [basic.type.qualifier] "A const object is an object of type
8415 : const T or a non-mutable subobject of a const object." */
8416 30112267 : if (mutable_p)
8417 : return false;
8418 :
8419 30111525 : if (TREE_READONLY (obj))
8420 : return true;
8421 :
8422 30056722 : if (CP_TYPE_CONST_P (TREE_TYPE (obj)))
8423 : {
8424 : /* Although a COMPONENT_REF may have a const type, we should
8425 : only consider it modifying a const object when any of the
8426 : field components is const. This can happen when using
8427 : constructs such as const_cast<const T &>(m), making something
8428 : const even though it wasn't declared const. */
8429 34461 : if (TREE_CODE (obj) == COMPONENT_REF)
8430 419 : return cref_has_const_field (obj);
8431 : else
8432 : return true;
8433 : }
8434 :
8435 : return false;
8436 : }
8437 :
8438 : /* Evaluate an INIT_EXPR or MODIFY_EXPR or MODOP_EXPR. MODOP_EXPR means
8439 : we are evaluating __builtin_start_lifetime (init is in the second
8440 : operand rather than third, like for INIT_EXPR and MODIFY_EXPR). */
8441 :
8442 : static tree
8443 104251006 : cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
8444 : value_cat lval,
8445 : bool *non_constant_p, bool *overflow_p,
8446 : tree *jump_target)
8447 : {
8448 104251006 : constexpr_ctx new_ctx = *ctx;
8449 :
8450 104251006 : tree init = TREE_OPERAND (t, 1);
8451 :
8452 : /* First we figure out where we're storing to. */
8453 104251006 : tree target = TREE_OPERAND (t, 0);
8454 :
8455 104251006 : maybe_simplify_trivial_copy (target, init);
8456 :
8457 104251006 : tree type = TREE_TYPE (target);
8458 104251006 : bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) != INIT_EXPR;
8459 73127352 : if (preeval && !TREE_CLOBBER_P (init) && TREE_CODE (t) != MODOP_EXPR)
8460 : {
8461 : /* Ignore var = .DEFERRED_INIT (); for now, until PR121965 is fixed. */
8462 72088237 : if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
8463 42121023 : && TREE_CODE (init) == CALL_EXPR
8464 6949527 : && CALL_EXPR_FN (init) == NULL_TREE
8465 72088289 : && CALL_EXPR_IFN (init) == IFN_DEFERRED_INIT)
8466 8 : return void_node;
8467 :
8468 : /* Evaluate the value to be stored without knowing what object it will be
8469 : stored in, so that any side-effects happen first. */
8470 72088229 : if (!SCALAR_TYPE_P (type))
8471 203804 : new_ctx.ctor = new_ctx.object = NULL_TREE;
8472 72088229 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8473 : non_constant_p, overflow_p,
8474 : jump_target);
8475 72088225 : if (*jump_target)
8476 : return NULL_TREE;
8477 72087957 : if (*non_constant_p)
8478 : return t;
8479 : }
8480 :
8481 95047980 : bool evaluated = false;
8482 95047980 : if (lval == vc_glvalue)
8483 : {
8484 : /* If we want to return a reference to the target, we need to evaluate it
8485 : as a whole; otherwise, only evaluate the innermost piece to avoid
8486 : building up unnecessary *_REFs. */
8487 0 : target = cxx_eval_constant_expression (ctx, target, lval,
8488 : non_constant_p, overflow_p,
8489 : jump_target);
8490 0 : evaluated = true;
8491 0 : if (*jump_target)
8492 : return NULL_TREE;
8493 0 : if (*non_constant_p)
8494 : return t;
8495 : }
8496 :
8497 : /* Find the underlying variable. */
8498 95047980 : releasing_vec refs;
8499 95047980 : tree object = NULL_TREE;
8500 : /* If we're modifying a const object, save it. */
8501 95047980 : tree const_object_being_modified = NULL_TREE;
8502 95047980 : bool mutable_p = false;
8503 : /* If we see a union, we can't ignore clobbers. */
8504 95047980 : int seen_union = 0;
8505 321491800 : for (tree probe = target; object == NULL_TREE; )
8506 : {
8507 226444285 : switch (TREE_CODE (probe))
8508 : {
8509 36348661 : case BIT_FIELD_REF:
8510 36348661 : case COMPONENT_REF:
8511 36348661 : case ARRAY_REF:
8512 36348661 : {
8513 36348661 : tree ob = TREE_OPERAND (probe, 0);
8514 36348661 : tree elt = TREE_OPERAND (probe, 1);
8515 36348661 : if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt))
8516 : mutable_p = true;
8517 36348661 : if (TREE_CODE (probe) == ARRAY_REF)
8518 : {
8519 5874073 : elt = eval_and_check_array_index (ctx, probe, false,
8520 : non_constant_p, overflow_p,
8521 : jump_target);
8522 5874073 : if (*jump_target)
8523 69 : return NULL_TREE;
8524 5874073 : if (*non_constant_p)
8525 : return t;
8526 : }
8527 : /* We don't check modifying_const_object_p for ARRAY_REFs. Given
8528 : "int a[10]", an ARRAY_REF "a[2]" can be "const int", even though
8529 : the array isn't const. Instead, check "a" in the next iteration;
8530 : that will detect modifying "const int a[10]". */
8531 30474588 : else if (evaluated
8532 12899066 : && modifying_const_object_p (TREE_CODE (t), probe,
8533 : mutable_p)
8534 30475202 : && const_object_being_modified == NULL_TREE)
8535 : const_object_being_modified = probe;
8536 :
8537 : /* Track named member accesses for unions to validate modifications
8538 : that change active member. */
8539 36348592 : if (!evaluated && TREE_CODE (probe) == COMPONENT_REF)
8540 17575522 : vec_safe_push (refs, probe);
8541 : else
8542 18773070 : vec_safe_push (refs, NULL_TREE);
8543 :
8544 36348592 : vec_safe_push (refs, elt);
8545 36348592 : vec_safe_push (refs, TREE_TYPE (probe));
8546 36348592 : probe = ob;
8547 36348592 : if (TREE_CODE (TREE_TYPE (ob)) == UNION_TYPE)
8548 587095 : ++seen_union;
8549 : }
8550 36348592 : break;
8551 :
8552 30 : case REALPART_EXPR:
8553 30 : gcc_assert (refs->is_empty ());
8554 30 : vec_safe_push (refs, NULL_TREE);
8555 30 : vec_safe_push (refs, probe);
8556 30 : vec_safe_push (refs, TREE_TYPE (probe));
8557 30 : probe = TREE_OPERAND (probe, 0);
8558 30 : break;
8559 :
8560 31 : case IMAGPART_EXPR:
8561 31 : gcc_assert (refs->is_empty ());
8562 31 : vec_safe_push (refs, NULL_TREE);
8563 31 : vec_safe_push (refs, probe);
8564 31 : vec_safe_push (refs, TREE_TYPE (probe));
8565 31 : probe = TREE_OPERAND (probe, 0);
8566 31 : break;
8567 :
8568 190095563 : default:
8569 190095563 : if (evaluated)
8570 : object = probe;
8571 : else
8572 : {
8573 95048048 : tree pvar = tree_strip_any_location_wrapper (probe);
8574 95048048 : if (VAR_P (pvar) && DECL_ANON_UNION_VAR_P (pvar))
8575 : {
8576 : /* Stores to DECL_ANON_UNION_VAR_P var are allowed to change
8577 : active union member. */
8578 101 : probe = DECL_VALUE_EXPR (pvar);
8579 101 : break;
8580 : }
8581 95047947 : probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue,
8582 : non_constant_p, overflow_p,
8583 : jump_target);
8584 95047947 : evaluated = true;
8585 95047947 : if (*jump_target)
8586 : return NULL_TREE;
8587 95047947 : if (*non_constant_p)
8588 : return t;
8589 : }
8590 : break;
8591 : }
8592 : }
8593 :
8594 95047515 : if (modifying_const_object_p (TREE_CODE (t), object, mutable_p)
8595 95047515 : && const_object_being_modified == NULL_TREE)
8596 95047515 : const_object_being_modified = object;
8597 :
8598 95047515 : if (DECL_P (object)
8599 95045485 : && TREE_CLOBBER_P (init)
8600 96109371 : && DECL_NAME (object) == heap_deleted_identifier)
8601 : /* Ignore clobbers of deleted allocations for now; we'll get a better error
8602 : message later when operator delete is called. */
8603 15 : return void_node;
8604 :
8605 : /* And then find/build up our initializer for the path to the subobject
8606 : we're initializing. */
8607 95047500 : tree *valp;
8608 95047500 : if (DECL_P (object))
8609 95045470 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8610 : else
8611 : valp = NULL;
8612 95047500 : if (!valp)
8613 : {
8614 : /* A constant-expression cannot modify objects from outside the
8615 : constant-expression. */
8616 11647 : if (!ctx->quiet)
8617 : {
8618 31 : auto_diagnostic_group d;
8619 31 : if (DECL_P (object) && DECL_NAME (object) == heap_deleted_identifier)
8620 : {
8621 0 : error ("modification of allocated storage after deallocation "
8622 : "is not a constant expression");
8623 0 : inform (DECL_SOURCE_LOCATION (object), "allocated here");
8624 : }
8625 31 : else if (DECL_P (object) && ctx->global->is_outside_lifetime (object))
8626 : {
8627 14 : if (TREE_CLOBBER_P (init))
8628 6 : error ("destroying %qE outside its lifetime", object);
8629 : else
8630 8 : error ("modification of %qE outside its lifetime "
8631 : "is not a constant expression", object);
8632 14 : inform (DECL_SOURCE_LOCATION (object), "declared here");
8633 : }
8634 : else
8635 : {
8636 17 : if (TREE_CLOBBER_P (init))
8637 6 : error ("destroying %qE from outside current evaluation "
8638 : "is not a constant expression", object);
8639 : else
8640 11 : error ("modification of %qE from outside current evaluation "
8641 : "is not a constant expression", object);
8642 : }
8643 31 : }
8644 11647 : *non_constant_p = true;
8645 11647 : return t;
8646 : }
8647 :
8648 : /* Handle explicit end-of-lifetime. */
8649 95035853 : if (TREE_CLOBBER_P (init))
8650 : {
8651 1061790 : if (CLOBBER_KIND (init) >= CLOBBER_OBJECT_END
8652 1061790 : && refs->is_empty ())
8653 : {
8654 300554 : ctx->global->destroy_value (object, (CLOBBER_KIND (init)
8655 : > CLOBBER_OBJECT_END));
8656 300554 : return void_node;
8657 : }
8658 :
8659 747995 : if (!seen_union && !*valp
8660 771681 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
8661 10410 : return void_node;
8662 :
8663 : /* Ending the lifetime of a const object is OK. */
8664 : const_object_being_modified = NULL_TREE;
8665 : }
8666 :
8667 94724889 : type = TREE_TYPE (object);
8668 94724889 : bool no_zero_init = true;
8669 94724889 : bool zero_padding_bits = false;
8670 :
8671 189449778 : auto_vec<tree *> ctors;
8672 189449778 : releasing_vec indexes;
8673 189449778 : auto_vec<int> index_pos_hints;
8674 94724889 : bool activated_union_member_p = false;
8675 94724889 : bool empty_base = false;
8676 130756802 : while (!refs->is_empty ())
8677 : {
8678 36318515 : if (*valp == NULL_TREE || *valp == void_node)
8679 : {
8680 2948541 : *valp = build_constructor (type, NULL);
8681 2948541 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8682 2948541 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8683 : }
8684 33369974 : else if (STRIP_ANY_LOCATION_WRAPPER (*valp),
8685 33369974 : TREE_CODE (*valp) == STRING_CST)
8686 : {
8687 : /* An array was initialized with a string constant, and now
8688 : we're writing into one of its elements. Explode the
8689 : single initialization into a set of element
8690 : initializations. */
8691 11465 : gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
8692 :
8693 11465 : tree string = *valp;
8694 11465 : tree elt_type = TREE_TYPE (type);
8695 11465 : unsigned chars_per_elt = (TYPE_PRECISION (elt_type)
8696 11465 : / TYPE_PRECISION (char_type_node));
8697 11465 : unsigned num_elts = TREE_STRING_LENGTH (string) / chars_per_elt;
8698 11465 : tree ary_ctor = build_constructor (type, NULL);
8699 :
8700 11465 : vec_safe_reserve (CONSTRUCTOR_ELTS (ary_ctor), num_elts);
8701 34563 : for (unsigned ix = 0; ix != num_elts; ix++)
8702 : {
8703 11633 : constructor_elt elt =
8704 : {
8705 11633 : build_int_cst (size_type_node, ix),
8706 11633 : extract_string_elt (string, chars_per_elt, ix)
8707 11633 : };
8708 11633 : CONSTRUCTOR_ELTS (ary_ctor)->quick_push (elt);
8709 : }
8710 :
8711 11465 : *valp = ary_ctor;
8712 : }
8713 :
8714 36318515 : enum tree_code code = TREE_CODE (type);
8715 36318515 : tree reftype = refs->pop();
8716 36318515 : tree index = refs->pop();
8717 36318515 : bool is_access_expr = refs->pop() != NULL_TREE;
8718 :
8719 36318515 : if (code == COMPLEX_TYPE)
8720 : {
8721 61 : if (TREE_CODE (*valp) == COMPLEX_CST)
8722 51 : *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp),
8723 51 : TREE_IMAGPART (*valp));
8724 10 : else if (TREE_CODE (*valp) == CONSTRUCTOR
8725 2 : && CONSTRUCTOR_NELTS (*valp) == 0
8726 12 : && CONSTRUCTOR_NO_CLEARING (*valp))
8727 : {
8728 2 : tree r = build_constructor (reftype, NULL);
8729 2 : CONSTRUCTOR_NO_CLEARING (r) = 1;
8730 2 : *valp = build2 (COMPLEX_EXPR, type, r, r);
8731 : }
8732 61 : gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR);
8733 61 : ctors.safe_push (valp);
8734 61 : vec_safe_push (indexes, index);
8735 61 : valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR);
8736 61 : gcc_checking_assert (refs->is_empty ());
8737 : type = reftype;
8738 282089 : break;
8739 : }
8740 :
8741 : /* If the value of object is already zero-initialized, any new ctors for
8742 : subobjects will also be zero-initialized. Similarly with zeroing of
8743 : padding bits. */
8744 36318454 : no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
8745 36318454 : zero_padding_bits = CONSTRUCTOR_ZERO_PADDING_BITS (*valp);
8746 :
8747 36318454 : if (code == RECORD_TYPE && is_empty_field (index))
8748 : /* Don't build a sub-CONSTRUCTOR for an empty base or field, as they
8749 : have no data and might have an offset lower than previously declared
8750 : fields, which confuses the middle-end. The code below will notice
8751 : that we don't have a CONSTRUCTOR for our inner target and just
8752 : return init. */
8753 : {
8754 : empty_base = true;
8755 : break;
8756 : }
8757 :
8758 : /* If a union is zero-initialized, its first non-static named data member
8759 : is zero-initialized (and therefore active). */
8760 36036426 : if (code == UNION_TYPE
8761 36036426 : && !no_zero_init
8762 36036426 : && CONSTRUCTOR_NELTS (*valp) == 0)
8763 4079 : if (tree first = next_aggregate_field (TYPE_FIELDS (type)))
8764 4079 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (*valp), first, NULL_TREE);
8765 :
8766 : /* Check for implicit change of active member for a union. */
8767 :
8768 : /* LWG3436, CWG2675, c++/121068: The array object model is confused. For
8769 : now allow initializing an array element to activate the array. */
8770 36088782 : auto only_array_refs = [](const releasing_vec &refs)
8771 : {
8772 52361 : for (unsigned i = 1; i < refs->length(); i += 3)
8773 35 : if (TREE_CODE ((*refs)[i]) != INTEGER_CST)
8774 : return false;
8775 : return true;
8776 : };
8777 :
8778 36036426 : if (code == UNION_TYPE
8779 585087 : && (CONSTRUCTOR_NELTS (*valp) == 0
8780 381021 : || CONSTRUCTOR_ELT (*valp, 0)->index != index)
8781 : /* An INIT_EXPR of the last member in an access chain is always OK,
8782 : but still check implicit change of members earlier on; see
8783 : cpp2a/constexpr-union6.C. */
8784 36252972 : && !(TREE_CODE (t) == INIT_EXPR && only_array_refs (refs)))
8785 : {
8786 164220 : bool has_active_member = CONSTRUCTOR_NELTS (*valp) != 0;
8787 164220 : tree inner = strip_array_types (reftype);
8788 :
8789 164220 : if (has_active_member && cxx_dialect < cxx20)
8790 : {
8791 58 : if (!ctx->quiet)
8792 19 : error_at (cp_expr_loc_or_input_loc (t),
8793 : "change of the active member of a union "
8794 : "from %qD to %qD is not a constant expression "
8795 : "before C++20",
8796 19 : CONSTRUCTOR_ELT (*valp, 0)->index,
8797 : index);
8798 58 : *non_constant_p = true;
8799 : }
8800 164162 : else if ((!is_access_expr
8801 47649 : || (TREE_CLOBBER_P (init)
8802 0 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8803 47649 : || (TREE_CODE (t) != INIT_EXPR
8804 47637 : && CLASS_TYPE_P (inner)
8805 482 : && !type_has_non_deleted_trivial_default_ctor (inner)))
8806 164247 : && TREE_CODE (t) != MODOP_EXPR)
8807 : {
8808 : /* Diagnose changing active union member after initialization
8809 : without a valid member access expression, as described in
8810 : [class.union.general] p5. */
8811 116522 : if (!ctx->quiet)
8812 : {
8813 33 : auto_diagnostic_group d;
8814 33 : if (has_active_member)
8815 24 : error_at (cp_expr_loc_or_input_loc (t),
8816 : "accessing %qD member instead of initialized "
8817 : "%qD member in constant expression",
8818 24 : index, CONSTRUCTOR_ELT (*valp, 0)->index);
8819 : else
8820 9 : error_at (cp_expr_loc_or_input_loc (t),
8821 : "accessing uninitialized member %qD",
8822 : index);
8823 33 : if (is_access_expr)
8824 3 : inform (DECL_SOURCE_LOCATION (index),
8825 : "%qD does not implicitly begin its lifetime "
8826 : "because %qT does not have a non-deleted "
8827 : "trivial default constructor, use "
8828 : "%<std::construct_at%> instead",
8829 : index, inner);
8830 : else
8831 30 : inform (DECL_SOURCE_LOCATION (index),
8832 : "initializing %qD requires a member access "
8833 : "expression as the left operand of the assignment",
8834 : index);
8835 33 : }
8836 116522 : *non_constant_p = true;
8837 : }
8838 47640 : else if (has_active_member && CONSTRUCTOR_NO_CLEARING (*valp))
8839 : {
8840 : /* Diagnose changing the active union member while the union
8841 : is in the process of being initialized. */
8842 18 : if (!ctx->quiet)
8843 6 : error_at (cp_expr_loc_or_input_loc (t),
8844 : "change of the active member of a union "
8845 : "from %qD to %qD during initialization",
8846 6 : CONSTRUCTOR_ELT (*valp, 0)->index,
8847 : index);
8848 18 : *non_constant_p = true;
8849 : }
8850 : no_zero_init = true;
8851 : }
8852 :
8853 : /* Ending the lifetime of the active union member means the union no
8854 : longer has an active member. */
8855 585087 : if (code == UNION_TYPE && refs->is_empty ()
8856 100834 : && TREE_CLOBBER_P (init)
8857 36044301 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8858 : {
8859 1799 : vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0);
8860 4513 : return void_node;
8861 : }
8862 :
8863 36034627 : ctors.safe_push (valp);
8864 36034627 : vec_safe_push (indexes, index);
8865 :
8866 : /* Avoid adding an _elt for a clobber when the whole CONSTRUCTOR is
8867 : uninitialized. */
8868 34124648 : int pos = (!seen_union && TREE_CLOBBER_P (init)
8869 1744458 : && CONSTRUCTOR_NO_CLEARING (*valp)
8870 37588532 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END) ? -2 : -1;
8871 36034627 : constructor_elt *cep
8872 36034627 : = get_or_insert_ctor_field (*valp, index, pos);
8873 36034627 : if (cep == nullptr)
8874 2714 : return void_node;
8875 36031913 : index_pos_hints.safe_push (cep - CONSTRUCTOR_ELTS (*valp)->begin());
8876 :
8877 36031913 : if (code == UNION_TYPE)
8878 : {
8879 583288 : activated_union_member_p = true;
8880 583288 : --seen_union;
8881 : }
8882 :
8883 36031913 : valp = &cep->value;
8884 36031913 : type = reftype;
8885 : }
8886 :
8887 : /* Change an "as-base" clobber to the real type;
8888 : we don't need to worry about padding in constexpr. */
8889 94720376 : tree itype = initialized_type (init);
8890 94720376 : if (IS_FAKE_BASE_TYPE (itype))
8891 4455 : itype = TYPE_CONTEXT (itype);
8892 :
8893 : /* For initialization of an empty base, the original target will be
8894 : *(base*)this, evaluation of which resolves to the object
8895 : argument, which has the derived type rather than the base type. */
8896 189158724 : if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p
8897 94438348 : (itype, type)))
8898 : {
8899 18782 : gcc_assert (is_empty_class (TREE_TYPE (target)));
8900 : empty_base = true;
8901 : }
8902 :
8903 : /* For __builtin_start_lifetime, if it is already within lifetime,
8904 : don't do anything. */
8905 94720376 : if (TREE_CODE (t) == MODOP_EXPR && *valp != NULL_TREE && *valp != void_node)
8906 : return void_node;
8907 :
8908 : /* Detect modifying a constant object in constexpr evaluation.
8909 : We have found a const object that is being modified. Figure out
8910 : if we need to issue an error. Consider
8911 :
8912 : struct A {
8913 : int n;
8914 : constexpr A() : n(1) { n = 2; } // #1
8915 : };
8916 : struct B {
8917 : const A a;
8918 : constexpr B() { a.n = 3; } // #2
8919 : };
8920 : constexpr B b{};
8921 :
8922 : #1 is OK, since we're modifying an object under construction, but
8923 : #2 is wrong, since "a" is const and has been fully constructed.
8924 : To track it, we use the TREE_READONLY bit in the object's CONSTRUCTOR
8925 : which means that the object is read-only. For the example above, the
8926 : *ctors stack at the point of #2 will look like:
8927 :
8928 : ctors[0] = {.a={.n=2}} TREE_READONLY = 0
8929 : ctors[1] = {.n=2} TREE_READONLY = 1
8930 :
8931 : and we're modifying "b.a", so we search the stack and see if the
8932 : constructor for "b.a" has already run. */
8933 94720338 : if (const_object_being_modified)
8934 : {
8935 87720 : bool fail = false;
8936 87720 : tree const_objtype
8937 87720 : = strip_array_types (TREE_TYPE (const_object_being_modified));
8938 87720 : if (!CLASS_TYPE_P (const_objtype))
8939 : fail = true;
8940 : else
8941 : {
8942 : /* [class.ctor]p5 "A constructor can be invoked for a const,
8943 : volatile, or const volatile object. const and volatile
8944 : semantics are not applied on an object under construction.
8945 : They come into effect when the constructor for the most
8946 : derived object ends." */
8947 263359 : for (tree *elt : ctors)
8948 88129 : if (same_type_ignoring_top_level_qualifiers_p
8949 88129 : (TREE_TYPE (const_object_being_modified), TREE_TYPE (*elt)))
8950 : {
8951 87615 : fail = TREE_READONLY (*elt);
8952 87615 : break;
8953 : }
8954 : }
8955 87615 : if (fail)
8956 : {
8957 200 : if (!ctx->quiet)
8958 65 : modifying_const_object_error (t, const_object_being_modified);
8959 200 : *non_constant_p = true;
8960 200 : return t;
8961 : }
8962 : }
8963 :
8964 94720138 : if (!preeval)
8965 : {
8966 : /* We're handling an INIT_EXPR of class type, so the value of the
8967 : initializer can depend on the object it's initializing. */
8968 :
8969 : /* Create a new CONSTRUCTOR in case evaluation of the initializer
8970 : wants to modify it. */
8971 31101442 : if (*valp == NULL_TREE)
8972 : {
8973 30007282 : *valp = build_constructor (type, NULL);
8974 30007282 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8975 30007282 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8976 : }
8977 31101442 : new_ctx.ctor = empty_base ? NULL_TREE : *valp;
8978 31101442 : new_ctx.object = target;
8979 : /* Avoid temporary materialization when initializing from a TARGET_EXPR.
8980 : We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because
8981 : expansion of those trees uses ctx instead. */
8982 31101442 : if (TREE_CODE (init) == TARGET_EXPR)
8983 3289040 : if (tree tinit = TARGET_EXPR_INITIAL (init))
8984 3289040 : init = tinit;
8985 31101442 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8986 : non_constant_p, overflow_p,
8987 : jump_target);
8988 31101442 : if (*jump_target)
8989 : return NULL_TREE;
8990 : /* The hash table might have moved since the get earlier, and the
8991 : initializer might have mutated the underlying CONSTRUCTORs, so we must
8992 : recompute VALP. */
8993 31101248 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8994 35581394 : for (unsigned i = 0; i < vec_safe_length (indexes); i++)
8995 : {
8996 4480146 : ctors[i] = valp;
8997 4480146 : constructor_elt *cep
8998 4480146 : = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]);
8999 4480146 : valp = &cep->value;
9000 : }
9001 : }
9002 :
9003 94719944 : if (*non_constant_p)
9004 : return t;
9005 :
9006 : /* Don't share a CONSTRUCTOR that might be changed later. */
9007 92854264 : init = unshare_constructor (init);
9008 :
9009 92854264 : gcc_checking_assert (!*valp
9010 : || *valp == void_node
9011 : || (same_type_ignoring_top_level_qualifiers_p
9012 : (TREE_TYPE (*valp), type)));
9013 92854264 : if (empty_base)
9014 : {
9015 : /* Just evaluate the initializer and return, since there's no actual data
9016 : to store, and we didn't build a CONSTRUCTOR. */
9017 289386 : if (!*valp)
9018 : {
9019 : /* But do make sure we have something in *valp. */
9020 0 : *valp = build_constructor (type, nullptr);
9021 0 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
9022 0 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
9023 : }
9024 : }
9025 92564878 : else if (TREE_CLOBBER_P (init))
9026 : {
9027 746313 : if (AGGREGATE_TYPE_P (type) && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
9028 : {
9029 11424 : if (*valp && TREE_CODE (*valp) == CONSTRUCTOR)
9030 6788 : CONSTRUCTOR_ELTS (*valp) = nullptr;
9031 : else
9032 4636 : *valp = build_constructor (type, nullptr);
9033 11424 : TREE_CONSTANT (*valp) = true;
9034 11424 : TREE_SIDE_EFFECTS (*valp) = false;
9035 11424 : CONSTRUCTOR_NO_CLEARING (*valp) = true;
9036 11424 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
9037 : }
9038 : else
9039 734889 : *valp = void_node;
9040 : }
9041 91818565 : else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
9042 29233859 : && TREE_CODE (init) == CONSTRUCTOR)
9043 : {
9044 : /* An outer ctx->ctor might be pointing to *valp, so replace
9045 : its contents. */
9046 4748242 : CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
9047 4748242 : TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
9048 4748242 : TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
9049 14244726 : CONSTRUCTOR_NO_CLEARING (*valp)
9050 4748242 : = CONSTRUCTOR_NO_CLEARING (init);
9051 14244726 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp)
9052 4748242 : = CONSTRUCTOR_ZERO_PADDING_BITS (init);
9053 : }
9054 : else
9055 87070323 : *valp = init;
9056 :
9057 : /* After initialization, 'const' semantics apply to the value of the
9058 : object. Make a note of this fact by marking the CONSTRUCTOR
9059 : TREE_READONLY. */
9060 92854264 : if (TREE_CODE (t) == INIT_EXPR
9061 70236342 : && !empty_base
9062 69946956 : && TREE_CODE (*valp) == CONSTRUCTOR
9063 97431480 : && TYPE_READONLY (type))
9064 : {
9065 35993 : tree target_type = TREE_TYPE (target);
9066 35993 : if (IS_FAKE_BASE_TYPE (target_type))
9067 0 : target_type = TYPE_CONTEXT (target_type);
9068 35993 : if (INDIRECT_REF_P (target)
9069 51147 : && (is_this_parameter
9070 15154 : (tree_strip_nop_conversions (TREE_OPERAND (target, 0)))))
9071 : /* We've just initialized '*this' (perhaps via the target
9072 : constructor of a delegating constructor). Leave it up to the
9073 : caller that set 'this' to set TREE_READONLY appropriately. */
9074 23 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
9075 : (target_type, type) || empty_base);
9076 : else
9077 35970 : TREE_READONLY (*valp) = true;
9078 : }
9079 :
9080 : /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing
9081 : CONSTRUCTORs, if any. */
9082 92854264 : bool c = TREE_CONSTANT (init);
9083 92854264 : bool s = TREE_SIDE_EFFECTS (init);
9084 92854264 : if (!indexes->is_empty ())
9085 : {
9086 20433777 : tree last = indexes->last ();
9087 20433777 : if (TREE_CODE (last) == REALPART_EXPR
9088 20433777 : || TREE_CODE (last) == IMAGPART_EXPR)
9089 : {
9090 : /* And canonicalize COMPLEX_EXPR into COMPLEX_CST if
9091 : possible. */
9092 61 : tree *cexpr = ctors.last ();
9093 61 : if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr),
9094 61 : TREE_OPERAND (*cexpr, 0),
9095 61 : TREE_OPERAND (*cexpr, 1)))
9096 53 : *cexpr = c;
9097 : else
9098 : {
9099 16 : TREE_CONSTANT (*cexpr)
9100 8 : = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0))
9101 8 : & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1)));
9102 16 : TREE_SIDE_EFFECTS (*cexpr)
9103 16 : = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0))
9104 8 : | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1)));
9105 : }
9106 61 : c = TREE_CONSTANT (*cexpr);
9107 61 : s = TREE_SIDE_EFFECTS (*cexpr);
9108 : }
9109 : }
9110 92854264 : if (!c || s || activated_union_member_p)
9111 63891486 : for (tree *elt : ctors)
9112 : {
9113 12533584 : if (TREE_CODE (*elt) != CONSTRUCTOR)
9114 0 : continue;
9115 12533584 : if (!c)
9116 10639948 : TREE_CONSTANT (*elt) = false;
9117 12533584 : if (s)
9118 0 : TREE_SIDE_EFFECTS (*elt) = true;
9119 : /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of
9120 : this union. */
9121 12533584 : if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE)
9122 465904 : CONSTRUCTOR_NO_CLEARING (*elt) = false;
9123 : }
9124 :
9125 92854264 : if (lval)
9126 : return target;
9127 : else
9128 587179 : return init;
9129 95047980 : }
9130 :
9131 : /* Evaluate a ++ or -- expression. */
9132 :
9133 : static tree
9134 8849887 : cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
9135 : value_cat lval,
9136 : bool *non_constant_p, bool *overflow_p,
9137 : tree *jump_target)
9138 : {
9139 8849887 : enum tree_code code = TREE_CODE (t);
9140 8849887 : tree type = TREE_TYPE (t);
9141 8849887 : tree op = TREE_OPERAND (t, 0);
9142 8849887 : tree offset = TREE_OPERAND (t, 1);
9143 8849887 : gcc_assert (TREE_CONSTANT (offset));
9144 :
9145 : /* OFFSET is constant, but perhaps not constant enough. We need to
9146 : e.g. bash FLOAT_EXPRs to REAL_CSTs. */
9147 8849887 : offset = fold_simple (offset);
9148 :
9149 : /* The operand as an lvalue. */
9150 8849887 : op = cxx_eval_constant_expression (ctx, op, vc_glvalue,
9151 : non_constant_p, overflow_p,
9152 : jump_target);
9153 8849887 : if (*jump_target)
9154 : return NULL_TREE;
9155 :
9156 : /* The operand as an rvalue. */
9157 8849887 : tree val
9158 8849887 : = cxx_eval_constant_expression (ctx, op, vc_prvalue,
9159 : non_constant_p, overflow_p,
9160 : jump_target);
9161 8849887 : if (*jump_target)
9162 : return NULL_TREE;
9163 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
9164 : a local array in a constexpr function. */
9165 8849887 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val));
9166 3533507 : if (!ptr)
9167 3533507 : VERIFY_CONSTANT (val);
9168 :
9169 : /* The modified value. */
9170 8790285 : bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
9171 8790285 : tree mod;
9172 8790285 : if (INDIRECT_TYPE_P (type))
9173 : {
9174 : /* The middle end requires pointers to use POINTER_PLUS_EXPR. */
9175 5316380 : offset = convert_to_ptrofftype (offset);
9176 5316380 : if (!inc)
9177 80918 : offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
9178 5316380 : mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
9179 : }
9180 3473905 : else if (c_promoting_integer_type_p (type)
9181 39613 : && !TYPE_UNSIGNED (type)
9182 3474117 : && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
9183 : {
9184 212 : offset = fold_convert (integer_type_node, offset);
9185 212 : mod = fold_convert (integer_type_node, val);
9186 245 : tree t = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, integer_type_node,
9187 : mod, offset);
9188 212 : mod = fold_convert (type, t);
9189 212 : if (TREE_OVERFLOW_P (mod) && !TREE_OVERFLOW_P (t))
9190 9 : TREE_OVERFLOW (mod) = false;
9191 : }
9192 : else
9193 3916548 : mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
9194 8790285 : if (!ptr)
9195 3473905 : VERIFY_CONSTANT (mod);
9196 :
9197 : /* Storing the modified value. */
9198 14760495 : tree store = build2_loc (cp_expr_loc_or_loc (t, input_location),
9199 : MODIFY_EXPR, type, op, mod);
9200 8790285 : mod = cxx_eval_constant_expression (ctx, store, lval,
9201 : non_constant_p, overflow_p,
9202 : jump_target);
9203 8790285 : ggc_free (store);
9204 8790285 : if (*jump_target)
9205 : return NULL_TREE;
9206 8790285 : if (*non_constant_p)
9207 : return t;
9208 :
9209 : /* And the value of the expression. */
9210 8715778 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
9211 : /* Prefix ops are lvalues, but the caller might want an rvalue;
9212 : lval has already been taken into account in the store above. */
9213 : return mod;
9214 : else
9215 : /* Postfix ops are rvalues. */
9216 422277 : return val;
9217 : }
9218 :
9219 : /* Subroutine of cxx_eval_statement_list. Determine whether the statement
9220 : STMT matches *jump_target. If we're looking for a case label and we see
9221 : the default label, note it in ctx->css_state. */
9222 :
9223 : static bool
9224 504254 : label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
9225 : {
9226 504254 : switch (TREE_CODE (*jump_target))
9227 : {
9228 145 : case LABEL_DECL:
9229 145 : if (TREE_CODE (stmt) == LABEL_EXPR
9230 145 : && LABEL_EXPR_LABEL (stmt) == *jump_target)
9231 52 : return true;
9232 : break;
9233 :
9234 502192 : case INTEGER_CST:
9235 502192 : if (TREE_CODE (stmt) == CASE_LABEL_EXPR)
9236 : {
9237 502165 : gcc_assert (ctx->css_state != NULL);
9238 502165 : if (!CASE_LOW (stmt))
9239 : {
9240 : /* default: should appear just once in a SWITCH_EXPR
9241 : body (excluding nested SWITCH_EXPR). */
9242 76286 : gcc_assert (*ctx->css_state != css_default_seen);
9243 : /* When evaluating SWITCH_EXPR body for the second time,
9244 : return true for the default: label. */
9245 76286 : if (*ctx->css_state == css_default_processing)
9246 : return true;
9247 39019 : *ctx->css_state = css_default_seen;
9248 : }
9249 425879 : else if (CASE_HIGH (stmt))
9250 : {
9251 20 : if (tree_int_cst_le (CASE_LOW (stmt), *jump_target)
9252 31 : && tree_int_cst_le (*jump_target, CASE_HIGH (stmt)))
9253 : return true;
9254 : }
9255 425859 : else if (tree_int_cst_equal (*jump_target, CASE_LOW (stmt)))
9256 : return true;
9257 : }
9258 : break;
9259 :
9260 : case BREAK_STMT:
9261 : case CONTINUE_STMT:
9262 : /* These two are handled directly in cxx_eval_loop_expr by testing
9263 : breaks (jump_target) or continues (jump_target). */
9264 : break;
9265 :
9266 : case VAR_DECL:
9267 : /* Uncaught exception. This is handled by TRY_BLOCK evaluation
9268 : and other places by testing throws (jump_target). */
9269 : break;
9270 :
9271 0 : default:
9272 0 : gcc_unreachable ();
9273 : }
9274 : return false;
9275 : }
9276 :
9277 : /* Evaluate a STATEMENT_LIST for side-effects. Handles various jump
9278 : semantics, for switch, break, continue, and return. */
9279 :
9280 : static tree
9281 48465181 : cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
9282 : bool *non_constant_p, bool *overflow_p,
9283 : tree *jump_target)
9284 : {
9285 : /* In a statement-expression we want to return the last value.
9286 : For empty statement expression return void_node. */
9287 48465181 : tree r = void_node;
9288 127349874 : for (tree_stmt_iterator i = tsi_start (t); !tsi_end_p (i); ++i)
9289 : {
9290 104731488 : tree stmt = *i;
9291 :
9292 : /* We've found a continue, so skip everything until we reach
9293 : the label its jumping to. */
9294 104731488 : if (continues (jump_target))
9295 : {
9296 2062 : if (label_matches (ctx, jump_target, stmt))
9297 : /* Found it. */
9298 52 : *jump_target = NULL_TREE;
9299 : else
9300 2010 : continue;
9301 : }
9302 104729478 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
9303 11325672 : continue;
9304 :
9305 93403806 : value_cat lval = vc_discard;
9306 : /* The result of a statement-expression is not wrapped in EXPR_STMT. */
9307 131439304 : if (tsi_one_before_end_p (i)
9308 38036760 : && !VOID_TYPE_P (TREE_TYPE (stmt)))
9309 : lval = vc_prvalue;
9310 :
9311 93403806 : r = cxx_eval_constant_expression (ctx, stmt, lval,
9312 : non_constant_p, overflow_p,
9313 : jump_target);
9314 93403802 : if (*non_constant_p)
9315 : break;
9316 83336111 : if (returns (jump_target)
9317 67646509 : || breaks (jump_target)
9318 78884693 : || throws (jump_target))
9319 : break;
9320 : }
9321 48465177 : return r;
9322 : }
9323 :
9324 : /* Evaluate a LOOP_EXPR for side-effects. Handles break and return
9325 : semantics; continue semantics are covered by cxx_eval_statement_list. */
9326 :
9327 : static tree
9328 6649851 : cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
9329 : bool *non_constant_p, bool *overflow_p,
9330 : tree *jump_target)
9331 : {
9332 6649851 : tree body, cond = NULL_TREE, expr = NULL_TREE;
9333 6649851 : tree cond_prep = NULL_TREE, cond_cleanup = NULL_TREE;
9334 6649851 : unsigned cond_cleanup_depth = 0;
9335 6649851 : int count = 0;
9336 6649851 : switch (TREE_CODE (t))
9337 : {
9338 3415 : case LOOP_EXPR:
9339 3415 : body = LOOP_EXPR_BODY (t);
9340 3415 : break;
9341 5351519 : case DO_STMT:
9342 5351519 : body = DO_BODY (t);
9343 5351519 : cond = DO_COND (t);
9344 5351519 : break;
9345 365729 : case WHILE_STMT:
9346 365729 : body = WHILE_BODY (t);
9347 365729 : cond = WHILE_COND (t);
9348 365729 : cond_prep = WHILE_COND_PREP (t);
9349 365729 : cond_cleanup = WHILE_COND_CLEANUP (t);
9350 365729 : count = -1;
9351 365729 : break;
9352 929188 : case FOR_STMT:
9353 929188 : if (FOR_INIT_STMT (t))
9354 0 : cxx_eval_constant_expression (ctx, FOR_INIT_STMT (t), vc_discard,
9355 : non_constant_p, overflow_p, jump_target);
9356 929188 : if (*non_constant_p)
9357 : return NULL_TREE;
9358 929188 : body = FOR_BODY (t);
9359 929188 : cond = FOR_COND (t);
9360 929188 : expr = FOR_EXPR (t);
9361 929188 : cond_prep = FOR_COND_PREP (t);
9362 929188 : cond_cleanup = FOR_COND_CLEANUP (t);
9363 929188 : count = -1;
9364 929188 : break;
9365 0 : default:
9366 0 : gcc_unreachable ();
9367 : }
9368 6649851 : if (cond_prep)
9369 12 : gcc_assert (TREE_CODE (cond_prep) == BIND_EXPR);
9370 31530772 : auto cleanup_cond = [&] {
9371 : /* Clean up the condition variable after each iteration. */
9372 24880921 : if (cond_cleanup_depth && !*non_constant_p)
9373 : {
9374 105 : auto_vec<tree, 4> cleanups (cond_cleanup_depth);
9375 105 : tree s = BIND_EXPR_BODY (cond_prep);
9376 105 : unsigned i;
9377 210 : for (i = cond_cleanup_depth; i; --i)
9378 : {
9379 105 : tree_stmt_iterator iter = tsi_last (s);
9380 105 : s = tsi_stmt (iter);
9381 105 : cleanups.quick_push (CLEANUP_EXPR (s));
9382 105 : s = CLEANUP_BODY (s);
9383 : }
9384 105 : tree c;
9385 420 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, c)
9386 105 : cxx_eval_constant_expression (ctx, c, vc_discard, non_constant_p,
9387 : overflow_p, jump_target);
9388 105 : }
9389 24880921 : if (cond_prep)
9390 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
9391 222 : decl; decl = DECL_CHAIN (decl))
9392 111 : destroy_value_checked (ctx, decl, non_constant_p);
9393 6649851 : };
9394 19561436 : do
9395 : {
9396 19561436 : if (count != -1)
9397 : {
9398 18266519 : if (body)
9399 18266519 : cxx_eval_constant_expression (ctx, body, vc_discard,
9400 : non_constant_p, overflow_p,
9401 : jump_target);
9402 18266519 : if (breaks (jump_target))
9403 : {
9404 35449 : *jump_target = NULL_TREE;
9405 35449 : break;
9406 : }
9407 :
9408 18231070 : if (TREE_CODE (t) != LOOP_EXPR && continues (jump_target))
9409 570 : *jump_target = NULL_TREE;
9410 :
9411 18231070 : if (expr)
9412 5449380 : cxx_eval_constant_expression (ctx, expr, vc_discard,
9413 : non_constant_p, overflow_p,
9414 : jump_target);
9415 18231070 : cleanup_cond ();
9416 : }
9417 :
9418 19525987 : if (cond_prep)
9419 : {
9420 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
9421 222 : decl; decl = DECL_CHAIN (decl))
9422 111 : ctx->global->clear_value (decl);
9423 111 : if (cond_cleanup)
9424 : {
9425 : /* If COND_CLEANUP is non-NULL, we need to evaluate DEPTH
9426 : nested STATEMENT_LISTs from inside of BIND_EXPR_BODY,
9427 : but defer the evaluation of CLEANUP_EXPRs of CLEANUP_STMT
9428 : at the end of those STATEMENT_LISTs. */
9429 111 : cond_cleanup_depth = 0;
9430 111 : tree s = BIND_EXPR_BODY (cond_prep);
9431 111 : for (unsigned depth = tree_to_uhwi (cond_cleanup);
9432 222 : depth; --depth)
9433 : {
9434 111 : for (tree_stmt_iterator i = tsi_start (s);
9435 321 : !tsi_end_p (i); ++i)
9436 : {
9437 321 : tree stmt = *i;
9438 321 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
9439 0 : continue;
9440 321 : if (tsi_one_before_end_p (i))
9441 : {
9442 : /* The last statement in the STATEMENT_LIST
9443 : has to be a CLEANUP_STMT (verified in
9444 : finish_loop_cond_prep). We want to
9445 : evaluate just its CLEANUP_BODY part but not
9446 : CLEANUP_EXPR part just yet. */
9447 105 : gcc_assert (TREE_CODE (stmt) == CLEANUP_STMT);
9448 : /* If the CLEANUP_STMT is not actually to be
9449 : evaluated, don't increment cond_cleanup_depth
9450 : so that we don't evaluate the CLEANUP_EXPR
9451 : for it later either. */
9452 105 : if (*jump_target)
9453 : {
9454 : depth = 1;
9455 : break;
9456 : }
9457 105 : ++cond_cleanup_depth;
9458 : /* If not in the innermost one, next iteration
9459 : will handle CLEANUP_BODY similarly. */
9460 105 : if (depth > 1)
9461 : {
9462 0 : s = CLEANUP_BODY (stmt);
9463 0 : break;
9464 : }
9465 : /* The innermost one can be evaluated normally. */
9466 105 : cxx_eval_constant_expression (ctx,
9467 105 : CLEANUP_BODY (stmt),
9468 : vc_discard,
9469 : non_constant_p,
9470 : overflow_p,
9471 : jump_target);
9472 105 : break;
9473 : }
9474 : /* And so should be evaluated statements which aren't
9475 : last in the STATEMENT_LIST. */
9476 216 : cxx_eval_constant_expression (ctx, stmt, vc_discard,
9477 : non_constant_p, overflow_p,
9478 : jump_target);
9479 216 : if (*non_constant_p
9480 210 : || returns (jump_target)
9481 210 : || breaks (jump_target)
9482 210 : || continues (jump_target)
9483 531 : || throws (jump_target))
9484 : {
9485 : depth = 1;
9486 : break;
9487 : }
9488 : }
9489 : }
9490 : }
9491 : else
9492 0 : cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (cond_prep),
9493 : vc_discard, non_constant_p,
9494 : overflow_p, jump_target);
9495 : }
9496 :
9497 19525987 : if (cond)
9498 : {
9499 19518457 : tree res
9500 19518457 : = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
9501 : non_constant_p, overflow_p,
9502 : jump_target);
9503 19518457 : if (res)
9504 : {
9505 19462967 : if (verify_constant (res, ctx->quiet, non_constant_p,
9506 : overflow_p))
9507 : break;
9508 19276345 : if (integer_zerop (res))
9509 : break;
9510 : }
9511 : else
9512 55490 : gcc_assert (*jump_target);
9513 : }
9514 :
9515 12968960 : if (++count >= constexpr_loop_limit)
9516 : {
9517 27 : if (!ctx->quiet)
9518 9 : error_at (cp_expr_loc_or_input_loc (t),
9519 : "%<constexpr%> loop iteration count exceeds limit of %d "
9520 : "(use %<-fconstexpr-loop-limit=%> to increase the limit)",
9521 : constexpr_loop_limit);
9522 27 : *non_constant_p = true;
9523 27 : break;
9524 : }
9525 : }
9526 38849690 : while (!returns (jump_target)
9527 12911824 : && !breaks (jump_target)
9528 12911824 : && !continues (jump_target)
9529 12911917 : && (!switches (jump_target) || count == 0)
9530 12911794 : && !throws (jump_target)
9531 25938021 : && !*non_constant_p);
9532 :
9533 6649851 : cleanup_cond ();
9534 :
9535 6649851 : return NULL_TREE;
9536 : }
9537 :
9538 : /* Evaluate a SWITCH_EXPR for side-effects. Handles switch and break jump
9539 : semantics. */
9540 :
9541 : static tree
9542 50127 : cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
9543 : bool *non_constant_p, bool *overflow_p,
9544 : tree *jump_target)
9545 : {
9546 50127 : tree cond
9547 50127 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
9548 50127 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
9549 : non_constant_p, overflow_p,
9550 : jump_target);
9551 50127 : if (*jump_target)
9552 : return NULL_TREE;
9553 50127 : VERIFY_CONSTANT (cond);
9554 49834 : if (TREE_CODE (cond) != INTEGER_CST)
9555 : {
9556 : /* If the condition doesn't reduce to an INTEGER_CST it isn't a usable
9557 : switch condition even if it's constant enough for other things
9558 : (c++/113545). */
9559 0 : gcc_checking_assert (ctx->quiet);
9560 0 : *non_constant_p = true;
9561 0 : return t;
9562 : }
9563 :
9564 49834 : *jump_target = cond;
9565 :
9566 49834 : tree body
9567 49834 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_BODY (t) : SWITCH_BODY (t);
9568 49834 : constexpr_ctx new_ctx = *ctx;
9569 49834 : constexpr_switch_state css = css_default_not_seen;
9570 49834 : new_ctx.css_state = &css;
9571 49834 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
9572 : non_constant_p, overflow_p, jump_target);
9573 87143 : if (switches (jump_target) && css == css_default_seen)
9574 : {
9575 : /* If the SWITCH_EXPR body has default: label, process it once again,
9576 : this time instructing label_matches to return true for default:
9577 : label on switches (jump_target). */
9578 37267 : css = css_default_processing;
9579 37267 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
9580 : non_constant_p, overflow_p, jump_target);
9581 : }
9582 49834 : if (breaks (jump_target) || switches (jump_target))
9583 21439 : *jump_target = NULL_TREE;
9584 : return NULL_TREE;
9585 : }
9586 :
9587 : /* Find the object of TYPE under initialization in CTX. */
9588 :
9589 : static tree
9590 16716 : lookup_placeholder (const constexpr_ctx *ctx, value_cat lval, tree type)
9591 : {
9592 16716 : if (!ctx)
9593 : return NULL_TREE;
9594 :
9595 : /* Prefer the outermost matching object, but don't cross
9596 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors. */
9597 16320 : if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
9598 574 : if (tree outer_ob = lookup_placeholder (ctx->parent, lval, type))
9599 : return outer_ob;
9600 :
9601 : /* We could use ctx->object unconditionally, but using ctx->ctor when we
9602 : can is a minor optimization. */
9603 16142 : if (!lval && ctx->ctor && same_type_p (TREE_TYPE (ctx->ctor), type))
9604 302 : return ctx->ctor;
9605 :
9606 15840 : if (!ctx->object)
9607 : return NULL_TREE;
9608 :
9609 : /* Since an object cannot have a field of its own type, we can search outward
9610 : from ctx->object to find the unique containing object of TYPE. */
9611 : tree ob = ctx->object;
9612 15816 : while (ob)
9613 : {
9614 15816 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type))
9615 : break;
9616 219 : if (handled_component_p (ob))
9617 217 : ob = TREE_OPERAND (ob, 0);
9618 : else
9619 : ob = NULL_TREE;
9620 : }
9621 :
9622 : /* Like in replace_placeholders_r. */
9623 15599 : return unshare_expr (ob);
9624 : }
9625 :
9626 : /* Complain about an attempt to evaluate inline assembly. If FUNDEF_P is
9627 : true, we're checking a constexpr function body. */
9628 :
9629 : static void
9630 35 : inline_asm_in_constexpr_error (location_t loc, bool fundef_p)
9631 : {
9632 35 : auto_diagnostic_group d;
9633 35 : if (constexpr_error (loc, fundef_p, "inline assembly is not a "
9634 : "constant expression"))
9635 35 : inform (loc, "only unevaluated inline assembly is allowed in a "
9636 : "%<constexpr%> function in C++20");
9637 35 : }
9638 :
9639 : /* We're getting the constant value of DECL in a manifestly constant-evaluated
9640 : context; maybe complain about that. */
9641 :
9642 : static void
9643 93649787 : maybe_warn_about_constant_value (location_t loc, tree decl)
9644 : {
9645 93649787 : static bool explained = false;
9646 93649787 : auto_diagnostic_group d;
9647 93649787 : if (cxx_dialect >= cxx17
9648 93480141 : && warn_interference_size
9649 93480141 : && !OPTION_SET_P (param_destruct_interfere_size)
9650 93480141 : && DECL_CONTEXT (decl) == std_node
9651 19137925 : && DECL_NAME (decl)
9652 19137919 : && id_equal (DECL_NAME (decl), "hardware_destructive_interference_size")
9653 16 : && (LOCATION_FILE (input_location) != main_input_filename
9654 10 : || module_exporting_p ())
9655 93649790 : && warning_at (loc, OPT_Winterference_size, "use of %qD", decl)
9656 93649796 : && !explained)
9657 : {
9658 6 : explained = true;
9659 6 : inform (loc, "its value can vary between compiler versions or "
9660 : "with different %<-mtune%> or %<-mcpu%> flags");
9661 6 : inform (loc, "if this use is part of a public ABI, change it to "
9662 : "instead use a constant variable you define");
9663 6 : inform (loc, "the default value for the current CPU tuning "
9664 : "is %d bytes", param_destruct_interfere_size);
9665 6 : inform (loc, "you can stabilize this value with %<--param "
9666 : "hardware_destructive_interference_size=%d%>, or disable "
9667 : "this warning with %<-Wno-interference-size%>",
9668 : param_destruct_interfere_size);
9669 : }
9670 93649787 : }
9671 :
9672 : /* For element type ELT_TYPE, return the appropriate type of the heap object
9673 : containing such element(s). COOKIE_SIZE is NULL or the size of cookie
9674 : in bytes. If COOKIE_SIZE is NULL, return array type
9675 : ELT_TYPE[FULL_SIZE / sizeof(ELT_TYPE)], otherwise return
9676 : struct { size_t[COOKIE_SIZE/sizeof(size_t)]; ELT_TYPE[N]; }
9677 : where N is computed such that the size of the struct fits into FULL_SIZE.
9678 : If ARG_SIZE is non-NULL, it is the first argument to the new operator.
9679 : It should be passed if ELT_TYPE is zero sized type in which case FULL_SIZE
9680 : will be also 0 and so it is not possible to determine the actual array
9681 : size. CTX, NON_CONSTANT_P and OVERFLOW_P are used during constant
9682 : expression evaluation of subexpressions of ARG_SIZE. */
9683 :
9684 : static tree
9685 118268 : build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type,
9686 : tree cookie_size, tree full_size, tree arg_size,
9687 : bool *non_constant_p, bool *overflow_p,
9688 : tree *jump_target)
9689 : {
9690 118268 : gcc_assert (cookie_size == NULL_TREE || tree_fits_uhwi_p (cookie_size));
9691 118268 : gcc_assert (tree_fits_uhwi_p (full_size));
9692 118268 : unsigned HOST_WIDE_INT csz = cookie_size ? tree_to_uhwi (cookie_size) : 0;
9693 118268 : if (arg_size)
9694 : {
9695 9 : STRIP_NOPS (arg_size);
9696 9 : if (cookie_size)
9697 : {
9698 0 : if (TREE_CODE (arg_size) != PLUS_EXPR)
9699 : arg_size = NULL_TREE;
9700 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 0)) == INTEGER_CST
9701 0 : && tree_int_cst_equal (cookie_size,
9702 0 : TREE_OPERAND (arg_size, 0)))
9703 : {
9704 0 : arg_size = TREE_OPERAND (arg_size, 1);
9705 0 : STRIP_NOPS (arg_size);
9706 : }
9707 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 1)) == INTEGER_CST
9708 0 : && tree_int_cst_equal (cookie_size,
9709 0 : TREE_OPERAND (arg_size, 1)))
9710 : {
9711 0 : arg_size = TREE_OPERAND (arg_size, 0);
9712 0 : STRIP_NOPS (arg_size);
9713 : }
9714 : else
9715 : arg_size = NULL_TREE;
9716 : }
9717 9 : if (arg_size && TREE_CODE (arg_size) == MULT_EXPR)
9718 : {
9719 9 : tree op0 = TREE_OPERAND (arg_size, 0);
9720 9 : tree op1 = TREE_OPERAND (arg_size, 1);
9721 9 : if (integer_zerop (op0))
9722 9 : arg_size
9723 9 : = cxx_eval_constant_expression (ctx, op1, vc_prvalue,
9724 : non_constant_p, overflow_p,
9725 : jump_target);
9726 0 : else if (integer_zerop (op1))
9727 0 : arg_size
9728 0 : = cxx_eval_constant_expression (ctx, op0, vc_prvalue,
9729 : non_constant_p, overflow_p,
9730 : jump_target);
9731 : else
9732 : arg_size = NULL_TREE;
9733 9 : if (*jump_target)
9734 : return NULL_TREE;
9735 : }
9736 : else
9737 : arg_size = NULL_TREE;
9738 : }
9739 :
9740 9 : unsigned HOST_WIDE_INT fsz = tree_to_uhwi (arg_size ? arg_size : full_size);
9741 118268 : if (!arg_size)
9742 : {
9743 118259 : unsigned HOST_WIDE_INT esz = int_size_in_bytes (elt_type);
9744 118259 : gcc_assert (fsz >= csz);
9745 118259 : fsz -= csz;
9746 118259 : if (esz)
9747 118259 : fsz /= esz;
9748 : }
9749 118268 : tree itype2 = build_index_type (size_int (fsz - 1));
9750 118268 : if (!cookie_size)
9751 118259 : return build_cplus_array_type (elt_type, itype2);
9752 9 : return build_new_constexpr_heap_type (elt_type, cookie_size, itype2);
9753 : }
9754 :
9755 : /* Handle the case when a cleanup of some expression throws. JMP_TARGET
9756 : indicates whether the cleanup threw or not, *JUMP_TARGET indicates whether
9757 : the expression which needed the cleanup threw. If both threw, diagnose
9758 : it and return NULL, otherwise return R. If only the cleanup threw, set
9759 : *JUMP_TARGET to the exception object from the cleanup. */
9760 :
9761 : static tree
9762 1743624 : merge_jump_target (location_t loc, const constexpr_ctx *ctx, tree r,
9763 : bool *non_constant_p, tree *jump_target, tree jmp_target)
9764 : {
9765 1743624 : if (!throws (&jmp_target))
9766 : return r;
9767 14 : if (throws (jump_target))
9768 : {
9769 : /* [except.throw]/9 - If the exception handling mechanism
9770 : handling an uncaught exception directly invokes a function
9771 : that exits via an exception, the function std::terminate is
9772 : invoked. */
9773 12 : if (!ctx->quiet)
9774 : {
9775 4 : auto_diagnostic_group d;
9776 4 : diagnose_std_terminate (loc, ctx, *jump_target);
9777 4 : inform (loc, "destructor exited with an exception");
9778 4 : }
9779 12 : *non_constant_p = true;
9780 12 : *jump_target = NULL_TREE;
9781 12 : return NULL_TREE;
9782 : }
9783 2 : *jump_target = jmp_target;
9784 2 : return r;
9785 : }
9786 :
9787 : /* Attempt to reduce the expression T to a constant value.
9788 : On failure, issue diagnostic and return error_mark_node. */
9789 : /* FIXME unify with c_fully_fold */
9790 : /* FIXME overflow_p is too global */
9791 :
9792 : tree
9793 3037128128 : cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
9794 : value_cat lval,
9795 : bool *non_constant_p, bool *overflow_p,
9796 : tree *jump_target)
9797 : {
9798 3037128128 : if (*jump_target)
9799 : {
9800 : /* If we are jumping, ignore all statements/expressions except those
9801 : that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies. */
9802 1623050 : switch (TREE_CODE (t))
9803 : {
9804 : case BIND_EXPR:
9805 : case STATEMENT_LIST:
9806 : case LOOP_EXPR:
9807 : case COND_EXPR:
9808 : case IF_STMT:
9809 : case DO_STMT:
9810 : case WHILE_STMT:
9811 : case FOR_STMT:
9812 : break;
9813 502192 : case LABEL_EXPR:
9814 502192 : case CASE_LABEL_EXPR:
9815 502192 : if (label_matches (ctx, jump_target, t))
9816 : /* Found it. */
9817 49792 : *jump_target = NULL_TREE;
9818 : return NULL_TREE;
9819 : default:
9820 : return NULL_TREE;
9821 : }
9822 : }
9823 3035750926 : if (error_operand_p (t))
9824 : {
9825 194 : *non_constant_p = true;
9826 194 : return t;
9827 : }
9828 :
9829 : /* Change the input location to the currently processed expression for
9830 : better error messages when a subexpression has no location. */
9831 3035750732 : location_t loc = cp_expr_loc_or_input_loc (t);
9832 6071496032 : iloc_sentinel sentinel (loc);
9833 :
9834 3035750732 : STRIP_ANY_LOCATION_WRAPPER (t);
9835 :
9836 3035750732 : if (CONSTANT_CLASS_P (t))
9837 : {
9838 463471130 : if (TREE_OVERFLOW (t))
9839 : {
9840 62 : if (!ctx->quiet)
9841 15 : permerror (input_location, "overflow in constant expression");
9842 62 : if (!flag_permissive || ctx->quiet)
9843 59 : *overflow_p = true;
9844 : }
9845 :
9846 463471130 : if (TREE_CODE (t) == INTEGER_CST
9847 441092858 : && TYPE_PTR_P (TREE_TYPE (t))
9848 : /* INTEGER_CST with pointer-to-method type is only used
9849 : for a virtual method in a pointer to member function.
9850 : Don't reject those. */
9851 2121782 : && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != METHOD_TYPE
9852 465592585 : && !integer_zerop (t))
9853 : {
9854 6 : if (!ctx->quiet)
9855 0 : error ("value %qE of type %qT is not a constant expression",
9856 0 : t, TREE_TYPE (t));
9857 6 : *non_constant_p = true;
9858 : }
9859 :
9860 : return t;
9861 : }
9862 :
9863 : /* Avoid excessively long constexpr evaluations. */
9864 2572279602 : if (++ctx->global->constexpr_ops_count >= constexpr_ops_limit)
9865 : {
9866 9 : if (!ctx->quiet)
9867 3 : error_at (loc,
9868 : "%<constexpr%> evaluation operation count exceeds limit of "
9869 : "%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
9870 : constexpr_ops_limit);
9871 9 : ctx->global->constexpr_ops_count = INTTYPE_MINIMUM (HOST_WIDE_INT);
9872 9 : *non_constant_p = true;
9873 9 : return t;
9874 : }
9875 :
9876 2572279593 : constexpr_ctx new_ctx;
9877 2572279593 : tree r = t;
9878 :
9879 2572279593 : tree_code tcode = TREE_CODE (t);
9880 2572279593 : switch (tcode)
9881 : {
9882 60027831 : case RESULT_DECL:
9883 60027831 : if (lval)
9884 : return t;
9885 : /* We ask for an rvalue for the RESULT_DECL when indirecting
9886 : through an invisible reference, or in named return value
9887 : optimization. */
9888 147332 : if (tree v = ctx->global->get_value (t))
9889 : return v;
9890 : else
9891 : {
9892 3 : if (!ctx->quiet)
9893 0 : error ("%qE is not a constant expression", t);
9894 3 : *non_constant_p = true;
9895 : }
9896 3 : break;
9897 :
9898 300761231 : case VAR_DECL:
9899 300761231 : if (DECL_HAS_VALUE_EXPR_P (t))
9900 : {
9901 9257836 : if (is_normal_capture_proxy (t)
9902 9257836 : && current_function_decl == DECL_CONTEXT (t))
9903 : {
9904 : /* Function parms aren't constexpr within the function
9905 : definition, so don't try to look at the closure. But if the
9906 : captured variable is constant, try to evaluate it directly. */
9907 631992 : r = DECL_CAPTURED_VARIABLE (t);
9908 : }
9909 : else
9910 8625844 : r = DECL_VALUE_EXPR (t);
9911 :
9912 9257836 : tree type = TREE_TYPE (t);
9913 9257836 : if (TYPE_REF_P (type) != TYPE_REF_P (TREE_TYPE (r)))
9914 : {
9915 : /* Adjust r to match the reference-ness of t. */
9916 259284 : if (TYPE_REF_P (type))
9917 255093 : r = build_address (r);
9918 : else
9919 4191 : r = convert_from_reference (r);
9920 : }
9921 9257836 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
9922 9257836 : overflow_p, jump_target);
9923 : }
9924 : /* fall through */
9925 302309689 : case CONST_DECL:
9926 : /* We used to not check lval for CONST_DECL, but darwin.cc uses
9927 : CONST_DECL for aggregate constants. */
9928 302309689 : if (lval)
9929 : return t;
9930 215088965 : else if (t == ctx->object)
9931 1029373 : return ctx->ctor;
9932 214059592 : if (VAR_P (t))
9933 : {
9934 203253304 : if (tree v = ctx->global->get_value (t))
9935 : {
9936 : r = v;
9937 : break;
9938 : }
9939 137954236 : if (ctx->global->is_outside_lifetime (t))
9940 : {
9941 137 : if (!ctx->quiet)
9942 39 : outside_lifetime_error (loc, t);
9943 137 : *non_constant_p = true;
9944 137 : break;
9945 : }
9946 : }
9947 148760387 : if (ctx->manifestly_const_eval == mce_true)
9948 93649787 : maybe_warn_about_constant_value (loc, t);
9949 148760387 : if (COMPLETE_TYPE_P (TREE_TYPE (t))
9950 148760387 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9951 : {
9952 : /* If the class is empty, we aren't actually loading anything. */
9953 252817 : r = build_constructor (TREE_TYPE (t), NULL);
9954 252817 : TREE_CONSTANT (r) = true;
9955 : }
9956 148507570 : else if (ctx->strict)
9957 148157604 : r = decl_really_constant_value (t, /*unshare_p=*/false);
9958 : else
9959 349966 : r = decl_constant_value (t, /*unshare_p=*/false);
9960 148757690 : if (TREE_CODE (r) == TARGET_EXPR
9961 148757690 : && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
9962 0 : r = TARGET_EXPR_INITIAL (r);
9963 148757690 : if (DECL_P (r)
9964 : /* P2280 allows references to unknown. */
9965 149047096 : && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
9966 : {
9967 34701347 : if (!ctx->quiet)
9968 177 : non_const_var_error (loc, r, /*fundef_p*/false);
9969 34701347 : *non_constant_p = true;
9970 : }
9971 : break;
9972 :
9973 : case DEBUG_BEGIN_STMT:
9974 : /* ??? It might be nice to retain this information somehow, so
9975 : as to be able to step into a constexpr function call. */
9976 : /* Fall through. */
9977 :
9978 : case FUNCTION_DECL:
9979 : case TEMPLATE_DECL:
9980 : case LABEL_DECL:
9981 : case LABEL_EXPR:
9982 : case CASE_LABEL_EXPR:
9983 : case PREDICT_EXPR:
9984 : case OMP_DECLARE_MAPPER:
9985 : case REFLECT_EXPR:
9986 : return t;
9987 :
9988 307772375 : case PARM_DECL:
9989 307772375 : if (lval && !TYPE_REF_P (TREE_TYPE (t)))
9990 : {
9991 : /* glvalue use. */
9992 21852876 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9993 220775 : if (tree v = ctx->global->get_value (t))
9994 2070839753 : r = v;
9995 : }
9996 285919499 : else if (tree v = ctx->global->get_value (t))
9997 : {
9998 167064560 : r = v;
9999 167064560 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
10000 11305 : r = cxx_eval_constant_expression (ctx, r, vc_prvalue,
10001 : non_constant_p, overflow_p,
10002 : jump_target);
10003 167064560 : if (*jump_target)
10004 : return NULL_TREE;
10005 : }
10006 118854939 : else if (lval)
10007 : /* Defer in case this is only used for its type. */;
10008 118854939 : else if (ctx->global->is_outside_lifetime (t))
10009 : {
10010 18 : if (!ctx->quiet)
10011 6 : outside_lifetime_error (loc, t);
10012 18 : *non_constant_p = true;
10013 18 : break;
10014 : }
10015 118854921 : else if (COMPLETE_TYPE_P (TREE_TYPE (t))
10016 118854921 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
10017 : {
10018 : /* If the class is empty, we aren't actually loading anything. */
10019 41552 : r = build_constructor (TREE_TYPE (t), NULL);
10020 41552 : TREE_CONSTANT (r) = true;
10021 : }
10022 118813369 : else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t)))
10023 : /* P2280 allows references to unknown... */;
10024 118536525 : else if (p2280_active_p (ctx) && is_this_parameter (t))
10025 : /* ...as well as the this pointer. */;
10026 : else
10027 : {
10028 118081539 : if (!ctx->quiet)
10029 199 : error ("%qE is not a constant expression", t);
10030 118081539 : *non_constant_p = true;
10031 : }
10032 : break;
10033 :
10034 207853872 : case CALL_EXPR:
10035 207853872 : case AGGR_INIT_EXPR:
10036 207853872 : r = cxx_eval_call_expression (ctx, t, lval,
10037 : non_constant_p, overflow_p, jump_target);
10038 207853872 : break;
10039 :
10040 21572025 : case DECL_EXPR:
10041 21572025 : {
10042 21572025 : r = DECL_EXPR_DECL (t);
10043 21572025 : if (TREE_CODE (r) == USING_DECL)
10044 : {
10045 9452 : r = void_node;
10046 9452 : break;
10047 : }
10048 :
10049 21562573 : if (VAR_P (r)
10050 21562573 : && (TREE_STATIC (r)
10051 21399061 : || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
10052 : /* Allow __FUNCTION__ etc. */
10053 163512 : && !DECL_ARTIFICIAL (r)
10054 21563470 : && !decl_constant_var_p (r))
10055 : {
10056 7 : if (!ctx->quiet)
10057 : {
10058 2 : if (CP_DECL_THREAD_LOCAL_P (r))
10059 1 : error_at (loc, "control passes through definition of %qD "
10060 : "with thread storage duration", r);
10061 : else
10062 1 : error_at (loc, "control passes through definition of %qD "
10063 : "with static storage duration", r);
10064 : }
10065 7 : *non_constant_p = true;
10066 7 : break;
10067 : }
10068 :
10069 : /* make_rtl_for_nonlocal_decl could have deferred emission of
10070 : a local static var, but if it appears in a statement expression
10071 : which is constant expression evaluated to e.g. just the address
10072 : of the variable, its DECL_EXPR will never be seen during
10073 : gimple lowering's record_vars_into as the statement expression
10074 : will not be in the IL at all. */
10075 21562566 : if (VAR_P (r)
10076 21562566 : && TREE_STATIC (r)
10077 163505 : && !DECL_REALLY_EXTERN (r)
10078 163483 : && DECL_FUNCTION_SCOPE_P (r)
10079 163483 : && !var_in_maybe_constexpr_fn (r)
10080 21562569 : && decl_constant_var_p (r))
10081 : {
10082 3 : varpool_node *node = varpool_node::get (r);
10083 3 : if (node == NULL || !node->definition)
10084 3 : rest_of_decl_compilation (r, 0, at_eof);
10085 : }
10086 :
10087 42881791 : if (AGGREGATE_TYPE_P (TREE_TYPE (r))
10088 40210203 : || VECTOR_TYPE_P (TREE_TYPE (r)))
10089 : {
10090 2917893 : new_ctx = *ctx;
10091 2917893 : new_ctx.object = r;
10092 2917893 : new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
10093 2917893 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
10094 2917893 : ctx->global->put_value (r, new_ctx.ctor);
10095 2917893 : ctx = &new_ctx;
10096 : }
10097 :
10098 21562566 : if (tree init = DECL_INITIAL (r))
10099 : {
10100 11240691 : init = cxx_eval_constant_expression (ctx, init, vc_prvalue,
10101 : non_constant_p, overflow_p,
10102 : jump_target);
10103 11240691 : if (*jump_target)
10104 : return NULL_TREE;
10105 : /* Don't share a CONSTRUCTOR that might be changed. */
10106 11240691 : init = unshare_constructor (init);
10107 : /* Remember that a constant object's constructor has already
10108 : run. */
10109 22481382 : if (CLASS_TYPE_P (TREE_TYPE (r))
10110 11790917 : && CP_TYPE_CONST_P (TREE_TYPE (r)))
10111 71521 : TREE_READONLY (init) = true;
10112 11240691 : ctx->global->put_value (r, init);
10113 : }
10114 10321875 : else if (ctx == &new_ctx)
10115 : /* We gave it a CONSTRUCTOR above. */;
10116 : else
10117 8031327 : ctx->global->put_value (r, NULL_TREE);
10118 : }
10119 : break;
10120 :
10121 27125745 : case TARGET_EXPR:
10122 27125745 : {
10123 27125745 : tree type = TREE_TYPE (t);
10124 :
10125 27125745 : if (!literal_type_p (type))
10126 : {
10127 7109 : if (!ctx->quiet)
10128 : {
10129 0 : auto_diagnostic_group d;
10130 0 : error ("temporary of non-literal type %qT in a "
10131 : "constant expression", type);
10132 0 : explain_non_literal_class (type);
10133 0 : }
10134 7109 : *non_constant_p = true;
10135 11859287 : break;
10136 : }
10137 27118636 : gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (t));
10138 : /* Avoid evaluating a TARGET_EXPR more than once. */
10139 27118636 : tree slot = TARGET_EXPR_SLOT (t);
10140 27118636 : if (tree v = ctx->global->get_value (slot))
10141 : {
10142 2142 : if (lval)
10143 10958621 : return slot;
10144 : r = v;
10145 : break;
10146 : }
10147 27116494 : if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
10148 : {
10149 : /* We're being expanded without an explicit target, so start
10150 : initializing a new object; expansion with an explicit target
10151 : strips the TARGET_EXPR before we get here. */
10152 20586510 : new_ctx = *ctx;
10153 : /* Link CTX to NEW_CTX so that lookup_placeholder can resolve
10154 : any PLACEHOLDER_EXPR within the initializer that refers to the
10155 : former object under construction. */
10156 20586510 : new_ctx.parent = ctx;
10157 20586510 : new_ctx.ctor = build_constructor (type, NULL);
10158 20586510 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
10159 20586510 : new_ctx.object = slot;
10160 20586510 : ctx->global->put_value (new_ctx.object, new_ctx.ctor);
10161 20586510 : ctx = &new_ctx;
10162 : }
10163 :
10164 : /* If the initializer is complex, evaluate it to initialize slot. */
10165 27116494 : bool is_complex = target_expr_needs_replace (t);
10166 27116494 : if (is_complex)
10167 : /* In case no initialization actually happens, clear out any
10168 : void_node from a previous evaluation. */
10169 493 : ctx->global->put_value (slot, NULL_TREE);
10170 :
10171 : /* Pass vc_prvalue because this indicates
10172 : initialization of a temporary. */
10173 27116494 : r = cxx_eval_constant_expression (ctx, TARGET_EXPR_INITIAL (t),
10174 : vc_prvalue, non_constant_p,
10175 : overflow_p, jump_target);
10176 27116494 : if (*non_constant_p)
10177 : break;
10178 15265402 : if (ctx->save_exprs)
10179 10095066 : ctx->save_exprs->safe_push (slot);
10180 15265402 : if (*jump_target)
10181 : {
10182 669 : if (!is_complex
10183 669 : && !(AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
10184 : /* If TARGET_EXPR_INITIAL throws exception and slot's value
10185 : has not been changed yet, CLEANUP_POINT_EXPR handling
10186 : could see there void_node from a previous evaluation
10187 : and complain. */
10188 6 : ctx->global->put_value (slot, NULL_TREE);
10189 : return NULL_TREE;
10190 : }
10191 15264733 : if (!is_complex)
10192 : {
10193 15264320 : r = unshare_constructor (r);
10194 : /* Adjust the type of the result to the type of the temporary. */
10195 15264320 : r = adjust_temp_type (type, r);
10196 15264320 : ctx->global->put_value (slot, r);
10197 : }
10198 15264733 : if (TARGET_EXPR_CLEANUP (t)
10199 15264733 : && (!CLEANUP_EH_ONLY (t) || cxx_dialect >= cxx26))
10200 : {
10201 1447712 : ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t));
10202 : /* Mark CLEANUP_EH_ONLY cleanups by pushing NULL_TREE after
10203 : them. */
10204 1447712 : if (CLEANUP_EH_ONLY (t))
10205 2164 : ctx->global->cleanups->safe_push (NULL_TREE);
10206 : }
10207 15264733 : if (lval)
10208 : return slot;
10209 4307837 : if (is_complex)
10210 0 : r = ctx->global->get_value (slot);
10211 : }
10212 4307837 : break;
10213 :
10214 104249503 : case INIT_EXPR:
10215 104249503 : case MODIFY_EXPR:
10216 104249503 : gcc_assert (jump_target == NULL || *jump_target == NULL_TREE);
10217 104249503 : r = cxx_eval_store_expression (ctx, t, lval,
10218 : non_constant_p, overflow_p, jump_target);
10219 104249503 : break;
10220 :
10221 0 : case SCOPE_REF:
10222 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
10223 : lval,
10224 : non_constant_p, overflow_p,
10225 : jump_target);
10226 0 : break;
10227 :
10228 64987581 : case RETURN_EXPR:
10229 64987581 : if (TREE_OPERAND (t, 0) != NULL_TREE)
10230 64661621 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10231 : lval,
10232 : non_constant_p, overflow_p,
10233 : jump_target);
10234 64987577 : if (!throws (jump_target))
10235 64987209 : *jump_target = t;
10236 : break;
10237 54031 : case BREAK_STMT:
10238 54031 : case CONTINUE_STMT:
10239 54031 : *jump_target = t;
10240 54031 : break;
10241 :
10242 972075 : case SAVE_EXPR:
10243 : /* Avoid evaluating a SAVE_EXPR more than once. */
10244 972075 : if (tree v = ctx->global->get_value (t))
10245 : r = v;
10246 : else
10247 : {
10248 950046 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10249 : vc_prvalue, non_constant_p,
10250 : overflow_p, jump_target);
10251 950046 : if (*non_constant_p || *jump_target)
10252 : break;
10253 12799 : ctx->global->put_value (t, r);
10254 12799 : if (ctx->save_exprs)
10255 9259 : ctx->save_exprs->safe_push (t);
10256 : }
10257 : break;
10258 :
10259 63198020 : case NON_LVALUE_EXPR:
10260 63198020 : case EXPR_STMT:
10261 63198020 : case EH_SPEC_BLOCK:
10262 63198020 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10263 : lval,
10264 : non_constant_p, overflow_p,
10265 : jump_target);
10266 63198020 : break;
10267 :
10268 9424 : case TRY_BLOCK:
10269 9424 : r = cxx_eval_constant_expression (ctx, TRY_STMTS (t), lval,
10270 : non_constant_p, overflow_p,
10271 : jump_target);
10272 9424 : if (!*non_constant_p && throws (jump_target))
10273 3799 : if (tree h = TRY_HANDLERS (t))
10274 : {
10275 3799 : tree type = strip_array_types (TREE_TYPE (*jump_target));
10276 3799 : if (TREE_CODE (h) == STATEMENT_LIST)
10277 : {
10278 938 : for (tree stmt : tsi_range (h))
10279 904 : if (TREE_CODE (stmt) == HANDLER
10280 904 : && handler_match_for_exception_type (stmt, type))
10281 : {
10282 : h = stmt;
10283 : break;
10284 : }
10285 462 : if (TREE_CODE (h) == STATEMENT_LIST)
10286 : h = NULL_TREE;
10287 : }
10288 3337 : else if (TREE_CODE (h) != HANDLER
10289 3337 : || !handler_match_for_exception_type (h, type))
10290 : h = NULL_TREE;
10291 : if (h)
10292 : {
10293 3765 : gcc_assert (VAR_P (*jump_target));
10294 3765 : ctx->global->caught_exceptions.safe_push (*jump_target);
10295 3765 : ctx->global->caught_exceptions.safe_push (HANDLER_TYPE (h));
10296 3765 : *jump_target = NULL_TREE;
10297 3765 : r = cxx_eval_constant_expression (ctx, HANDLER_BODY (h),
10298 : vc_discard, non_constant_p,
10299 : overflow_p, jump_target);
10300 : }
10301 : }
10302 : break;
10303 :
10304 92426006 : case CLEANUP_POINT_EXPR:
10305 92426006 : {
10306 92426006 : auto_vec<tree, 2> cleanups;
10307 92426006 : vec<tree> *prev_cleanups = ctx->global->cleanups;
10308 92426006 : ctx->global->cleanups = &cleanups;
10309 :
10310 92426006 : auto_vec<tree, 10> save_exprs;
10311 92426006 : constexpr_ctx new_ctx = *ctx;
10312 92426006 : new_ctx.save_exprs = &save_exprs;
10313 :
10314 92426006 : r = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 0),
10315 : lval,
10316 : non_constant_p, overflow_p,
10317 : jump_target);
10318 :
10319 92426004 : ctx->global->cleanups = prev_cleanups;
10320 92426004 : unsigned int i;
10321 92426004 : tree cleanup, jmp_target = NULL_TREE;
10322 92426004 : bool eh = throws (jump_target);
10323 : /* Evaluate the cleanups. */
10324 186197210 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
10325 1345202 : if (cleanup == NULL_TREE)
10326 : {
10327 : /* NULL_TREE cleanup is a marker that before it is
10328 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it
10329 : if the body didn't throw. */
10330 2141 : if (!eh)
10331 2139 : --i;
10332 : }
10333 : else
10334 1343061 : cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard,
10335 : non_constant_p, overflow_p,
10336 : &jmp_target);
10337 :
10338 : /* Forget SAVE_EXPRs and TARGET_EXPRs created by this
10339 : full-expression. */
10340 287382337 : for (tree save_expr : save_exprs)
10341 10104325 : destroy_value_checked (ctx, save_expr, non_constant_p);
10342 92426004 : if (throws (&jmp_target))
10343 0 : *jump_target = jmp_target;
10344 92426004 : }
10345 92426004 : break;
10346 :
10347 59312415 : case MUST_NOT_THROW_EXPR:
10348 59312415 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10349 : lval,
10350 : non_constant_p, overflow_p,
10351 : jump_target);
10352 59312413 : if (throws (jump_target))
10353 : {
10354 : /* [except.handle]/7 - If the search for a handler exits the
10355 : function body of a function with a non-throwing exception
10356 : specification, the function std::terminate is invoked. */
10357 54 : if (!ctx->quiet)
10358 : {
10359 18 : auto_diagnostic_group d;
10360 18 : diagnose_std_terminate (loc, ctx, *jump_target);
10361 18 : if (MUST_NOT_THROW_NOEXCEPT_P (t)
10362 14 : && ctx->call
10363 32 : && ctx->call->fundef)
10364 14 : inform (loc, "uncaught exception exited from %<noexcept%> "
10365 : "function %qD",
10366 : ctx->call->fundef->decl);
10367 4 : else if (MUST_NOT_THROW_THROW_P (t))
10368 2 : inform (loc, "destructor exited with an exception after "
10369 : "initializing the exception object");
10370 2 : else if (MUST_NOT_THROW_CATCH_P (t))
10371 2 : inform (loc, "constructor exited with another exception while "
10372 : "entering handler");
10373 18 : }
10374 54 : *non_constant_p = true;
10375 54 : *jump_target = NULL_TREE;
10376 54 : r = NULL_TREE;
10377 : }
10378 : break;
10379 :
10380 0 : case TRY_CATCH_EXPR:
10381 0 : if (TREE_OPERAND (t, 0) == NULL_TREE)
10382 : {
10383 0 : r = void_node;
10384 0 : break;
10385 : }
10386 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10387 : non_constant_p, overflow_p,
10388 : jump_target);
10389 0 : if (!*non_constant_p && throws (jump_target))
10390 : {
10391 0 : tree jmp_target = NULL_TREE;
10392 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
10393 : non_constant_p, overflow_p,
10394 : &jmp_target);
10395 0 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10396 : jmp_target);
10397 : }
10398 : break;
10399 :
10400 842 : case TRY_FINALLY_EXPR:
10401 842 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10402 : non_constant_p, overflow_p,
10403 : jump_target);
10404 842 : if (!*non_constant_p)
10405 : {
10406 827 : tree jmp_target = NULL_TREE;
10407 : /* Also evaluate the cleanup. */
10408 827 : if (TREE_CODE (TREE_OPERAND (t, 1)) == EH_ELSE_EXPR
10409 827 : && throws (jump_target))
10410 0 : cxx_eval_constant_expression (ctx,
10411 0 : TREE_OPERAND (TREE_OPERAND (t, 1),
10412 : 1), vc_discard,
10413 : non_constant_p, overflow_p,
10414 : &jmp_target);
10415 : else
10416 827 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
10417 : non_constant_p, overflow_p,
10418 : &jmp_target);
10419 827 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10420 : jmp_target);
10421 : }
10422 : break;
10423 :
10424 0 : case EH_ELSE_EXPR:
10425 : /* Evaluate any cleanup that applies to non-EH exits. */
10426 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_discard,
10427 : non_constant_p, overflow_p,
10428 : jump_target);
10429 :
10430 : /* The EH path is handled in TRY_FINALLY_EXPR handling above. */
10431 0 : break;
10432 :
10433 3932888 : case CLEANUP_STMT:
10434 3932888 : r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
10435 : non_constant_p, overflow_p,
10436 : jump_target);
10437 3932902 : if ((!CLEANUP_EH_ONLY (t) || throws (jump_target)) && !*non_constant_p)
10438 : {
10439 1742797 : iloc_sentinel ils (loc);
10440 1742797 : tree jmp_target = NULL_TREE;
10441 : /* Also evaluate the cleanup. */
10442 1742797 : cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), vc_discard,
10443 : non_constant_p, overflow_p,
10444 : &jmp_target);
10445 1742797 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10446 : jmp_target);
10447 1742797 : }
10448 : break;
10449 :
10450 : /* These differ from cxx_eval_unary_expression in that this doesn't
10451 : check for a constant operand or result; an address can be
10452 : constant without its operand being, and vice versa. */
10453 104550846 : case MEM_REF:
10454 104550846 : case INDIRECT_REF:
10455 104550846 : r = cxx_eval_indirect_ref (ctx, t, lval,
10456 : non_constant_p, overflow_p,
10457 : jump_target);
10458 104550846 : break;
10459 :
10460 101970011 : case ADDR_EXPR:
10461 101970011 : {
10462 101970011 : tree oldop = TREE_OPERAND (t, 0);
10463 101970011 : tree op = cxx_eval_constant_expression (ctx, oldop, vc_glvalue,
10464 : non_constant_p, overflow_p,
10465 : jump_target);
10466 101970011 : if (*jump_target)
10467 : return NULL_TREE;
10468 : /* Don't VERIFY_CONSTANT here. */
10469 101970006 : if (*non_constant_p)
10470 : return t;
10471 82262945 : gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
10472 : /* This function does more aggressive folding than fold itself. */
10473 82262945 : r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
10474 82262945 : if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
10475 : {
10476 57019009 : ggc_free (r);
10477 57019009 : return t;
10478 : }
10479 : break;
10480 : }
10481 :
10482 861430 : case REALPART_EXPR:
10483 861430 : case IMAGPART_EXPR:
10484 861430 : if (lval)
10485 : {
10486 1386 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10487 : non_constant_p, overflow_p,
10488 : jump_target);
10489 1386 : if (*jump_target)
10490 : return NULL_TREE;
10491 1386 : if (r == error_mark_node)
10492 : ;
10493 1386 : else if (r == TREE_OPERAND (t, 0) || lval == vc_discard)
10494 : r = t;
10495 : else
10496 1276 : r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
10497 : break;
10498 : }
10499 : /* FALLTHRU */
10500 26066249 : case CONJ_EXPR:
10501 26066249 : case FIX_TRUNC_EXPR:
10502 26066249 : case FLOAT_EXPR:
10503 26066249 : case NEGATE_EXPR:
10504 26066249 : case ABS_EXPR:
10505 26066249 : case ABSU_EXPR:
10506 26066249 : case BIT_NOT_EXPR:
10507 26066249 : case TRUTH_NOT_EXPR:
10508 26066249 : case FIXED_CONVERT_EXPR:
10509 26066249 : case VEC_DUPLICATE_EXPR:
10510 26066249 : r = cxx_eval_unary_expression (ctx, t, lval,
10511 : non_constant_p, overflow_p,
10512 : jump_target);
10513 26066249 : break;
10514 :
10515 9436360 : case SIZEOF_EXPR:
10516 9436360 : r = fold_sizeof_expr (t);
10517 : /* In a template, fold_sizeof_expr may merely create a new SIZEOF_EXPR,
10518 : which could lead to an infinite recursion. */
10519 9436360 : if (TREE_CODE (r) != SIZEOF_EXPR)
10520 9436360 : r = cxx_eval_constant_expression (ctx, r, lval,
10521 : non_constant_p, overflow_p,
10522 : jump_target);
10523 : else
10524 : {
10525 0 : *non_constant_p = true;
10526 0 : gcc_assert (ctx->quiet);
10527 : }
10528 :
10529 : break;
10530 :
10531 13721865 : case COMPOUND_EXPR:
10532 13721865 : {
10533 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
10534 : COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
10535 : introduced by build_call_a. */
10536 13721865 : tree op0 = TREE_OPERAND (t, 0);
10537 13721865 : tree op1 = TREE_OPERAND (t, 1);
10538 13721865 : STRIP_NOPS (op1);
10539 5578166 : if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
10540 16330005 : || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
10541 6864734 : r = cxx_eval_constant_expression (ctx, op0,
10542 : lval, non_constant_p, overflow_p,
10543 : jump_target);
10544 : else
10545 : {
10546 : /* Check that the LHS is constant and then discard it. */
10547 6857131 : cxx_eval_constant_expression (ctx, op0, vc_discard,
10548 : non_constant_p, overflow_p,
10549 : jump_target);
10550 6857131 : if (*jump_target)
10551 : return NULL_TREE;
10552 6849896 : if (*non_constant_p)
10553 : return t;
10554 6569783 : op1 = TREE_OPERAND (t, 1);
10555 6569783 : r = cxx_eval_constant_expression (ctx, op1,
10556 : lval, non_constant_p, overflow_p,
10557 : jump_target);
10558 : }
10559 : }
10560 : break;
10561 :
10562 112954598 : case POINTER_PLUS_EXPR:
10563 112954598 : case POINTER_DIFF_EXPR:
10564 112954598 : case PLUS_EXPR:
10565 112954598 : case MINUS_EXPR:
10566 112954598 : case MULT_EXPR:
10567 112954598 : case TRUNC_DIV_EXPR:
10568 112954598 : case CEIL_DIV_EXPR:
10569 112954598 : case FLOOR_DIV_EXPR:
10570 112954598 : case ROUND_DIV_EXPR:
10571 112954598 : case TRUNC_MOD_EXPR:
10572 112954598 : case CEIL_MOD_EXPR:
10573 112954598 : case ROUND_MOD_EXPR:
10574 112954598 : case RDIV_EXPR:
10575 112954598 : case EXACT_DIV_EXPR:
10576 112954598 : case MIN_EXPR:
10577 112954598 : case MAX_EXPR:
10578 112954598 : case LSHIFT_EXPR:
10579 112954598 : case RSHIFT_EXPR:
10580 112954598 : case LROTATE_EXPR:
10581 112954598 : case RROTATE_EXPR:
10582 112954598 : case BIT_IOR_EXPR:
10583 112954598 : case BIT_XOR_EXPR:
10584 112954598 : case BIT_AND_EXPR:
10585 112954598 : case TRUTH_XOR_EXPR:
10586 112954598 : case LT_EXPR:
10587 112954598 : case LE_EXPR:
10588 112954598 : case GT_EXPR:
10589 112954598 : case GE_EXPR:
10590 112954598 : case EQ_EXPR:
10591 112954598 : case NE_EXPR:
10592 112954598 : case SPACESHIP_EXPR:
10593 112954598 : case UNORDERED_EXPR:
10594 112954598 : case ORDERED_EXPR:
10595 112954598 : case UNLT_EXPR:
10596 112954598 : case UNLE_EXPR:
10597 112954598 : case UNGT_EXPR:
10598 112954598 : case UNGE_EXPR:
10599 112954598 : case UNEQ_EXPR:
10600 112954598 : case LTGT_EXPR:
10601 112954598 : case RANGE_EXPR:
10602 112954598 : case COMPLEX_EXPR:
10603 112954598 : r = cxx_eval_binary_expression (ctx, t, lval,
10604 : non_constant_p, overflow_p,
10605 : jump_target);
10606 112954598 : break;
10607 :
10608 : /* fold can introduce non-IF versions of these; still treat them as
10609 : short-circuiting. */
10610 15608633 : case TRUTH_AND_EXPR:
10611 15608633 : case TRUTH_ANDIF_EXPR:
10612 15608633 : r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
10613 : boolean_true_node,
10614 : non_constant_p, overflow_p,
10615 : jump_target);
10616 15608633 : break;
10617 :
10618 3084122 : case TRUTH_OR_EXPR:
10619 3084122 : case TRUTH_ORIF_EXPR:
10620 3084122 : r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
10621 : boolean_false_node,
10622 : non_constant_p, overflow_p,
10623 : jump_target);
10624 3084122 : break;
10625 :
10626 15700971 : case ARRAY_REF:
10627 15700971 : r = cxx_eval_array_reference (ctx, t, lval,
10628 : non_constant_p, overflow_p,
10629 : jump_target);
10630 15700971 : break;
10631 :
10632 116396785 : case COMPONENT_REF:
10633 116396785 : if (is_overloaded_fn (t))
10634 : {
10635 : /* We can only get here in checking mode via
10636 : build_non_dependent_expr, because any expression that
10637 : calls or takes the address of the function will have
10638 : pulled a FUNCTION_DECL out of the COMPONENT_REF. */
10639 6 : gcc_checking_assert (ctx->quiet || errorcount);
10640 6 : *non_constant_p = true;
10641 6 : return t;
10642 : }
10643 116396779 : r = cxx_eval_component_reference (ctx, t, lval,
10644 : non_constant_p, overflow_p,
10645 : jump_target);
10646 116396779 : break;
10647 :
10648 40745 : case BIT_FIELD_REF:
10649 40745 : r = cxx_eval_bit_field_ref (ctx, t, lval,
10650 : non_constant_p, overflow_p,
10651 : jump_target);
10652 40745 : break;
10653 :
10654 39678094 : case COND_EXPR:
10655 39678094 : case IF_STMT:
10656 39678094 : if (*jump_target)
10657 : {
10658 151552 : tree orig_jump = *jump_target;
10659 151552 : tree arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 1))
10660 303104 : ? TREE_OPERAND (t, 1) : void_node);
10661 : /* When jumping to a label, the label might be either in the
10662 : then or else blocks, so process then block first in skipping
10663 : mode first, and if we are still in the skipping mode at its end,
10664 : process the else block too. */
10665 151552 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
10666 : overflow_p, jump_target);
10667 : /* It's possible that we found the label in the then block. But
10668 : it could have been followed by another jumping statement, e.g.
10669 : say we're looking for case 1:
10670 : if (cond)
10671 : {
10672 : // skipped statements
10673 : case 1:; // clears up *jump_target
10674 : return 1; // and sets it to a RETURN_EXPR
10675 : }
10676 : else { ... }
10677 : in which case we need not go looking to the else block.
10678 : (goto is not allowed in a constexpr function.) */
10679 151552 : if (*jump_target == orig_jump)
10680 : {
10681 151609 : arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 2))
10682 151609 : ? TREE_OPERAND (t, 2) : void_node);
10683 151514 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
10684 : overflow_p, jump_target);
10685 : }
10686 : break;
10687 : }
10688 39526542 : r = cxx_eval_conditional_expression (ctx, t, lval,
10689 : non_constant_p, overflow_p,
10690 : jump_target);
10691 39526542 : break;
10692 11755 : case VEC_COND_EXPR:
10693 11755 : r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
10694 : overflow_p, jump_target);
10695 11755 : break;
10696 :
10697 23435868 : case CONSTRUCTOR:
10698 23435868 : if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
10699 : {
10700 : /* Don't re-process a constant CONSTRUCTOR. */
10701 20044525 : verify_constructor_flags (t);
10702 20044525 : if (TREE_CONSTANT (t))
10703 : return t;
10704 : }
10705 3391343 : if (TREE_CLOBBER_P (t))
10706 : {
10707 : /* Assignment from a clobber is handled in cxx_eval_store_expression;
10708 : a clobber by itself isn't a constant-expression. */
10709 242 : gcc_assert (ctx->quiet);
10710 242 : *non_constant_p = true;
10711 242 : break;
10712 : }
10713 3391101 : r = cxx_eval_bare_aggregate (ctx, t, lval,
10714 : non_constant_p, overflow_p, jump_target);
10715 3391101 : break;
10716 :
10717 794 : case VEC_INIT_EXPR:
10718 : /* We can get this in a defaulted constructor for a class with a
10719 : non-static data member of array type. Either the initializer will
10720 : be NULL, meaning default-initialization, or it will be an lvalue
10721 : or xvalue of the same type, meaning direct-initialization from the
10722 : corresponding member. */
10723 794 : r = cxx_eval_vec_init (ctx, t, lval,
10724 : non_constant_p, overflow_p, jump_target);
10725 794 : break;
10726 :
10727 43640 : case VEC_PERM_EXPR:
10728 43640 : r = cxx_eval_trinary_expression (ctx, t, lval,
10729 : non_constant_p, overflow_p,
10730 : jump_target);
10731 43640 : break;
10732 :
10733 7 : case PAREN_EXPR:
10734 7 : gcc_assert (!REF_PARENTHESIZED_P (t));
10735 : /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
10736 : constant expressions since it's unaffected by -fassociative-math. */
10737 7 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10738 : non_constant_p, overflow_p,
10739 : jump_target);
10740 7 : break;
10741 :
10742 445044389 : case NOP_EXPR:
10743 445044389 : if (REINTERPRET_CAST_P (t))
10744 : {
10745 145 : if (!ctx->quiet)
10746 6 : error_at (loc,
10747 : "%<reinterpret_cast%> is not a constant expression");
10748 145 : *non_constant_p = true;
10749 145 : return t;
10750 : }
10751 : /* FALLTHROUGH. */
10752 557680605 : case CONVERT_EXPR:
10753 557680605 : case VIEW_CONVERT_EXPR:
10754 557680605 : case UNARY_PLUS_EXPR:
10755 557680605 : {
10756 557680605 : tree oldop = TREE_OPERAND (t, 0);
10757 :
10758 557680605 : tree op = cxx_eval_constant_expression (ctx, oldop,
10759 557680605 : VOID_TYPE_P (TREE_TYPE (t))
10760 : ? vc_discard
10761 : : tcode == VIEW_CONVERT_EXPR
10762 523723142 : ? lval : vc_prvalue,
10763 : non_constant_p, overflow_p,
10764 : jump_target);
10765 557677906 : if (*jump_target)
10766 : return NULL_TREE;
10767 557673820 : if (*non_constant_p)
10768 : return t;
10769 449614045 : tree type = TREE_TYPE (t);
10770 :
10771 449614045 : if (VOID_TYPE_P (type))
10772 32747128 : return void_node;
10773 :
10774 416866917 : if (TREE_CODE (t) == CONVERT_EXPR
10775 61071331 : && ARITHMETIC_TYPE_P (type)
10776 5101768 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10777 416890668 : && ctx->strict)
10778 : {
10779 23656 : if (!ctx->quiet)
10780 54 : error_at (loc,
10781 : "conversion from pointer type %qT to arithmetic type "
10782 54 : "%qT in a constant expression", TREE_TYPE (op), type);
10783 23656 : *non_constant_p = true;
10784 23656 : return t;
10785 : }
10786 :
10787 : /* [expr.const]: a conversion from type cv void* to a pointer-to-object
10788 : type cannot be part of a core constant expression as a resolution to
10789 : DR 1312. */
10790 154521735 : if (TYPE_PTROB_P (type)
10791 151123406 : && TYPE_PTR_P (TREE_TYPE (op))
10792 95030920 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
10793 : /* Inside a call to std::construct_at,
10794 : std::allocator<T>::{,de}allocate, or
10795 : std::source_location::current, we permit casting from void*
10796 : because that is compiler-generated code. */
10797 1917849 : && !is_std_construct_at (ctx->call)
10798 166884 : && !is_std_allocator_allocate_deallocate (ctx->call)
10799 416929421 : && !is_std_source_location_current (ctx->call))
10800 : {
10801 : /* Likewise, don't error when casting from void* when OP is
10802 : &heap uninit and similar. */
10803 86001 : tree sop = tree_strip_nop_conversions (op);
10804 86001 : tree decl = NULL_TREE;
10805 86001 : if (TREE_CODE (sop) == ADDR_EXPR)
10806 63796 : decl = TREE_OPERAND (sop, 0);
10807 63796 : if (decl
10808 63796 : && VAR_P (decl)
10809 62368 : && DECL_ARTIFICIAL (decl)
10810 125730 : && (DECL_NAME (decl) == heap_identifier
10811 39888 : || DECL_NAME (decl) == heap_uninit_identifier
10812 4549 : || DECL_NAME (decl) == heap_vec_identifier
10813 2616 : || DECL_NAME (decl) == heap_vec_uninit_identifier))
10814 : /* OK */;
10815 : /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
10816 : cv void" to a pointer-to-object type T unless P is a null
10817 : pointer value or points to an object whose type is similar to
10818 : T. */
10819 24478 : else if (cxx_dialect > cxx23)
10820 : {
10821 24288 : if (integer_zerop (sop))
10822 30 : return build_int_cst (type, 0);
10823 24258 : r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10824 : NULL, jump_target);
10825 24258 : if (*jump_target)
10826 : return NULL_TREE;
10827 24258 : if (r)
10828 : {
10829 24211 : r = build1 (ADDR_EXPR, type, r);
10830 24211 : break;
10831 : }
10832 47 : if (!ctx->quiet)
10833 : {
10834 5 : gcc_assert (TREE_CODE (sop) == ADDR_EXPR);
10835 5 : auto_diagnostic_group d;
10836 5 : error_at (loc, "cast from %qT is not allowed in a "
10837 : "constant expression because "
10838 : "pointed-to type %qT is not similar to %qT",
10839 5 : TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)),
10840 5 : TREE_TYPE (type));
10841 5 : tree obj = build_fold_indirect_ref (sop);
10842 5 : if (TREE_CODE (obj) == COMPONENT_REF)
10843 4 : obj = TREE_OPERAND (obj, 1);
10844 5 : if (DECL_P (obj))
10845 5 : inform (DECL_SOURCE_LOCATION (obj),
10846 : "pointed-to object declared here");
10847 5 : }
10848 47 : *non_constant_p = true;
10849 47 : return t;
10850 : }
10851 : else
10852 : {
10853 190 : if (!ctx->quiet)
10854 26 : error_at (loc, "cast from %qT is not allowed in a "
10855 : "constant expression before C++26",
10856 26 : TREE_TYPE (op));
10857 190 : *non_constant_p = true;
10858 190 : return t;
10859 : }
10860 : }
10861 :
10862 : /* [expr.static.cast]/10: A prvalue of type "pointer to cv1 B", where
10863 : B is a class type, can be converted to a prvalue of type
10864 : "pointer to cv2 D", where D is a complete class derived from B, ...
10865 : If the prvalue of type "pointer to cv1 B" points to a B that is
10866 : actually a base class subobject of an object of type D, the
10867 : resulting pointer points to the enclosing object of type D.
10868 : Otherwise, the behavior is undefined.
10869 : Similarly [expr.static.cast]/2 for references. */
10870 416818783 : if (INDIRECT_TYPE_P (type)
10871 258782085 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10872 258646699 : && COMPLETE_TYPE_P (TREE_TYPE (type))
10873 255431925 : && !integer_zerop (op)
10874 671524925 : && is_properly_derived_from (TREE_TYPE (type),
10875 254706142 : TREE_TYPE (TREE_TYPE (op))))
10876 : {
10877 14503 : tree sop = tree_strip_nop_conversions (op);
10878 14503 : if (cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10879 : NULL, jump_target) == NULL_TREE)
10880 : {
10881 284 : tree dyntype = NULL_TREE;
10882 284 : if (!ctx->quiet && TREE_CODE (sop) == ADDR_EXPR)
10883 : {
10884 44 : sop = TREE_OPERAND (sop, 0);
10885 44 : while (TREE_CODE (sop) == COMPONENT_REF
10886 59 : && DECL_FIELD_IS_BASE (TREE_OPERAND (sop, 1)))
10887 15 : sop = TREE_OPERAND (sop, 0);
10888 44 : dyntype = strip_array_types (TREE_TYPE (sop));
10889 44 : if (same_type_p (dyntype, TREE_TYPE (TREE_TYPE (op))))
10890 261 : dyntype = NULL_TREE;
10891 : }
10892 284 : if (!ctx->quiet)
10893 : {
10894 53 : if (dyntype)
10895 23 : error_at (loc, "%qT operand (of dynamic type %qT) is "
10896 : "not a base class subobject of a %qT object",
10897 23 : TREE_TYPE (TREE_TYPE (op)), dyntype,
10898 23 : TREE_TYPE (type));
10899 : else
10900 30 : error_at (loc, "%qT operand is not a base class "
10901 : "subobject of a %qT object",
10902 30 : TREE_TYPE (TREE_TYPE (op)), TREE_TYPE (type));
10903 : }
10904 284 : *non_constant_p = true;
10905 284 : return t;
10906 : }
10907 : }
10908 :
10909 416818499 : if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
10910 : {
10911 1064 : op = cplus_expand_constant (op);
10912 1064 : if (TREE_CODE (op) == PTRMEM_CST)
10913 : {
10914 21 : if (!ctx->quiet)
10915 3 : error_at (loc, "%qE is not a constant expression when the "
10916 : "class %qT is still incomplete", op,
10917 3 : PTRMEM_CST_CLASS (op));
10918 21 : *non_constant_p = true;
10919 21 : return t;
10920 : }
10921 : }
10922 :
10923 416818478 : if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
10924 : {
10925 657 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
10926 657 : && !can_convert_qual (type, op))
10927 6 : op = cplus_expand_constant (op);
10928 657 : return cp_fold_convert (type, op);
10929 : }
10930 :
10931 416817821 : if (INDIRECT_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
10932 : {
10933 837520 : if (integer_zerop (op))
10934 : {
10935 780416 : if (TYPE_REF_P (type))
10936 : {
10937 36 : if (!ctx->quiet)
10938 4 : error_at (loc, "dereferencing a null pointer");
10939 36 : *non_constant_p = true;
10940 36 : return t;
10941 : }
10942 : }
10943 57104 : else if (TYPE_PTR_P (type)
10944 57104 : && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
10945 : /* INTEGER_CST with pointer-to-method type is only used
10946 : for a virtual method in a pointer to member function.
10947 : Don't reject those. */
10948 : ;
10949 : else
10950 : {
10951 : /* This detects for example:
10952 : reinterpret_cast<void*>(sizeof 0)
10953 : */
10954 57101 : if (!ctx->quiet)
10955 6 : error_at (loc, "%<reinterpret_cast<%T>(%E)%> is not "
10956 : "a constant expression",
10957 : type, op);
10958 57101 : *non_constant_p = true;
10959 57101 : return t;
10960 : }
10961 : }
10962 :
10963 416760684 : if (INDIRECT_TYPE_P (type)
10964 258724664 : && TREE_CODE (op) == NOP_EXPR
10965 124094722 : && TREE_TYPE (op) == ptr_type_node
10966 519879 : && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR
10967 516792 : && VAR_P (TREE_OPERAND (TREE_OPERAND (op, 0), 0))
10968 417164536 : && (DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10969 403852 : 0)) == heap_uninit_identifier
10970 287789 : || DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10971 287789 : 0)) == heap_vec_uninit_identifier))
10972 : {
10973 118268 : tree var = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10974 118268 : tree var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
10975 118268 : tree elt_type = TREE_TYPE (type);
10976 118268 : tree cookie_size = NULL_TREE;
10977 118268 : tree arg_size = NULL_TREE;
10978 118268 : if (TREE_CODE (elt_type) == RECORD_TYPE
10979 118268 : && TYPE_IDENTIFIER (elt_type) == heap_identifier)
10980 : {
10981 9 : tree fld1 = TYPE_FIELDS (elt_type);
10982 9 : tree fld2 = DECL_CHAIN (fld1);
10983 9 : elt_type = TREE_TYPE (TREE_TYPE (fld2));
10984 9 : cookie_size = TYPE_SIZE_UNIT (TREE_TYPE (fld1));
10985 : }
10986 118268 : DECL_NAME (var)
10987 118268 : = (DECL_NAME (var) == heap_uninit_identifier
10988 118268 : ? heap_identifier : heap_vec_identifier);
10989 : /* For zero sized elt_type, try to recover how many outer_nelts
10990 : it should have. */
10991 118268 : if ((cookie_size ? tree_int_cst_equal (var_size, cookie_size)
10992 118259 : : integer_zerop (var_size))
10993 109 : && !int_size_in_bytes (elt_type)
10994 9 : && TREE_CODE (oldop) == CALL_EXPR
10995 118286 : && call_expr_nargs (oldop) >= 1)
10996 9 : if (tree fun = get_function_named_in_call (oldop))
10997 9 : if (cxx_replaceable_global_alloc_fn (fun)
10998 9 : && IDENTIFIER_NEW_OP_P (DECL_NAME (fun)))
10999 9 : arg_size = CALL_EXPR_ARG (oldop, 0);
11000 118268 : tree new_type
11001 118268 : = build_new_constexpr_heap_type (ctx, elt_type, cookie_size,
11002 : var_size, arg_size,
11003 : non_constant_p, overflow_p,
11004 : jump_target);
11005 118268 : if (*jump_target)
11006 : return NULL_TREE;
11007 118268 : TREE_TYPE (var) = new_type;
11008 118268 : TREE_TYPE (TREE_OPERAND (op, 0))
11009 118268 : = build_pointer_type (TREE_TYPE (var));
11010 118268 : if (is_std_allocator_allocate (ctx->call))
11011 : {
11012 : /* [allocator.members]/5: This function starts the lifetime
11013 : of the array object, but not that of any of the array
11014 : elements. */
11015 80724 : tree ctor = build_constructor (new_type, NULL);
11016 80724 : CONSTRUCTOR_NO_CLEARING (ctor) = 1;
11017 80724 : CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
11018 80724 : ctx->global->put_value (var, ctor);
11019 : }
11020 : }
11021 :
11022 : /* This can happen for std::meta::info(^^int) where the cast has no
11023 : meaning. */
11024 416760684 : if (REFLECTION_TYPE_P (type) && REFLECT_EXPR_P (op))
11025 : {
11026 : r = op;
11027 : break;
11028 : }
11029 :
11030 416670272 : if (op == oldop && tcode != UNARY_PLUS_EXPR)
11031 : /* We didn't fold at the top so we could check for ptr-int
11032 : conversion. */
11033 32789283 : return fold (t);
11034 :
11035 383880989 : tree sop;
11036 :
11037 : /* Handle an array's bounds having been deduced after we built
11038 : the wrapping expression. */
11039 383880989 : if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
11040 : r = op;
11041 168012118 : else if (sop = tree_strip_nop_conversions (op),
11042 235622393 : sop != op && (same_type_ignoring_tlq_and_bounds_p
11043 67610275 : (type, TREE_TYPE (sop))))
11044 : r = sop;
11045 138854610 : else if (tcode == UNARY_PLUS_EXPR)
11046 0 : r = fold_convert (TREE_TYPE (t), op);
11047 : else
11048 138854610 : r = fold_build1 (tcode, type, op);
11049 :
11050 : /* Conversion of an out-of-range value has implementation-defined
11051 : behavior; the language considers it different from arithmetic
11052 : overflow, which is undefined. */
11053 383880989 : if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
11054 13293 : TREE_OVERFLOW (r) = false;
11055 : }
11056 : break;
11057 :
11058 9845 : case EXCESS_PRECISION_EXPR:
11059 9845 : {
11060 9845 : tree oldop = TREE_OPERAND (t, 0);
11061 :
11062 9845 : tree op = cxx_eval_constant_expression (ctx, oldop,
11063 : lval,
11064 : non_constant_p, overflow_p,
11065 : jump_target);
11066 9845 : if (*jump_target)
11067 : return NULL_TREE;
11068 9845 : if (*non_constant_p)
11069 : return t;
11070 9839 : r = fold_convert (TREE_TYPE (t), op);
11071 9839 : break;
11072 : }
11073 :
11074 66575 : case EMPTY_CLASS_EXPR:
11075 : /* Handle EMPTY_CLASS_EXPR produced by build_call_a by lowering
11076 : it to an appropriate CONSTRUCTOR. */
11077 66575 : return build_constructor (TREE_TYPE (t), NULL);
11078 :
11079 48465181 : case STATEMENT_LIST:
11080 48465181 : new_ctx = *ctx;
11081 48465181 : new_ctx.ctor = new_ctx.object = NULL_TREE;
11082 48465181 : return cxx_eval_statement_list (&new_ctx, t,
11083 48465177 : non_constant_p, overflow_p, jump_target);
11084 :
11085 33727270 : case BIND_EXPR:
11086 : /* Pre-emptively clear the vars declared by this BIND_EXPR from the value
11087 : map, so that when checking whether they're already destroyed later we
11088 : don't get confused by remnants of previous calls. */
11089 53057496 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
11090 19330226 : ctx->global->clear_value (decl);
11091 33727270 : r = cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
11092 : lval,
11093 : non_constant_p, overflow_p,
11094 : jump_target);
11095 53057492 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
11096 19330224 : destroy_value_checked (ctx, decl, non_constant_p);
11097 : break;
11098 :
11099 8849887 : case PREINCREMENT_EXPR:
11100 8849887 : case POSTINCREMENT_EXPR:
11101 8849887 : case PREDECREMENT_EXPR:
11102 8849887 : case POSTDECREMENT_EXPR:
11103 8849887 : return cxx_eval_increment_expression (ctx, t,
11104 : lval, non_constant_p, overflow_p,
11105 8849887 : jump_target);
11106 :
11107 2182 : case THROW_EXPR:
11108 2182 : if (cxx_dialect >= cxx26)
11109 1855 : return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
11110 : non_constant_p, overflow_p,
11111 1855 : jump_target);
11112 : /* FALLTHROUGH */
11113 335 : case LAMBDA_EXPR:
11114 335 : case NEW_EXPR:
11115 335 : case VEC_NEW_EXPR:
11116 335 : case DELETE_EXPR:
11117 335 : case VEC_DELETE_EXPR:
11118 335 : case MODOP_EXPR:
11119 : /* GCC internal stuff. */
11120 335 : case VA_ARG_EXPR:
11121 335 : case BASELINK:
11122 335 : case OFFSET_REF:
11123 335 : if (!ctx->quiet)
11124 86 : error_at (loc, "expression %qE is not a constant expression", t);
11125 335 : *non_constant_p = true;
11126 335 : break;
11127 :
11128 407839 : case OBJ_TYPE_REF:
11129 : /* Virtual function lookup. We don't need to do anything fancy. */
11130 407839 : return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t),
11131 : lval, non_constant_p, overflow_p,
11132 407839 : jump_target);
11133 :
11134 16142 : case PLACEHOLDER_EXPR:
11135 : /* Use of the value or address of the current object. */
11136 16142 : if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
11137 : {
11138 15899 : if (TREE_CODE (ctor) == CONSTRUCTOR)
11139 : return ctor;
11140 : else
11141 15597 : return cxx_eval_constant_expression (ctx, ctor, lval,
11142 : non_constant_p, overflow_p,
11143 15597 : jump_target);
11144 : }
11145 : /* A placeholder without a referent. We can get here when
11146 : checking whether NSDMIs are noexcept, or in massage_init_elt;
11147 : just say it's non-constant for now. */
11148 243 : gcc_assert (ctx->quiet);
11149 243 : *non_constant_p = true;
11150 243 : break;
11151 :
11152 6945 : case EXIT_EXPR:
11153 6945 : {
11154 6945 : tree cond = TREE_OPERAND (t, 0);
11155 6945 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
11156 : non_constant_p, overflow_p,
11157 : jump_target);
11158 6945 : if (*jump_target)
11159 : return NULL_TREE;
11160 6945 : VERIFY_CONSTANT (cond);
11161 6945 : if (integer_nonzerop (cond))
11162 3397 : *jump_target = t;
11163 : }
11164 : break;
11165 :
11166 83 : case GOTO_EXPR:
11167 83 : if (breaks (&TREE_OPERAND (t, 0))
11168 83 : || continues (&TREE_OPERAND (t, 0)))
11169 64 : *jump_target = TREE_OPERAND (t, 0);
11170 : else
11171 : {
11172 19 : if (!ctx->quiet)
11173 1 : error_at (loc, "%<goto%> is not a constant expression");
11174 19 : *non_constant_p = true;
11175 : }
11176 : break;
11177 :
11178 6649851 : case LOOP_EXPR:
11179 6649851 : case DO_STMT:
11180 6649851 : case WHILE_STMT:
11181 6649851 : case FOR_STMT:
11182 6649851 : cxx_eval_loop_expr (ctx, t,
11183 : non_constant_p, overflow_p, jump_target);
11184 6649851 : break;
11185 :
11186 50127 : case SWITCH_EXPR:
11187 50127 : case SWITCH_STMT:
11188 50127 : cxx_eval_switch_expr (ctx, t,
11189 : non_constant_p, overflow_p, jump_target);
11190 50127 : break;
11191 :
11192 215 : case REQUIRES_EXPR:
11193 : /* It's possible to get a requires-expression in a constant
11194 : expression. For example:
11195 :
11196 : template<typename T> concept bool C() {
11197 : return requires (T t) { t; };
11198 : }
11199 :
11200 : template<typename T> requires !C<T>() void f(T);
11201 :
11202 : Normalization leaves f with the associated constraint
11203 : '!requires (T t) { ... }' which is not transformed into
11204 : a constraint. */
11205 215 : if (!processing_template_decl)
11206 215 : return evaluate_requires_expr (t);
11207 : else
11208 0 : *non_constant_p = true;
11209 0 : return t;
11210 :
11211 1395385 : case ANNOTATE_EXPR:
11212 1395385 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
11213 : lval,
11214 : non_constant_p, overflow_p,
11215 : jump_target);
11216 1395385 : break;
11217 :
11218 9366 : case USING_STMT:
11219 9366 : r = void_node;
11220 9366 : break;
11221 :
11222 32 : case ASSERTION_STMT:
11223 32 : case PRECONDITION_STMT:
11224 32 : case POSTCONDITION_STMT:
11225 32 : {
11226 32 : r = void_node;
11227 : /* Only record the first fail, and do not go further is the semantic
11228 : is 'ignore'. */
11229 32 : if (*non_constant_p || ctx->global->contract_statement
11230 64 : || contract_ignored_p (t))
11231 : break;
11232 :
11233 32 : tree cond = CONTRACT_CONDITION (t);
11234 32 : if (!potential_rvalue_constant_expression (cond))
11235 : {
11236 6 : ctx->global->contract_statement = t;
11237 6 : ctx->global->contract_condition_non_const = true;
11238 6 : break;
11239 : }
11240 :
11241 : /* We need to evaluate and stash the result of this here, since whether
11242 : it needs to be reported (and how) depends on whether the containing
11243 : expression is otherwise const. */
11244 26 : bool ctrct_non_const_p = false;
11245 26 : bool ctrct_overflow_p = false;
11246 26 : tree jmp_target = NULL_TREE;
11247 26 : constexpr_ctx new_ctx = *ctx;
11248 26 : new_ctx.quiet = true;
11249 : /* Avoid modification of existing values. */
11250 26 : modifiable_tracker ms (new_ctx.global);
11251 26 : tree eval =
11252 26 : cxx_eval_constant_expression (&new_ctx, cond, vc_prvalue,
11253 : &ctrct_non_const_p,
11254 : &ctrct_overflow_p, &jmp_target);
11255 : /* Not a constant. */
11256 26 : if (ctrct_non_const_p)
11257 : {
11258 0 : ctx->global->contract_statement = t;
11259 0 : ctx->global->contract_condition_non_const = true;
11260 0 : break;
11261 : }
11262 : /* Constant, but check failed. */
11263 26 : if (integer_zerop (eval))
11264 24 : ctx->global->contract_statement = t;
11265 26 : }
11266 26 : break;
11267 :
11268 2780794 : case TEMPLATE_ID_EXPR:
11269 2780794 : {
11270 : /* We can evaluate template-id that refers to a concept only if
11271 : the template arguments are non-dependent. */
11272 2780794 : gcc_assert (concept_check_p (t));
11273 :
11274 2780794 : if (!value_dependent_expression_p (t)
11275 2780794 : && !uid_sensitive_constexpr_evaluation_p ())
11276 2779871 : r = evaluate_concept_check (t);
11277 : else
11278 923 : *non_constant_p = true;
11279 :
11280 : break;
11281 : }
11282 :
11283 51 : case ASM_EXPR:
11284 51 : if (!ctx->quiet)
11285 29 : inline_asm_in_constexpr_error (loc, /*constexpr_fundef_p*/false);
11286 51 : *non_constant_p = true;
11287 51 : return t;
11288 :
11289 4047 : case BIT_CAST_EXPR:
11290 4047 : if (lval)
11291 : {
11292 0 : if (!ctx->quiet)
11293 0 : error_at (EXPR_LOCATION (t),
11294 : "address of a call to %qs is not a constant expression",
11295 : "__builtin_bit_cast");
11296 0 : *non_constant_p = true;
11297 0 : return t;
11298 : }
11299 4047 : r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p, jump_target);
11300 4047 : break;
11301 :
11302 0 : case OMP_PARALLEL:
11303 0 : case OMP_TASK:
11304 0 : case OMP_FOR:
11305 0 : case OMP_SIMD:
11306 0 : case OMP_DISTRIBUTE:
11307 0 : case OMP_TASKLOOP:
11308 0 : case OMP_LOOP:
11309 0 : case OMP_TEAMS:
11310 0 : case OMP_TARGET_DATA:
11311 0 : case OMP_TARGET:
11312 0 : case OMP_SECTIONS:
11313 0 : case OMP_ORDERED:
11314 0 : case OMP_CRITICAL:
11315 0 : case OMP_SINGLE:
11316 0 : case OMP_SCAN:
11317 0 : case OMP_SCOPE:
11318 0 : case OMP_SECTION:
11319 0 : case OMP_STRUCTURED_BLOCK:
11320 0 : case OMP_MASTER:
11321 0 : case OMP_MASKED:
11322 0 : case OMP_TASKGROUP:
11323 0 : case OMP_TARGET_UPDATE:
11324 0 : case OMP_TARGET_ENTER_DATA:
11325 0 : case OMP_TARGET_EXIT_DATA:
11326 0 : case OMP_ATOMIC:
11327 0 : case OMP_ATOMIC_READ:
11328 0 : case OMP_ATOMIC_CAPTURE_OLD:
11329 0 : case OMP_ATOMIC_CAPTURE_NEW:
11330 0 : case OMP_DEPOBJ:
11331 0 : case OACC_PARALLEL:
11332 0 : case OACC_KERNELS:
11333 0 : case OACC_SERIAL:
11334 0 : case OACC_DATA:
11335 0 : case OACC_HOST_DATA:
11336 0 : case OACC_LOOP:
11337 0 : case OACC_CACHE:
11338 0 : case OACC_DECLARE:
11339 0 : case OACC_ENTER_DATA:
11340 0 : case OACC_EXIT_DATA:
11341 0 : case OACC_UPDATE:
11342 0 : if (!ctx->quiet)
11343 0 : error_at (EXPR_LOCATION (t),
11344 : "statement is not a constant expression");
11345 0 : *non_constant_p = true;
11346 0 : break;
11347 :
11348 0 : default:
11349 0 : if (STATEMENT_CODE_P (TREE_CODE (t)))
11350 : {
11351 : /* This function doesn't know how to deal with pre-genericize
11352 : statements; this can only happen with statement-expressions,
11353 : so for now just fail. */
11354 0 : if (!ctx->quiet)
11355 0 : error_at (EXPR_LOCATION (t),
11356 : "statement is not a constant expression");
11357 : }
11358 0 : else if (flag_checking)
11359 0 : internal_error ("unexpected expression %qE of kind %s", t,
11360 : get_tree_code_name (TREE_CODE (t)));
11361 0 : *non_constant_p = true;
11362 0 : break;
11363 : }
11364 :
11365 2070839753 : if (r == error_mark_node)
11366 14728159 : *non_constant_p = true;
11367 :
11368 135973765 : if (r == void_node && lval != vc_discard && !*jump_target
11369 2070857560 : && !VOID_TYPE_P (TREE_TYPE (t)))
11370 : {
11371 : /* For diagnostic quality we should have handled this sooner, where we
11372 : can be more specific about the out-of-lifetime object. But here we
11373 : can still be correct. */
11374 2 : gcc_checking_assert (false);
11375 : if (!ctx->quiet)
11376 : error_at (EXPR_LOCATION (t),
11377 : "%qE accesses an object outside its lifetime", t);
11378 : *non_constant_p = true;
11379 : }
11380 :
11381 2070839751 : if (*non_constant_p)
11382 : return t;
11383 : else
11384 1645805394 : return r;
11385 : }
11386 :
11387 : /* P0859: A function is needed for constant evaluation if it is a constexpr
11388 : function that is named by an expression ([basic.def.odr]) that is
11389 : potentially constant evaluated.
11390 :
11391 : So we need to instantiate any constexpr functions mentioned by the
11392 : expression even if the definition isn't needed for evaluating the
11393 : expression. */
11394 :
11395 : static tree
11396 598290812 : instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
11397 : {
11398 598290812 : if (TREE_CODE (*tp) == FUNCTION_DECL
11399 12291176 : && DECL_DECLARED_CONSTEXPR_P (*tp)
11400 12153203 : && !DECL_INITIAL (*tp)
11401 3133636 : && !trivial_fn_p (*tp)
11402 3133487 : && (DECL_TEMPLOID_INSTANTIATION (*tp) || DECL_DEFAULTED_FN (*tp))
11403 598290812 : && !uid_sensitive_constexpr_evaluation_p ())
11404 : {
11405 3104011 : ++function_depth;
11406 3104011 : if (DECL_TEMPLOID_INSTANTIATION (*tp))
11407 3103979 : instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
11408 : else
11409 32 : synthesize_method (*tp);
11410 3104011 : --function_depth;
11411 : }
11412 595186801 : else if (TREE_CODE (*tp) == CALL_EXPR
11413 583392179 : || TREE_CODE (*tp) == AGGR_INIT_EXPR)
11414 : {
11415 12356413 : if (EXPR_HAS_LOCATION (*tp))
11416 12349484 : input_location = EXPR_LOCATION (*tp);
11417 : }
11418 :
11419 598290812 : if (!EXPR_P (*tp))
11420 342161526 : *walk_subtrees = 0;
11421 :
11422 598290812 : return NULL_TREE;
11423 : }
11424 :
11425 : static void
11426 291978597 : instantiate_constexpr_fns (tree t)
11427 : {
11428 291978597 : location_t loc = input_location;
11429 291978597 : cp_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
11430 291978597 : input_location = loc;
11431 291978597 : }
11432 :
11433 : /* Look for heap variables in the expression *TP. */
11434 :
11435 : static tree
11436 379717 : find_heap_var_refs (tree *tp, int *walk_subtrees, void */*data*/)
11437 : {
11438 379717 : if (VAR_P (*tp)
11439 379717 : && (DECL_NAME (*tp) == heap_uninit_identifier
11440 10006 : || DECL_NAME (*tp) == heap_identifier
11441 3104 : || DECL_NAME (*tp) == heap_vec_uninit_identifier
11442 2347 : || DECL_NAME (*tp) == heap_vec_identifier
11443 583 : || DECL_NAME (*tp) == heap_deleted_identifier))
11444 : return *tp;
11445 :
11446 265267 : if (TYPE_P (*tp))
11447 68 : *walk_subtrees = 0;
11448 : return NULL_TREE;
11449 : }
11450 :
11451 : /* Find immediate function decls in *TP if any. */
11452 :
11453 : static tree
11454 627632458 : find_immediate_fndecl (tree *tp, int *walk_subtrees, void */*data*/)
11455 : {
11456 631733766 : if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (*tp))
11457 : return *tp;
11458 627625846 : if (TREE_CODE (*tp) == PTRMEM_CST
11459 29940 : && TREE_CODE (PTRMEM_CST_MEMBER (*tp)) == FUNCTION_DECL
11460 627654975 : && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (*tp)))
11461 : return PTRMEM_CST_MEMBER (*tp);
11462 627625733 : if (REFLECT_EXPR_P (*tp))
11463 86547 : *walk_subtrees = 0;
11464 : return NULL_TREE;
11465 : }
11466 :
11467 : /* T has TREE_CONSTANT set but has been deemed not a valid C++ constant
11468 : expression. Return a version of T that has TREE_CONSTANT cleared. */
11469 :
11470 : static tree
11471 147718 : mark_non_constant (tree t)
11472 : {
11473 147718 : gcc_checking_assert (TREE_CONSTANT (t));
11474 :
11475 : /* This isn't actually constant, so unset TREE_CONSTANT.
11476 : Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
11477 : it to be set if it is invariant address, even when it is not
11478 : a valid C++ constant expression. Wrap it with a NOP_EXPR
11479 : instead. */
11480 147718 : if (EXPR_P (t) && TREE_CODE (t) != ADDR_EXPR)
11481 145753 : t = copy_node (t);
11482 1965 : else if (TREE_CODE (t) == CONSTRUCTOR)
11483 480 : t = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (t), t);
11484 : else
11485 1485 : t = build_nop (TREE_TYPE (t), t);
11486 147718 : TREE_CONSTANT (t) = false;
11487 147718 : return t;
11488 : }
11489 :
11490 : /* If we have a successful constant evaluation, now check whether there is
11491 : a failed or non-constant contract that would invalidate this. */
11492 :
11493 : static bool
11494 571455003 : check_for_failed_contracts (constexpr_ctx *ctx)
11495 : {
11496 571455003 : constexpr_global_ctx *const global_ctx = ctx->global;
11497 571455003 : if (!flag_contracts || !global_ctx->contract_statement)
11498 : return false;
11499 :
11500 30 : location_t loc = EXPR_LOCATION (global_ctx->contract_statement);
11501 30 : enum diagnostics::kind kind;
11502 30 : bool error = false;
11503 : /* [intro.compliance.general]/2.3.4. */
11504 : /* [basic.contract.eval]/8. */
11505 30 : if (ctx->manifestly_const_eval != mce_true)
11506 : {
11507 : /* When !MCE, silently return not constant. */
11508 : return true;
11509 : }
11510 27 : else if (contract_terminating_p (global_ctx->contract_statement))
11511 : {
11512 : kind = diagnostics::kind::error;
11513 : error = true;
11514 : }
11515 : else
11516 6 : kind = diagnostics::kind::warning;
11517 :
11518 : /* [basic.contract.eval]/7.3 */
11519 27 : if (global_ctx->contract_condition_non_const)
11520 : {
11521 6 : emit_diagnostic (kind, loc, 0, "contract condition is not constant");
11522 6 : return error;
11523 : }
11524 :
11525 : /* Otherwise, the evaluation was const, but determined to be false. */
11526 21 : emit_diagnostic (kind, loc, 0,
11527 : "contract predicate is false in constant expression");
11528 21 : return error;
11529 : }
11530 :
11531 : /* ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
11532 : STRICT has the same sense as for constant_value_1: true if we only allow
11533 : conforming C++ constant expressions, or false if we want a constant value
11534 : even if it doesn't conform.
11535 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
11536 : per P0595 even when ALLOW_NON_CONSTANT is true.
11537 : CONSTEXPR_DTOR is true when evaluating the dtor of a constexpr variable.
11538 : OBJECT must be non-NULL in that case. */
11539 :
11540 : static tree
11541 581596999 : cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
11542 : bool strict = true,
11543 : mce_value manifestly_const_eval = mce_unknown,
11544 : bool constexpr_dtor = false,
11545 : tree object = NULL_TREE)
11546 : {
11547 581596999 : auto_timevar time (TV_CONSTEXPR);
11548 :
11549 581596999 : bool non_constant_p = false;
11550 581596999 : bool overflow_p = false;
11551 :
11552 581596999 : if (BRACE_ENCLOSED_INITIALIZER_P (t))
11553 : {
11554 0 : gcc_checking_assert (allow_non_constant);
11555 : return t;
11556 : }
11557 :
11558 581596999 : constexpr_global_ctx global_ctx;
11559 581596999 : constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
11560 : allow_non_constant, strict,
11561 581596999 : !allow_non_constant ? mce_true : manifestly_const_eval };
11562 :
11563 : /* Turn off -frounding-math for manifestly constant evaluation. */
11564 581596999 : warning_sentinel rm (flag_rounding_math,
11565 581596999 : ctx.manifestly_const_eval == mce_true);
11566 581596999 : tree type = (object
11567 581596999 : ? cv_unqualified (TREE_TYPE (object))
11568 514577417 : : initialized_type (t));
11569 581596999 : tree r = t;
11570 581596999 : bool is_consteval = false;
11571 581596999 : if (VOID_TYPE_P (type))
11572 : {
11573 10133711 : if (!constexpr_dtor)
11574 : {
11575 10133711 : if (cxx_dialect < cxx20)
11576 : return t;
11577 : /* We could have a COMPOUND_EXPR here coming from
11578 : keep_unused_object_arg. */
11579 10122661 : tree x = extract_call_expr (t);
11580 10122661 : if (x == NULL_TREE || x == error_mark_node)
11581 : return t;
11582 : /* Calls to immediate functions returning void need to be
11583 : evaluated. */
11584 10122619 : tree fndecl = cp_get_callee_fndecl_nofold (x);
11585 20245238 : if (fndecl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (fndecl))
11586 : return t;
11587 : else
11588 626 : is_consteval = true;
11589 626 : tree lam;
11590 626 : if (manifestly_const_eval == mce_true
11591 1158 : && LAMBDA_FUNCTION_P (fndecl)
11592 526 : && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fndecl)))
11593 1152 : && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
11594 519 : global_ctx.consteval_block = fndecl;
11595 : }
11596 : }
11597 571463288 : else if (cxx_dialect >= cxx20
11598 562552743 : && (TREE_CODE (t) == CALL_EXPR
11599 483408660 : || TREE_CODE (t) == AGGR_INIT_EXPR
11600 478269338 : || TREE_CODE (t) == TARGET_EXPR))
11601 : {
11602 89766060 : tree x = t;
11603 89766060 : if (TREE_CODE (x) == TARGET_EXPR)
11604 5482655 : x = TARGET_EXPR_INITIAL (x);
11605 89766060 : tree fndecl = cp_get_callee_fndecl_nofold (x);
11606 176742221 : if (fndecl && DECL_IMMEDIATE_FUNCTION_P (fndecl))
11607 : is_consteval = true;
11608 : /* Don't try to evaluate a std::vector constructor taking an integer, it
11609 : will fail in the 'if (heap_var)' block below after doing all the work
11610 : (c++/113835). This will need adjustment if P3554 is accepted. Note
11611 : that evaluation of e.g. the vector default constructor can succeed, so
11612 : we don't shortcut all vector constructors. */
11613 173952322 : if (fndecl && DECL_CONSTRUCTOR_P (fndecl) && allow_non_constant
11614 11577468 : && is_std_class (type, "vector") && call_expr_nargs (x) > 1
11615 89790636 : && TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE)
11616 : return t;
11617 : }
11618 571461861 : if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
11619 : {
11620 : /* In C++14 an NSDMI can participate in aggregate initialization,
11621 : and can refer to the address of the object being initialized, so
11622 : we need to pass in the relevant VAR_DECL if we want to do the
11623 : evaluation in a single pass. The evaluation will dynamically
11624 : update ctx.values for the VAR_DECL. We use the same strategy
11625 : for C++11 constexpr constructors that refer to the object being
11626 : initialized. */
11627 49826929 : if (constexpr_dtor)
11628 : {
11629 202 : gcc_assert (object && VAR_P (object));
11630 202 : gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
11631 202 : gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
11632 202 : if (error_operand_p (DECL_INITIAL (object)))
11633 : return t;
11634 185 : ctx.ctor = unshare_expr (DECL_INITIAL (object));
11635 185 : TREE_READONLY (ctx.ctor) = false;
11636 : /* Temporarily force decl_really_constant_value to return false
11637 : for it, we want to use ctx.ctor for the current value instead. */
11638 185 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = false;
11639 : }
11640 : else
11641 : {
11642 49826727 : ctx.ctor = build_constructor (type, NULL);
11643 49826727 : CONSTRUCTOR_NO_CLEARING (ctx.ctor) = true;
11644 : }
11645 49826912 : if (!object)
11646 : {
11647 22087995 : if (TREE_CODE (t) == CALL_EXPR)
11648 : {
11649 : /* If T is calling a constructor to initialize an object, reframe
11650 : it as an AGGR_INIT_EXPR to avoid trying to modify an object
11651 : from outside the constant evaluation, which will fail even if
11652 : the value is actually constant (is_constant_evaluated3.C). */
11653 10006723 : tree fn = cp_get_callee_fndecl_nofold (t);
11654 20013238 : if (fn && DECL_CONSTRUCTOR_P (fn))
11655 : {
11656 4114020 : object = CALL_EXPR_ARG (t, 0);
11657 4114020 : object = build_fold_indirect_ref (object);
11658 4114020 : r = build_aggr_init_expr (type, r);
11659 : }
11660 : }
11661 12081272 : else if (TREE_CODE (t) == TARGET_EXPR)
11662 5377216 : object = TARGET_EXPR_SLOT (t);
11663 6704056 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
11664 709547 : object = AGGR_INIT_EXPR_SLOT (t);
11665 : }
11666 49826912 : ctx.object = object;
11667 49826912 : if (object)
11668 37939700 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
11669 : (type, TREE_TYPE (object)));
11670 37939700 : if (object && DECL_P (object))
11671 31768601 : global_ctx.put_value (object, ctx.ctor);
11672 49826912 : if (TREE_CODE (r) == TARGET_EXPR)
11673 : /* Avoid creating another CONSTRUCTOR when we expand the
11674 : TARGET_EXPR. */
11675 5519207 : r = TARGET_EXPR_INITIAL (r);
11676 : }
11677 :
11678 : /* uid_sensitive_constexpr_evaluation_value restricts warning-dependent
11679 : constexpr evaluation to avoid unnecessary template instantiation, and is
11680 : always done with mce_unknown. But due to gaps in the restriction logic
11681 : we may still end up taking an evaluation path that in turn requires
11682 : manifestly constant evaluation, and such evaluation must not be
11683 : restricted since it likely has semantic consequences.
11684 : TODO: Remove/replace the mechanism in GCC 17. */
11685 571461844 : auto uids = make_temp_override (uid_sensitive_constexpr_evaluation_value);
11686 571461844 : if (ctx.manifestly_const_eval == mce_true)
11687 291978597 : uid_sensitive_constexpr_evaluation_value = false;
11688 :
11689 571461844 : auto_vec<tree, 16> cleanups;
11690 571461844 : global_ctx.cleanups = &cleanups;
11691 :
11692 571461844 : if (manifestly_const_eval == mce_true)
11693 291978597 : instantiate_constexpr_fns (r);
11694 571461844 : tree jmp_target = NULL_TREE;
11695 571461844 : r = cxx_eval_constant_expression (&ctx, r, vc_prvalue,
11696 : &non_constant_p, &overflow_p,
11697 : &jmp_target);
11698 571460539 : if (throws (&jmp_target) && !non_constant_p)
11699 : {
11700 1394 : if (!ctx.quiet)
11701 392 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
11702 1394 : non_constant_p = true;
11703 1394 : jmp_target = NULL_TREE;
11704 1394 : r = t;
11705 : }
11706 571457751 : else if (!non_constant_p && jmp_target)
11707 : {
11708 24 : non_constant_p = true;
11709 24 : if (!ctx.quiet)
11710 : {
11711 3 : if (breaks (&jmp_target))
11712 3 : error ("%<break%> outside of a loop or %<switch%>");
11713 0 : else if (continues (&jmp_target))
11714 0 : error ("%<continue%> outside of a loop");
11715 0 : else if (returns (&jmp_target))
11716 0 : error ("%<return%> in a statement expression");
11717 : else
11718 0 : gcc_unreachable ();
11719 : }
11720 24 : r = t;
11721 : }
11722 :
11723 : /* If we got a non-simple TARGET_EXPR, the initializer was a sequence
11724 : of statements, and the result ought to be stored in ctx.ctor. */
11725 571459145 : if (r == void_node && !constexpr_dtor && ctx.ctor)
11726 0 : r = ctx.ctor;
11727 :
11728 571459145 : unsigned int i;
11729 571459145 : tree cleanup;
11730 571459145 : jmp_target = NULL_TREE;
11731 : /* Evaluate the cleanups. */
11732 1143020802 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
11733 102512 : if (cleanup == NULL_TREE)
11734 : /* NULL_TREE cleanup is a marker that before it is
11735 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it. */
11736 23 : --i;
11737 : else
11738 102489 : cxx_eval_constant_expression (&ctx, cleanup, vc_discard,
11739 : &non_constant_p, &overflow_p,
11740 : &jmp_target);
11741 571459145 : if (throws (&jmp_target) && !non_constant_p)
11742 : {
11743 0 : if (!ctx.quiet)
11744 0 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
11745 0 : non_constant_p = true;
11746 0 : r = t;
11747 : }
11748 :
11749 : /* Mutable logic is a bit tricky: we want to allow initialization of
11750 : constexpr variables with mutable members, but we can't copy those
11751 : members to another constexpr variable. */
11752 571459145 : if (!non_constant_p
11753 419493951 : && TREE_CODE (r) == CONSTRUCTOR
11754 588500348 : && CONSTRUCTOR_MUTABLE_POISON (r))
11755 : {
11756 93 : if (!allow_non_constant)
11757 6 : error ("%qE is not a constant expression because it refers to "
11758 : "mutable subobjects of %qT", t, type);
11759 93 : non_constant_p = true;
11760 : }
11761 :
11762 419493858 : if (!non_constant_p && cxx_dialect >= cxx20
11763 990953003 : && !global_ctx.heap_vars.is_empty ())
11764 : {
11765 123492 : tree heap_var = cp_walk_tree_without_duplicates (&r, find_heap_var_refs,
11766 : NULL);
11767 123492 : unsigned int i;
11768 123492 : if (heap_var)
11769 : {
11770 114450 : if (!allow_non_constant && !non_constant_p)
11771 : {
11772 17 : auto_diagnostic_group d;
11773 17 : if (DECL_LANG_SPECIFIC (heap_var))
11774 4 : error ("%qE is not a constant expression because it refers to "
11775 : "exception object allocated with "
11776 : "%<__cxa_allocate_exception%>", t);
11777 : else
11778 13 : error ("%qE is not a constant expression because it refers to "
11779 : "a result of %<operator new%>", t);
11780 17 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11781 17 : }
11782 114450 : r = t;
11783 114450 : non_constant_p = true;
11784 : }
11785 320258 : FOR_EACH_VEC_ELT (global_ctx.heap_vars, i, heap_var)
11786 : {
11787 196766 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
11788 : {
11789 115022 : if (!allow_non_constant && !non_constant_p)
11790 : {
11791 16 : auto_diagnostic_group d;
11792 16 : error ("%qE is not a constant expression because allocated "
11793 : "storage has not been deallocated", t);
11794 16 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11795 16 : }
11796 115022 : r = t;
11797 115022 : non_constant_p = true;
11798 : }
11799 : }
11800 : }
11801 :
11802 : /* Check that immediate invocation does not return an expression referencing
11803 : any immediate function decls. */
11804 571459145 : if (!non_constant_p && cxx_dialect >= cxx20)
11805 827324164 : if (tree immediate_fndecl
11806 413662082 : = cp_walk_tree_without_duplicates (&r, find_immediate_fndecl,
11807 : NULL))
11808 : {
11809 6725 : if (!allow_non_constant && !non_constant_p)
11810 : {
11811 78 : if (is_consteval)
11812 36 : error_at (cp_expr_loc_or_input_loc (t),
11813 : "immediate evaluation returns address of immediate "
11814 : "function %qD", immediate_fndecl);
11815 : else
11816 64 : error_at (cp_expr_loc_or_input_loc (t),
11817 : "constant evaluation returns address of immediate "
11818 : "function %qD", immediate_fndecl);
11819 : }
11820 6725 : r = t;
11821 6725 : non_constant_p = true;
11822 : }
11823 :
11824 571459145 : if (!non_constant_p && !constexpr_dtor)
11825 419372436 : verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
11826 :
11827 : /* After verify_constant because reduced_constant_expression_p can unset
11828 : CONSTRUCTOR_NO_CLEARING. */
11829 571459145 : if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
11830 : {
11831 70035 : if (!allow_non_constant)
11832 45 : error ("%qE is not a constant expression because it refers to "
11833 : "an incompletely initialized variable", t);
11834 70035 : TREE_CONSTANT (r) = false;
11835 70035 : non_constant_p = true;
11836 : }
11837 :
11838 571459145 : if (non_constant_p)
11839 : /* If we saw something bad, go back to our argument. The wrapping below is
11840 : only for the cases of TREE_CONSTANT argument or overflow. */
11841 154531646 : r = t;
11842 :
11843 571459145 : if (!non_constant_p && overflow_p)
11844 215 : non_constant_p = true;
11845 :
11846 : /* Unshare the result. */
11847 571459145 : bool should_unshare = true;
11848 571459145 : if (r == t || (TREE_CODE (t) == TARGET_EXPR
11849 1511758 : && TARGET_EXPR_INITIAL (t) == r))
11850 : should_unshare = false;
11851 :
11852 571459145 : if (non_constant_p && !allow_non_constant)
11853 4142 : return error_mark_node;
11854 571455003 : else if (check_for_failed_contracts (&ctx))
11855 : {
11856 24 : if (manifestly_const_eval == mce_true)
11857 : /* If MCE, we gave a hard error and return error_mark_node. */
11858 21 : return error_mark_node;
11859 : else
11860 : {
11861 : /* Otherwise treat it as non-constant so the violation is still
11862 : detectable at run-time. */
11863 3 : gcc_checking_assert (allow_non_constant);
11864 : return t;
11865 : }
11866 : }
11867 571454979 : else if (non_constant_p && TREE_CONSTANT (r))
11868 143220 : r = mark_non_constant (r);
11869 571311759 : else if (non_constant_p)
11870 : return t;
11871 :
11872 417070480 : if (constexpr_dtor)
11873 : {
11874 167 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
11875 167 : return r;
11876 : }
11877 :
11878 : /* Check we are not trying to return the wrong type. */
11879 417070313 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
11880 : {
11881 : /* If so, this is not a constant expression. */
11882 151 : if (!allow_non_constant)
11883 0 : error ("%qE is not a constant expression because it initializes "
11884 0 : "a %qT rather than %qT", t, TREE_TYPE (t), type);
11885 : return t;
11886 : }
11887 :
11888 417070162 : if (should_unshare)
11889 234266382 : r = unshare_expr (r);
11890 :
11891 417070162 : if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
11892 : {
11893 16033740 : r = adjust_temp_type (type, r);
11894 16033740 : if (TREE_CODE (t) == TARGET_EXPR
11895 16033740 : && TARGET_EXPR_INITIAL (t) == r)
11896 : return t;
11897 15076704 : else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR
11898 2530667 : || TREE_CODE (t) == AGGR_INIT_EXPR)
11899 : /* Don't add a TARGET_EXPR if our argument didn't have one. */;
11900 839612 : else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t))
11901 774 : r = get_target_expr (r);
11902 838838 : else if (processing_template_decl)
11903 : /* Don't insert TARGET_EXPR in template trees. */
11904 : return r;
11905 : else
11906 : {
11907 838835 : r = get_target_expr (r, tf_warning_or_error | tf_no_cleanup);
11908 838835 : TREE_CONSTANT (r) = true;
11909 : }
11910 : }
11911 :
11912 416113123 : if (TREE_CODE (t) == TARGET_EXPR
11913 554722 : && TREE_CODE (r) == TARGET_EXPR)
11914 : {
11915 : /* Preserve this flag for potential_constant_expression, and the others
11916 : for good measure. */
11917 554610 : TARGET_EXPR_ELIDING_P (r) = TARGET_EXPR_ELIDING_P (t);
11918 554610 : TARGET_EXPR_IMPLICIT_P (r) = TARGET_EXPR_IMPLICIT_P (t);
11919 554610 : TARGET_EXPR_LIST_INIT_P (r) = TARGET_EXPR_LIST_INIT_P (t);
11920 554610 : TARGET_EXPR_DIRECT_INIT_P (r) = TARGET_EXPR_DIRECT_INIT_P (t);
11921 : }
11922 :
11923 : /* Remember the original location if that wouldn't need a wrapper. */
11924 416113123 : if (location_t loc = EXPR_LOCATION (t))
11925 190399336 : protected_set_expr_location (r, loc);
11926 :
11927 416113123 : return r;
11928 581594300 : }
11929 :
11930 : /* If T represents a constant expression returns its reduced value.
11931 : Otherwise return error_mark_node. */
11932 :
11933 : tree
11934 159785603 : cxx_constant_value (tree t, tree decl /* = NULL_TREE */,
11935 : tsubst_flags_t complain /* = tf_error */)
11936 : {
11937 159785603 : bool sfinae = !(complain & tf_error);
11938 159785603 : tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, mce_true, false, decl);
11939 159785603 : if (sfinae && !TREE_CONSTANT (r))
11940 2975 : r = error_mark_node;
11941 159785603 : return r;
11942 : }
11943 :
11944 : /* Like cxx_constant_value, but used for evaluation of constexpr destructors
11945 : of constexpr variables. The actual initializer of DECL is not modified. */
11946 :
11947 : void
11948 202 : cxx_constant_dtor (tree t, tree decl)
11949 : {
11950 202 : cxx_eval_outermost_constant_expr (t, false, true, mce_true, true, decl);
11951 202 : }
11952 :
11953 : /* Helper routine for fold_simple function. Either return simplified
11954 : expression T, otherwise NULL_TREE.
11955 : In contrast to cp_fully_fold, and to maybe_constant_value, we try to fold
11956 : even if we are within template-declaration. So be careful on call, as in
11957 : such case types can be undefined. */
11958 :
11959 : static tree
11960 171555317 : fold_simple_1 (tree t)
11961 : {
11962 171555317 : tree op1;
11963 171555317 : enum tree_code code = TREE_CODE (t);
11964 :
11965 171555317 : switch (code)
11966 : {
11967 : case INTEGER_CST:
11968 : case REAL_CST:
11969 : case VECTOR_CST:
11970 : case FIXED_CST:
11971 : case COMPLEX_CST:
11972 : return t;
11973 :
11974 1466318 : case SIZEOF_EXPR:
11975 1466318 : return fold_sizeof_expr (t);
11976 :
11977 40678235 : case ABS_EXPR:
11978 40678235 : case ABSU_EXPR:
11979 40678235 : case CONJ_EXPR:
11980 40678235 : case REALPART_EXPR:
11981 40678235 : case IMAGPART_EXPR:
11982 40678235 : case NEGATE_EXPR:
11983 40678235 : case BIT_NOT_EXPR:
11984 40678235 : case TRUTH_NOT_EXPR:
11985 40678235 : case VIEW_CONVERT_EXPR:
11986 40678235 : CASE_CONVERT:
11987 40678235 : case FLOAT_EXPR:
11988 40678235 : case FIX_TRUNC_EXPR:
11989 40678235 : case FIXED_CONVERT_EXPR:
11990 40678235 : case ADDR_SPACE_CONVERT_EXPR:
11991 :
11992 40678235 : op1 = TREE_OPERAND (t, 0);
11993 :
11994 40678235 : t = const_unop (code, TREE_TYPE (t), op1);
11995 40678235 : if (!t)
11996 : return NULL_TREE;
11997 :
11998 6252479 : if (CONVERT_EXPR_CODE_P (code)
11999 6252479 : && TREE_OVERFLOW_P (t) && !TREE_OVERFLOW_P (op1))
12000 0 : TREE_OVERFLOW (t) = false;
12001 : return t;
12002 :
12003 : default:
12004 : return NULL_TREE;
12005 : }
12006 : }
12007 :
12008 : /* If T is a simple constant expression, returns its simplified value.
12009 : Otherwise returns T. In contrast to maybe_constant_value we
12010 : simplify only few operations on constant-expressions, and we don't
12011 : try to simplify constexpressions. */
12012 :
12013 : tree
12014 172369571 : fold_simple (tree t)
12015 : {
12016 172369571 : if (processing_template_decl)
12017 : return t;
12018 :
12019 171555317 : tree r = fold_simple_1 (t);
12020 171555317 : if (r)
12021 120565189 : return r;
12022 :
12023 : return t;
12024 : }
12025 :
12026 : /* Try folding the expression T to a simple constant.
12027 : Returns that constant, otherwise returns T. */
12028 :
12029 : tree
12030 1686655 : fold_to_constant (tree t)
12031 : {
12032 1686655 : if (processing_template_decl)
12033 : return t;
12034 :
12035 1589060 : tree r = fold (t);
12036 1589060 : if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
12037 : return r;
12038 : else
12039 141201 : return t;
12040 : }
12041 :
12042 : /* If T is a constant expression, returns its reduced value.
12043 : Otherwise, if T does not have TREE_CONSTANT set, returns T.
12044 : Otherwise, returns a version of T without TREE_CONSTANT.
12045 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
12046 : as per P0595. */
12047 :
12048 : static GTY((deletable)) hash_map<tree, tree> *cv_cache;
12049 :
12050 : tree
12051 874694302 : maybe_constant_value (tree t, tree decl /* = NULL_TREE */,
12052 : mce_value manifestly_const_eval /* = mce_unknown */)
12053 : {
12054 874694302 : tree orig_t = t;
12055 874694302 : tree r;
12056 :
12057 874694302 : if (EXPR_P (t) && manifestly_const_eval == mce_unknown)
12058 : {
12059 : /* Look up each operand in the cv_cache first to see if we've already
12060 : reduced it, and reuse that result to avoid quadratic behavior if
12061 : we're called when building up a large expression. */
12062 253081586 : int n = cp_tree_operand_length (t);
12063 253081586 : tree *ops = XALLOCAVEC (tree, n);
12064 253081586 : bool rebuild = false;
12065 708344364 : for (int i = 0; i < n; ++i)
12066 : {
12067 455262778 : ops[i] = TREE_OPERAND (t, i);
12068 941285611 : if (tree *cached = hash_map_safe_get (cv_cache, ops[i]))
12069 31476212 : if (*cached != ops[i])
12070 : {
12071 9836998 : ops[i] = *cached;
12072 9836998 : rebuild = true;
12073 : }
12074 : }
12075 253081586 : if (rebuild)
12076 : {
12077 8258708 : t = copy_node (t);
12078 26901215 : for (int i = 0; i < n; ++i)
12079 18642507 : TREE_OPERAND (t, i) = ops[i];
12080 : }
12081 : }
12082 :
12083 874694302 : if (!is_nondependent_constant_expression (t))
12084 : {
12085 0 : if (TREE_OVERFLOW_P (t)
12086 129386627 : || (!processing_template_decl && TREE_CONSTANT (t)))
12087 4498 : t = mark_non_constant (t);
12088 129386627 : return t;
12089 : }
12090 745307675 : else if (CONSTANT_CLASS_P (t))
12091 : /* No caching or evaluation needed. */
12092 : return t;
12093 :
12094 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
12095 : but at least try folding it to a simple constant. */
12096 340976527 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
12097 512292 : return fold_to_constant (t);
12098 :
12099 323817567 : if (manifestly_const_eval != mce_unknown)
12100 : /* TODO: Extend the cache to be mce_value aware. And if we have a
12101 : previously cached mce_unknown result that's TREE_CONSTANT, it means
12102 : the reduced value is independent of mce_value and so we should
12103 : be able to reuse it in the mce_true/false case. */
12104 174839827 : return cxx_eval_outermost_constant_expr (t, true, true,
12105 174837128 : manifestly_const_eval, false, decl);
12106 :
12107 165624408 : if (cv_cache == NULL)
12108 151756 : cv_cache = hash_map<tree, tree>::create_ggc (101);
12109 165624408 : if (tree *cached = cv_cache->get (t))
12110 : {
12111 13483810 : r = *cached;
12112 13483810 : if (r != t)
12113 : {
12114 : /* Clear processing_template_decl for sake of break_out_target_exprs;
12115 : entries in the cv_cache are non-templated. */
12116 4544984 : processing_template_decl_sentinel ptds;
12117 :
12118 4544984 : r = break_out_target_exprs (r, /*clear_loc*/true);
12119 4544984 : protected_set_expr_location (r, EXPR_LOCATION (t));
12120 4544984 : }
12121 13483810 : return r;
12122 : }
12123 :
12124 152140598 : uid_sensitive_constexpr_evaluation_checker c;
12125 152140598 : r = cxx_eval_outermost_constant_expr (t, true, true,
12126 : manifestly_const_eval, false, decl);
12127 152140598 : gcc_checking_assert (r == t
12128 : || CONVERT_EXPR_P (t)
12129 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
12130 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
12131 : || !cp_tree_equal (r, t));
12132 152140598 : if (!c.evaluation_restricted_p ())
12133 151897071 : cv_cache->put (orig_t, r);
12134 : return r;
12135 : }
12136 :
12137 : /* Dispose of the whole CV_CACHE. */
12138 :
12139 : static void
12140 41438208 : clear_cv_cache (void)
12141 : {
12142 41438208 : if (cv_cache != NULL)
12143 41107844 : cv_cache->empty ();
12144 41438208 : }
12145 :
12146 : /* Dispose of the whole CV_CACHE and FOLD_CACHE. */
12147 :
12148 : void
12149 41438208 : clear_cv_and_fold_caches ()
12150 : {
12151 41438208 : clear_cv_cache ();
12152 41438208 : clear_fold_cache ();
12153 41438208 : }
12154 :
12155 : /* Internal function handling expressions in templates for
12156 : fold_non_dependent_expr and fold_non_dependent_init.
12157 :
12158 : If we're in a template, but T isn't value dependent, simplify
12159 : it. We're supposed to treat:
12160 :
12161 : template <typename T> void f(T[1 + 1]);
12162 : template <typename T> void f(T[2]);
12163 :
12164 : as two declarations of the same function, for example. */
12165 :
12166 : static tree
12167 31920834 : fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
12168 : bool manifestly_const_eval,
12169 : tree object)
12170 : {
12171 31920834 : gcc_assert (processing_template_decl);
12172 :
12173 31920834 : if (is_nondependent_constant_expression (t))
12174 : {
12175 17780104 : processing_template_decl_sentinel s;
12176 17780104 : t = instantiate_non_dependent_expr_internal (t, complain);
12177 :
12178 17780104 : if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t))
12179 : {
12180 0 : if (TREE_OVERFLOW_P (t))
12181 : {
12182 0 : t = build_nop (TREE_TYPE (t), t);
12183 0 : TREE_CONSTANT (t) = false;
12184 : }
12185 : return t;
12186 : }
12187 17780104 : else if (CONSTANT_CLASS_P (t))
12188 : /* No evaluation needed. */
12189 : return t;
12190 :
12191 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
12192 : but at least try folding it to a simple constant. */
12193 4696406 : if (cp_unevaluated_operand && !manifestly_const_eval)
12194 89 : return fold_to_constant (t);
12195 :
12196 4696317 : tree r = cxx_eval_outermost_constant_expr (t, true, true,
12197 : mce_value (manifestly_const_eval),
12198 : false, object);
12199 : /* cp_tree_equal looks through NOPs, so allow them. */
12200 4696317 : gcc_checking_assert (r == t
12201 : || CONVERT_EXPR_P (t)
12202 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
12203 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
12204 : || !cp_tree_equal (r, t));
12205 : return r;
12206 17780104 : }
12207 14140730 : else if (TREE_OVERFLOW_P (t))
12208 : {
12209 0 : t = build_nop (TREE_TYPE (t), t);
12210 0 : TREE_CONSTANT (t) = false;
12211 : }
12212 :
12213 : return t;
12214 : }
12215 :
12216 : /* Like maybe_constant_value but first fully instantiate the argument.
12217 :
12218 : Note: this is equivalent to instantiate_non_dependent_expr (t, complain)
12219 : followed by maybe_constant_value but is more efficient,
12220 : because it calls instantiation_dependent_expression_p and
12221 : potential_constant_expression at most once.
12222 : The manifestly_const_eval argument is passed to maybe_constant_value.
12223 :
12224 : Callers should generally pass their active complain, or if they are in a
12225 : non-template, diagnosing context, they can use the default of
12226 : tf_warning_or_error. Callers that might be within a template context, don't
12227 : have a complain parameter, and aren't going to remember the result for long
12228 : (e.g. null_ptr_cst_p), can pass tf_none and deal with error_mark_node
12229 : appropriately. */
12230 :
12231 : tree
12232 267613811 : fold_non_dependent_expr (tree t,
12233 : tsubst_flags_t complain /* = tf_warning_or_error */,
12234 : bool manifestly_const_eval /* = false */,
12235 : tree object /* = NULL_TREE */)
12236 : {
12237 267613811 : if (t == NULL_TREE)
12238 : return NULL_TREE;
12239 :
12240 266481622 : if (processing_template_decl)
12241 30783349 : return fold_non_dependent_expr_template (t, complain,
12242 30783349 : manifestly_const_eval, object);
12243 :
12244 235698273 : return maybe_constant_value (t, object, mce_value (manifestly_const_eval));
12245 : }
12246 :
12247 : /* Like fold_non_dependent_expr, but if EXPR couldn't be folded to a constant,
12248 : return the original expression. */
12249 :
12250 : tree
12251 2393117 : maybe_fold_non_dependent_expr (tree expr,
12252 : tsubst_flags_t complain/*=tf_warning_or_error*/)
12253 : {
12254 2393117 : tree t = fold_non_dependent_expr (expr, complain);
12255 2393117 : if (t && TREE_CONSTANT (t))
12256 1139807 : return t;
12257 :
12258 : return expr;
12259 : }
12260 :
12261 : /* Like maybe_constant_init but first fully instantiate the argument. */
12262 :
12263 : tree
12264 63355973 : fold_non_dependent_init (tree t,
12265 : tsubst_flags_t complain /*=tf_warning_or_error*/,
12266 : bool manifestly_const_eval /*=false*/,
12267 : tree object /* = NULL_TREE */)
12268 : {
12269 63355973 : if (t == NULL_TREE)
12270 : return NULL_TREE;
12271 :
12272 63355973 : if (processing_template_decl)
12273 : {
12274 1137485 : t = fold_non_dependent_expr_template (t, complain,
12275 : manifestly_const_eval, object);
12276 : /* maybe_constant_init does this stripping, so do it here too. */
12277 1137485 : if (TREE_CODE (t) == TARGET_EXPR)
12278 : {
12279 2107 : tree init = TARGET_EXPR_INITIAL (t);
12280 2107 : if (TREE_CODE (init) == CONSTRUCTOR)
12281 63355973 : t = init;
12282 : }
12283 : return t;
12284 : }
12285 :
12286 62218488 : return maybe_constant_init (t, object, manifestly_const_eval);
12287 : }
12288 :
12289 : /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
12290 : than wrapped in a TARGET_EXPR.
12291 : ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
12292 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
12293 : per P0595 even when ALLOW_NON_CONSTANT is true. */
12294 :
12295 : static tree
12296 176572202 : maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
12297 : mce_value manifestly_const_eval)
12298 : {
12299 176572202 : if (!t)
12300 : return t;
12301 176572202 : if (TREE_CODE (t) == EXPR_STMT)
12302 264 : t = TREE_OPERAND (t, 0);
12303 176572202 : if (TREE_CODE (t) == CONVERT_EXPR
12304 176572202 : && VOID_TYPE_P (TREE_TYPE (t)))
12305 2848 : t = TREE_OPERAND (t, 0);
12306 : /* If the types don't match, the INIT_EXPR is initializing a subobject of
12307 : DECL and losing that information would cause mischief later. */
12308 176572202 : if (TREE_CODE (t) == INIT_EXPR
12309 176572202 : && (!decl
12310 2602 : || same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (decl),
12311 2602 : TREE_TYPE (t))))
12312 1692 : t = TREE_OPERAND (t, 1);
12313 176572202 : if (TREE_CODE (t) == TARGET_EXPR)
12314 7906699 : t = TARGET_EXPR_INITIAL (t);
12315 176572202 : if (!is_nondependent_static_init_expression (t))
12316 : /* Don't try to evaluate it. */;
12317 142722043 : else if (CONSTANT_CLASS_P (t) && TREE_CODE (t) != PTRMEM_CST)
12318 : /* No evaluation needed. PTRMEM_CST needs the immediate fn check. */;
12319 : else
12320 : {
12321 : /* [basic.start.static] allows constant-initialization of variables with
12322 : static or thread storage duration even if it isn't required, but we
12323 : shouldn't bend the rules the same way for automatic variables.
12324 :
12325 : But still enforce the requirements of constexpr/constinit.
12326 : [dcl.constinit] "If a variable declared with the constinit specifier
12327 : has dynamic initialization, the program is ill-formed, even if the
12328 : implementation would perform that initialization as a static
12329 : initialization." */
12330 43525967 : bool is_static = (decl && DECL_P (decl)
12331 103907562 : && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
12332 : bool strict = (!is_static
12333 : || (decl && DECL_P (decl)
12334 3467971 : && (DECL_DECLARED_CONSTEXPR_P (decl)
12335 996646 : || DECL_DECLARED_CONSTINIT_P (decl))));
12336 : if (is_static)
12337 : manifestly_const_eval = mce_true;
12338 :
12339 66172839 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
12340 89285 : return fold_to_constant (t);
12341 :
12342 66083554 : t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
12343 : manifestly_const_eval,
12344 : false, decl);
12345 : }
12346 176482917 : if (TREE_CODE (t) == TARGET_EXPR)
12347 : {
12348 284438 : tree init = TARGET_EXPR_INITIAL (t);
12349 284438 : if (TREE_CODE (init) == CONSTRUCTOR)
12350 176572202 : t = init;
12351 : }
12352 : return t;
12353 : }
12354 :
12355 : /* Wrapper for maybe_constant_init_1 which permits non constants. */
12356 :
12357 : tree
12358 96780442 : maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
12359 : {
12360 96780442 : return maybe_constant_init_1 (t, decl, true, mce_value (manifestly_const_eval));
12361 : }
12362 :
12363 : tree
12364 79789513 : maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval)
12365 : {
12366 79789513 : return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
12367 : }
12368 :
12369 : /* Wrapper for maybe_constant_init_1 which does not permit non constants. */
12370 :
12371 : tree
12372 2247 : cxx_constant_init (tree t, tree decl)
12373 : {
12374 2247 : return maybe_constant_init_1 (t, decl, false, mce_true);
12375 : }
12376 :
12377 : /* Return true if CALL_EXPR T might throw during constant evaluation. */
12378 :
12379 : static bool
12380 232896160 : callee_might_throw (tree t)
12381 : {
12382 232896160 : if (cxx_dialect < cxx26 || !flag_exceptions)
12383 : return false;
12384 36963681 : tree callee = cp_get_callee (t);
12385 36963681 : if (callee == NULL_TREE)
12386 : return false;
12387 36906305 : tree callee_fn = cp_get_fndecl_from_callee (callee, false);
12388 36906305 : return (!flag_enforce_eh_specs
12389 36906305 : || type_dependent_expression_p (callee)
12390 33847656 : || !POINTER_TYPE_P (TREE_TYPE (callee))
12391 68541562 : || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee)))
12392 14841532 : && (callee_fn == NULL_TREE || !TREE_NOTHROW (callee_fn))));
12393 : }
12394 :
12395 : #if 0
12396 : /* FIXME see ADDR_EXPR section in potential_constant_expression_1. */
12397 : /* Return true if the object referred to by REF has automatic or thread
12398 : local storage. */
12399 :
12400 : enum { ck_ok, ck_bad, ck_unknown };
12401 : static int
12402 : check_automatic_or_tls (tree ref)
12403 : {
12404 : machine_mode mode;
12405 : poly_int64 bitsize, bitpos;
12406 : tree offset;
12407 : int volatilep = 0, unsignedp = 0;
12408 : tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
12409 : &mode, &unsignedp, &volatilep, false);
12410 : duration_kind dk;
12411 :
12412 : /* If there isn't a decl in the middle, we don't know the linkage here,
12413 : and this isn't a constant expression anyway. */
12414 : if (!DECL_P (decl))
12415 : return ck_unknown;
12416 : dk = decl_storage_duration (decl);
12417 : return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
12418 : }
12419 : #endif
12420 :
12421 : /* Data structure for passing data from potential_constant_expression_1
12422 : to check_for_return_continue via cp_walk_tree. */
12423 : struct check_for_return_continue_data {
12424 : hash_set<tree> *pset;
12425 : tree continue_stmt;
12426 : tree break_stmt;
12427 : bool could_throw;
12428 : };
12429 :
12430 : /* Helper function for potential_constant_expression_1 SWITCH_STMT handling,
12431 : called through cp_walk_tree. Return the first RETURN_EXPR found, or note
12432 : the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found.
12433 : For C++26 also note presence of possibly throwing calls. */
12434 : static tree
12435 51941647 : check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
12436 : {
12437 51941647 : tree t = *tp, s, b;
12438 51941647 : check_for_return_continue_data *d = (check_for_return_continue_data *) data;
12439 51941647 : switch (TREE_CODE (t))
12440 : {
12441 : case RETURN_EXPR:
12442 : return t;
12443 :
12444 28 : case CONTINUE_STMT:
12445 28 : if (d->continue_stmt == NULL_TREE)
12446 28 : d->continue_stmt = t;
12447 : break;
12448 :
12449 3274 : case BREAK_STMT:
12450 3274 : if (d->break_stmt == NULL_TREE)
12451 1351 : d->break_stmt = t;
12452 : break;
12453 :
12454 : #define RECUR(x) \
12455 : if (tree r = cp_walk_tree (&x, check_for_return_continue, data, \
12456 : d->pset)) \
12457 : return r
12458 :
12459 : /* For loops, walk subtrees manually, so that continue stmts found
12460 : inside of the bodies of the loops are ignored. */
12461 42433 : case DO_STMT:
12462 42433 : *walk_subtrees = 0;
12463 42433 : RECUR (DO_COND (t));
12464 42433 : s = d->continue_stmt;
12465 42433 : b = d->break_stmt;
12466 42433 : RECUR (DO_BODY (t));
12467 42433 : d->continue_stmt = s;
12468 42433 : d->break_stmt = b;
12469 42433 : break;
12470 :
12471 127 : case WHILE_STMT:
12472 127 : *walk_subtrees = 0;
12473 127 : RECUR (WHILE_COND_PREP (t));
12474 127 : RECUR (WHILE_COND (t));
12475 127 : s = d->continue_stmt;
12476 127 : b = d->break_stmt;
12477 127 : RECUR (WHILE_BODY (t));
12478 113 : d->continue_stmt = s;
12479 113 : d->break_stmt = b;
12480 113 : break;
12481 :
12482 414 : case FOR_STMT:
12483 414 : *walk_subtrees = 0;
12484 414 : RECUR (FOR_INIT_STMT (t));
12485 414 : RECUR (FOR_COND_PREP (t));
12486 414 : RECUR (FOR_COND (t));
12487 414 : RECUR (FOR_EXPR (t));
12488 414 : s = d->continue_stmt;
12489 414 : b = d->break_stmt;
12490 414 : RECUR (FOR_BODY (t));
12491 360 : d->continue_stmt = s;
12492 360 : d->break_stmt = b;
12493 360 : break;
12494 :
12495 0 : case RANGE_FOR_STMT:
12496 0 : *walk_subtrees = 0;
12497 0 : RECUR (RANGE_FOR_EXPR (t));
12498 0 : s = d->continue_stmt;
12499 0 : b = d->break_stmt;
12500 0 : RECUR (RANGE_FOR_BODY (t));
12501 0 : d->continue_stmt = s;
12502 0 : d->break_stmt = b;
12503 0 : break;
12504 :
12505 209 : case SWITCH_STMT:
12506 209 : *walk_subtrees = 0;
12507 209 : RECUR (SWITCH_STMT_COND (t));
12508 209 : b = d->break_stmt;
12509 209 : RECUR (SWITCH_STMT_BODY (t));
12510 189 : d->break_stmt = b;
12511 189 : break;
12512 : #undef RECUR
12513 :
12514 : case STATEMENT_LIST:
12515 : case CONSTRUCTOR:
12516 : break;
12517 :
12518 2667242 : case AGGR_INIT_EXPR:
12519 2667242 : case CALL_EXPR:
12520 : /* In C++26 a function could throw. */
12521 2667242 : if (callee_might_throw (t))
12522 128756 : d->could_throw = true;
12523 : break;
12524 :
12525 47808712 : default:
12526 47808712 : if (!EXPR_P (t))
12527 14855977 : *walk_subtrees = 0;
12528 : break;
12529 : }
12530 :
12531 : return NULL_TREE;
12532 : }
12533 :
12534 : /* Return true if T denotes a potentially constant expression. Issue
12535 : diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
12536 : an lvalue-rvalue conversion is implied. If NOW is true, we want to
12537 : consider the expression in the current context, independent of constexpr
12538 : substitution. If FUNDEF_P is true, we're checking a constexpr function body
12539 : and hard errors should not be reported by constexpr_error.
12540 :
12541 : C++0x [expr.const] used to say
12542 :
12543 : 6 An expression is a potential constant expression if it is
12544 : a constant expression where all occurrences of function
12545 : parameters are replaced by arbitrary constant expressions
12546 : of the appropriate type.
12547 :
12548 : 2 A conditional expression is a constant expression unless it
12549 : involves one of the following as a potentially evaluated
12550 : subexpression (3.2), but subexpressions of logical AND (5.14),
12551 : logical OR (5.15), and conditional (5.16) operations that are
12552 : not evaluated are not considered. */
12553 :
12554 : static bool
12555 4997767407 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
12556 : bool fundef_p, tsubst_flags_t flags,
12557 : tree *jump_target)
12558 : {
12559 : #define RECUR(T,RV) \
12560 : potential_constant_expression_1 ((T), (RV), strict, now, fundef_p, flags, \
12561 : jump_target)
12562 :
12563 4997767407 : enum { any = false, rval = true };
12564 4997767407 : int i;
12565 4997767407 : tree tmp;
12566 :
12567 4997767407 : if (t == error_mark_node)
12568 : return false;
12569 4997754865 : if (t == NULL_TREE)
12570 : return true;
12571 4989517667 : location_t loc = cp_expr_loc_or_input_loc (t);
12572 4989517667 : iloc_sentinel ils = loc;
12573 :
12574 4989517667 : if (*jump_target)
12575 : /* If we are jumping, ignore everything. This is simpler than the
12576 : cxx_eval_constant_expression handling because we only need to be
12577 : conservatively correct, and we don't necessarily have a constant value
12578 : available, so we don't bother with switch tracking. */
12579 : return true;
12580 :
12581 2251406 : if (TREE_THIS_VOLATILE (t) && want_rval
12582 1273005 : && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))
12583 4979971023 : && !NULLPTR_TYPE_P (TREE_TYPE (t)))
12584 : {
12585 78550 : if (TREE_CLOBBER_P (t))
12586 : {
12587 : /* We should have caught any clobbers in INIT/MODIFY_EXPR. */
12588 0 : gcc_checking_assert (false);
12589 : return true;
12590 : }
12591 :
12592 78550 : if (flags & tf_error)
12593 25 : constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of "
12594 : "a volatile lvalue %qE with type %qT", t,
12595 25 : TREE_TYPE (t));
12596 : return false;
12597 : }
12598 4979813896 : if (CONSTANT_CLASS_P (t))
12599 : return true;
12600 3630871759 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
12601 3630871759 : && TREE_TYPE (t) == error_mark_node)
12602 : return false;
12603 :
12604 3630871716 : switch (TREE_CODE (t))
12605 : {
12606 : case FUNCTION_DECL:
12607 : case BASELINK:
12608 : case TEMPLATE_DECL:
12609 : case OVERLOAD:
12610 : case TEMPLATE_ID_EXPR:
12611 : case LABEL_DECL:
12612 : case CASE_LABEL_EXPR:
12613 : case PREDICT_EXPR:
12614 : case CONST_DECL:
12615 : case SIZEOF_EXPR:
12616 : case ALIGNOF_EXPR:
12617 : case OFFSETOF_EXPR:
12618 : case NOEXCEPT_EXPR:
12619 : case TEMPLATE_PARM_INDEX:
12620 : case TRAIT_EXPR:
12621 : case IDENTIFIER_NODE:
12622 : case USERDEF_LITERAL:
12623 : /* We can see a FIELD_DECL in a pointer-to-member expression. */
12624 : case FIELD_DECL:
12625 : case RESULT_DECL:
12626 : case USING_DECL:
12627 : case USING_STMT:
12628 : case PLACEHOLDER_EXPR:
12629 : case REQUIRES_EXPR:
12630 : case STATIC_ASSERT:
12631 : case DEBUG_BEGIN_STMT:
12632 : case REFLECT_EXPR:
12633 : return true;
12634 :
12635 25085728 : case RETURN_EXPR:
12636 25085728 : if (!RECUR (TREE_OPERAND (t, 0), any))
12637 : return false;
12638 : /* FALLTHROUGH */
12639 :
12640 24917063 : case BREAK_STMT:
12641 24917063 : case CONTINUE_STMT:
12642 24917063 : *jump_target = t;
12643 24917063 : return true;
12644 :
12645 396904859 : case PARM_DECL:
12646 396904859 : if (now && want_rval)
12647 : {
12648 102040016 : tree type = TREE_TYPE (t);
12649 102040016 : if (dependent_type_p (type)
12650 72821947 : || !COMPLETE_TYPE_P (processing_template_decl
12651 : ? type : complete_type (type))
12652 174861963 : || is_really_empty_class (type, /*ignore_vptr*/false))
12653 : /* An empty class has no data to read. */
12654 : return true;
12655 72821241 : if (flags & tf_error)
12656 24 : constexpr_error (input_location, fundef_p,
12657 : "%qE is not a constant expression", t);
12658 : return false;
12659 : }
12660 : return true;
12661 :
12662 287447686 : case AGGR_INIT_EXPR:
12663 287447686 : case CALL_EXPR:
12664 : /* -- an invocation of a function other than a constexpr function
12665 : or a constexpr constructor. */
12666 287447686 : {
12667 287447686 : tree fun = get_function_named_in_call (t);
12668 287447686 : const int nargs = call_expr_nargs (t);
12669 287447686 : i = 0;
12670 :
12671 287447686 : if (fun == NULL_TREE)
12672 : {
12673 : /* Reset to allow the function to continue past the end
12674 : of the block below. Otherwise return early. */
12675 428766 : bool bail = true;
12676 :
12677 428766 : if (TREE_CODE (t) == CALL_EXPR
12678 428766 : && CALL_EXPR_FN (t) == NULL_TREE)
12679 428766 : switch (CALL_EXPR_IFN (t))
12680 : {
12681 : /* These should be ignored, they are optimized away from
12682 : constexpr functions. */
12683 : case IFN_UBSAN_NULL:
12684 : case IFN_UBSAN_BOUNDS:
12685 : case IFN_UBSAN_VPTR:
12686 : case IFN_FALLTHROUGH:
12687 : case IFN_ASSUME:
12688 : return true;
12689 :
12690 : case IFN_ADD_OVERFLOW:
12691 : case IFN_SUB_OVERFLOW:
12692 : case IFN_MUL_OVERFLOW:
12693 : case IFN_LAUNDER:
12694 : case IFN_VEC_CONVERT:
12695 : case IFN_BSWAP:
12696 : case IFN_BITREVERSE:
12697 : bail = false;
12698 : break;
12699 :
12700 : default:
12701 : break;
12702 : }
12703 :
12704 : if (bail)
12705 : {
12706 : /* fold_call_expr can't do anything with IFN calls. */
12707 172 : if (flags & tf_error)
12708 0 : constexpr_error (loc, fundef_p,
12709 : "call to internal function %qE", t);
12710 : return false;
12711 : }
12712 : }
12713 :
12714 287018920 : if (fun && is_overloaded_fn (fun))
12715 : {
12716 268034034 : if (!RECUR (fun, true))
12717 : return false;
12718 267607171 : fun = get_fns (fun);
12719 :
12720 267607171 : if (TREE_CODE (fun) == FUNCTION_DECL)
12721 : {
12722 249553976 : if (builtin_valid_in_constant_expr_p (fun))
12723 : return true;
12724 247722684 : if (!maybe_constexpr_fn (fun)
12725 : /* Allow any built-in function; if the expansion
12726 : isn't constant, we'll deal with that then. */
12727 55669845 : && !fndecl_built_in_p (fun)
12728 : /* In C++20, replaceable global allocation functions
12729 : are constant expressions. */
12730 37973268 : && (!cxx_replaceable_global_alloc_fn (fun)
12731 996990 : || TREE_CODE (t) != CALL_EXPR
12732 996990 : || (!CALL_FROM_NEW_OR_DELETE_P (t)
12733 363945 : && (current_function_decl == NULL_TREE
12734 363945 : || !is_std_allocator_allocate_deallocate
12735 363945 : (current_function_decl))))
12736 : /* Allow placement new in std::construct_at. */
12737 36983389 : && (!cxx_placement_new_fn (fun)
12738 403944 : || TREE_CODE (t) != CALL_EXPR
12739 403944 : || current_function_decl == NULL_TREE
12740 403932 : || !is_std_construct_at (current_function_decl))
12741 36710421 : && !cxx_dynamic_cast_fn_p (fun)
12742 284429494 : && !cxx_cxa_builtin_fn_p (fun))
12743 : {
12744 : /* In C++26 evaluation of the function arguments might
12745 : throw and in that case it is irrelevant whether
12746 : fun is constexpr or not. */
12747 36653414 : if (cxx_dialect >= cxx26)
12748 8136260 : for (; i < nargs; ++i)
12749 : {
12750 4881239 : tree x = get_nth_callarg (t, i);
12751 4881239 : bool rv = processing_template_decl ? any : rval;
12752 4881239 : bool sub_now = false;
12753 4881239 : if (!potential_constant_expression_1 (x, rv, strict,
12754 : sub_now,
12755 : fundef_p,
12756 : flags,
12757 : jump_target))
12758 : return false;
12759 4591263 : if (throws (jump_target))
12760 : return true;
12761 : }
12762 36333987 : if ((flags & tf_error)
12763 36333987 : && constexpr_error (loc, fundef_p,
12764 : "call to non-%<constexpr%> "
12765 : "function %qD", fun))
12766 272 : explain_invalid_constexpr_fn (fun);
12767 : return false;
12768 : }
12769 : }
12770 :
12771 229122465 : fun = OVL_FIRST (fun);
12772 : /* Skip initial arguments to base constructors. */
12773 229122465 : if (DECL_BASE_CONSTRUCTOR_P (fun))
12774 4198900 : i = num_artificial_parms_for (fun);
12775 : }
12776 18984886 : else if (fun)
12777 : {
12778 18984886 : if (TREE_TYPE (fun)
12779 18984886 : && FUNCTION_POINTER_TYPE_P (TREE_TYPE (fun)))
12780 : want_rval = rval;
12781 : else
12782 : want_rval = any;
12783 18984886 : if (RECUR (fun, want_rval))
12784 : /* Might end up being a constant function pointer. But it
12785 : could also be a function object with constexpr op(), so
12786 : we pass 'any' so that the underlying VAR_DECL is deemed
12787 : as potentially-constant even though it wasn't declared
12788 : constexpr. */;
12789 : else
12790 : return false;
12791 : }
12792 550745980 : for (; i < nargs; ++i)
12793 : {
12794 320460678 : tree x = get_nth_callarg (t, i);
12795 : /* In a template, reference arguments haven't been converted to
12796 : REFERENCE_TYPE and we might not even know if the parameter
12797 : is a reference, so accept lvalue constants too. */
12798 320460678 : bool rv = processing_template_decl ? any : rval;
12799 : /* Don't require an immediately constant value, as constexpr
12800 : substitution might not use the value of the argument. */
12801 320460678 : bool sub_now = false;
12802 320460678 : if (!potential_constant_expression_1 (x, rv, strict,
12803 : sub_now, fundef_p, flags,
12804 : jump_target))
12805 : return false;
12806 3252113852 : if (throws (jump_target))
12807 : return true;
12808 : }
12809 : /* In C++26 a function could throw. */
12810 230285302 : if (*jump_target == NULL_TREE && callee_might_throw (t))
12811 11724819 : *jump_target = void_node;
12812 : return true;
12813 : }
12814 :
12815 204876979 : case NON_LVALUE_EXPR:
12816 : /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
12817 : -- an lvalue of integral type that refers to a non-volatile
12818 : const variable or static data member initialized with
12819 : constant expressions, or
12820 :
12821 : -- an lvalue of literal type that refers to non-volatile
12822 : object defined with constexpr, or that refers to a
12823 : sub-object of such an object; */
12824 204876979 : return RECUR (TREE_OPERAND (t, 0), rval);
12825 :
12826 72123 : case EXCESS_PRECISION_EXPR:
12827 72123 : return RECUR (TREE_OPERAND (t, 0), rval);
12828 :
12829 317735093 : case VAR_DECL:
12830 317735093 : if (DECL_HAS_VALUE_EXPR_P (t))
12831 : {
12832 5285963 : if (now && is_normal_capture_proxy (t))
12833 : {
12834 : /* -- in a lambda-expression, a reference to this or to a
12835 : variable with automatic storage duration defined outside that
12836 : lambda-expression, where the reference would be an
12837 : odr-use. */
12838 :
12839 474236 : if (want_rval)
12840 : /* Since we're doing an lvalue-rvalue conversion, this might
12841 : not be an odr-use, so evaluate the variable directly. */
12842 467223 : return RECUR (DECL_CAPTURED_VARIABLE (t), rval);
12843 :
12844 7013 : if (flags & tf_error)
12845 : {
12846 3 : tree cap = DECL_CAPTURED_VARIABLE (t);
12847 3 : auto_diagnostic_group d;
12848 3 : if (constexpr_error (input_location, fundef_p,
12849 : "lambda capture of %qE is not a "
12850 : "constant expression", cap)
12851 3 : && decl_constant_var_p (cap))
12852 3 : inform (input_location, "because it is used as a glvalue");
12853 3 : }
12854 : return false;
12855 : }
12856 4811727 : tree ve = DECL_VALUE_EXPR (t);
12857 : /* Treat __PRETTY_FUNCTION__ inside a template function as
12858 : potentially-constant. */
12859 4811727 : if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
12860 : return true;
12861 4811722 : if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
12862 2736 : return RECUR (TREE_VEC_ELT (ve, 0), rval);
12863 4808986 : return RECUR (ve, rval);
12864 : }
12865 312449130 : if (want_rval
12866 220943297 : && (now || !var_in_maybe_constexpr_fn (t))
12867 201462287 : && !type_dependent_expression_p (t)
12868 169390879 : && !decl_maybe_constant_var_p (t)
12869 55317850 : && !is_local_temp (t)
12870 54738554 : && (strict
12871 4128278 : || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
12872 1640178 : || (DECL_INITIAL (t)
12873 1169447 : && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)))
12874 54228614 : && COMPLETE_TYPE_P (TREE_TYPE (t))
12875 366677590 : && !is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
12876 : {
12877 54223612 : if (flags & tf_error)
12878 175 : non_const_var_error (loc, t, fundef_p);
12879 : return false;
12880 : }
12881 : return true;
12882 :
12883 451930355 : case NOP_EXPR:
12884 451930355 : if (REINTERPRET_CAST_P (t))
12885 : {
12886 163829 : if (flags & tf_error)
12887 49 : constexpr_error (loc, fundef_p, "%<reinterpret_cast%> is not a "
12888 : "constant expression");
12889 : return false;
12890 : }
12891 : /* FALLTHRU */
12892 909902146 : case CONVERT_EXPR:
12893 909902146 : case VIEW_CONVERT_EXPR:
12894 : /* -- a reinterpret_cast. FIXME not implemented, and this rule
12895 : may change to something more specific to type-punning (DR 1312). */
12896 909902146 : {
12897 909902146 : tree from = TREE_OPERAND (t, 0);
12898 909902146 : if (location_wrapper_p (t))
12899 373040685 : return (RECUR (from, want_rval));
12900 536861461 : if (INDIRECT_TYPE_P (TREE_TYPE (t)))
12901 : {
12902 305518967 : STRIP_ANY_LOCATION_WRAPPER (from);
12903 305518967 : if (TREE_CODE (from) == INTEGER_CST
12904 305518967 : && !integer_zerop (from))
12905 : {
12906 1647 : if (flags & tf_error)
12907 37 : constexpr_error (loc, fundef_p,
12908 : "%<reinterpret_cast%> from integer to "
12909 : "pointer");
12910 : return false;
12911 : }
12912 : }
12913 : /* convert_to_void used to fold these away to void_node, because they
12914 : are a discarded-value expression. */
12915 536859814 : if (TREE_CODE (t) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (t)))
12916 8822546 : return RECUR (from, /*want_rval=*/false);
12917 528037268 : return RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR);
12918 : }
12919 :
12920 13009 : case ADDRESSOF_EXPR:
12921 : /* This is like ADDR_EXPR, except it won't form pointer-to-member. */
12922 13009 : t = TREE_OPERAND (t, 0);
12923 13009 : goto handle_addr_expr;
12924 :
12925 101082697 : case ADDR_EXPR:
12926 : /* -- a unary operator & that is applied to an lvalue that
12927 : designates an object with thread or automatic storage
12928 : duration; */
12929 101082697 : t = TREE_OPERAND (t, 0);
12930 :
12931 101082697 : if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t))
12932 : /* A pointer-to-member constant. */
12933 : return true;
12934 :
12935 101095440 : handle_addr_expr:
12936 : #if 0
12937 : /* FIXME adjust when issue 1197 is fully resolved. For now don't do
12938 : any checking here, as we might dereference the pointer later. If
12939 : we remove this code, also remove check_automatic_or_tls. */
12940 : i = check_automatic_or_tls (t);
12941 : if (i == ck_ok)
12942 : return true;
12943 : if (i == ck_bad)
12944 : {
12945 : if (flags & tf_error)
12946 : error ("address-of an object %qE with thread local or "
12947 : "automatic storage is not a constant expression", t);
12948 : return false;
12949 : }
12950 : #endif
12951 101095440 : return RECUR (t, any);
12952 :
12953 108203720 : case COMPONENT_REF:
12954 108203720 : case ARROW_EXPR:
12955 108203720 : case OFFSET_REF:
12956 : /* -- a class member access unless its postfix-expression is
12957 : of literal type or of pointer to literal type. */
12958 : /* This test would be redundant, as it follows from the
12959 : postfix-expression being a potential constant expression. */
12960 108203720 : if (type_unknown_p (t))
12961 : return true;
12962 100191566 : if (is_overloaded_fn (t))
12963 : /* In a template, a COMPONENT_REF of a function expresses ob.fn(),
12964 : which uses ob as an lvalue. */
12965 102722302 : want_rval = false;
12966 102722302 : gcc_fallthrough ();
12967 :
12968 102722302 : case REALPART_EXPR:
12969 102722302 : case IMAGPART_EXPR:
12970 102722302 : case BIT_FIELD_REF:
12971 102722302 : return RECUR (TREE_OPERAND (t, 0), want_rval);
12972 :
12973 296626 : case EXPR_PACK_EXPANSION:
12974 296626 : return RECUR (PACK_EXPANSION_PATTERN (t), want_rval);
12975 :
12976 : case PACK_INDEX_EXPR:
12977 : return true;
12978 :
12979 113794160 : case INDIRECT_REF:
12980 113794160 : return RECUR (TREE_OPERAND (t, 0), rval);
12981 :
12982 25759995 : case STATEMENT_LIST:
12983 5090887015 : for (tree stmt : tsi_range (t))
12984 76138383 : if (!RECUR (stmt, any))
12985 4989517667 : return false;
12986 : return true;
12987 :
12988 5192363 : case MODIFY_EXPR:
12989 5192363 : if (cxx_dialect < cxx14)
12990 3893 : goto fail;
12991 5188470 : if (!RECUR (TREE_OPERAND (t, 0), any))
12992 : return false;
12993 : /* Just ignore clobbers. */
12994 4327957 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
12995 : return true;
12996 3844178 : if (!RECUR (TREE_OPERAND (t, 1), rval))
12997 : return false;
12998 : return true;
12999 :
13000 910990 : case MODOP_EXPR:
13001 910990 : if (cxx_dialect < cxx14)
13002 98 : goto fail;
13003 910892 : if (!RECUR (TREE_OPERAND (t, 0), rval))
13004 : return false;
13005 900266 : if (!RECUR (TREE_OPERAND (t, 2), rval))
13006 : return false;
13007 : return true;
13008 :
13009 553902 : case DO_STMT:
13010 553902 : if (!RECUR (DO_COND (t), rval))
13011 : return false;
13012 553902 : if (!RECUR (DO_BODY (t), any))
13013 : return false;
13014 553276 : if (breaks (jump_target) || continues (jump_target))
13015 5 : *jump_target = NULL_TREE;
13016 : return true;
13017 :
13018 456125 : case FOR_STMT:
13019 456125 : if (!RECUR (FOR_INIT_STMT (t), any))
13020 : return false;
13021 456125 : if (!RECUR (FOR_COND_PREP (t), any))
13022 : return false;
13023 456125 : tmp = FOR_COND (t);
13024 456125 : if (!RECUR (tmp, rval))
13025 : return false;
13026 456047 : if (tmp)
13027 : {
13028 407320 : if (!processing_template_decl)
13029 402737 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13030 : /* If we couldn't evaluate the condition, it might not ever be
13031 : true. */
13032 407320 : if (!integer_onep (tmp))
13033 : {
13034 : /* Before returning true, check if the for body can contain
13035 : a return. */
13036 407320 : hash_set<tree> pset;
13037 407320 : check_for_return_continue_data data = { &pset, NULL_TREE,
13038 407320 : NULL_TREE, false };
13039 407320 : if (tree ret_expr
13040 407320 : = cp_walk_tree (&FOR_BODY (t), check_for_return_continue,
13041 : &data, &pset))
13042 141582 : *jump_target = ret_expr;
13043 407320 : if (data.could_throw)
13044 18025 : *jump_target = void_node;
13045 407320 : return true;
13046 407320 : }
13047 : }
13048 48727 : if (!RECUR (FOR_EXPR (t), any))
13049 : return false;
13050 48727 : if (!RECUR (FOR_BODY (t), any))
13051 : return false;
13052 48727 : if (!RECUR (FOR_COND_CLEANUP (t), any))
13053 : return false;
13054 48727 : if (breaks (jump_target) || continues (jump_target))
13055 12 : *jump_target = NULL_TREE;
13056 : return true;
13057 :
13058 484 : case RANGE_FOR_STMT:
13059 484 : if (!RECUR (RANGE_FOR_INIT_STMT (t), any))
13060 : return false;
13061 484 : if (!RECUR (RANGE_FOR_EXPR (t), any))
13062 : return false;
13063 484 : if (!RECUR (RANGE_FOR_BODY (t), any))
13064 : return false;
13065 482 : if (breaks (jump_target) || continues (jump_target))
13066 0 : *jump_target = NULL_TREE;
13067 : return true;
13068 :
13069 169601 : case WHILE_STMT:
13070 169601 : if (!RECUR (WHILE_COND_PREP (t), any))
13071 : return false;
13072 169601 : tmp = WHILE_COND (t);
13073 169601 : if (!RECUR (tmp, rval))
13074 : return false;
13075 169536 : if (!processing_template_decl)
13076 169499 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13077 : /* If we couldn't evaluate the condition, it might not ever be true. */
13078 169536 : if (!integer_onep (tmp))
13079 : {
13080 : /* Before returning true, check if the while body can contain
13081 : a return. */
13082 159318 : hash_set<tree> pset;
13083 159318 : check_for_return_continue_data data = { &pset, NULL_TREE,
13084 159318 : NULL_TREE, false };
13085 159318 : if (tree ret_expr
13086 159318 : = cp_walk_tree (&WHILE_BODY (t), check_for_return_continue,
13087 : &data, &pset))
13088 476 : *jump_target = ret_expr;
13089 159318 : if (data.could_throw)
13090 4633 : *jump_target = void_node;
13091 159318 : return true;
13092 159318 : }
13093 10218 : if (!RECUR (WHILE_BODY (t), any))
13094 : return false;
13095 10207 : if (!RECUR (WHILE_COND_CLEANUP (t), any))
13096 : return false;
13097 10207 : if (breaks (jump_target) || continues (jump_target))
13098 24 : *jump_target = NULL_TREE;
13099 : return true;
13100 :
13101 43236 : case SWITCH_STMT:
13102 43236 : if (!RECUR (SWITCH_STMT_COND (t), rval))
13103 : return false;
13104 : /* FIXME we don't check SWITCH_STMT_BODY currently, because even
13105 : unreachable labels would be checked and it is enough if there is
13106 : a single switch cond value for which it is a valid constant
13107 : expression. We need to check if there are any RETURN_EXPRs
13108 : or CONTINUE_STMTs inside of the body though, as in that case
13109 : we need to set *jump_target. */
13110 : else
13111 : {
13112 43226 : hash_set<tree> pset;
13113 43226 : check_for_return_continue_data data = { &pset, NULL_TREE,
13114 43226 : NULL_TREE, false };
13115 43226 : if (tree ret_expr
13116 43226 : = cp_walk_tree (&SWITCH_STMT_BODY (t), check_for_return_continue,
13117 : &data, &pset))
13118 : /* The switch might return. */
13119 42833 : *jump_target = ret_expr;
13120 393 : else if (data.continue_stmt)
13121 : /* The switch can't return, but might continue. */
13122 3 : *jump_target = data.continue_stmt;
13123 43226 : if (data.could_throw)
13124 1867 : *jump_target = void_node;
13125 43226 : }
13126 43226 : return true;
13127 :
13128 50 : case STMT_EXPR:
13129 50 : return RECUR (STMT_EXPR_STMT (t), rval);
13130 :
13131 629533 : case LAMBDA_EXPR:
13132 629533 : if (cxx_dialect >= cxx17)
13133 : /* In C++17 lambdas can be constexpr, don't give up yet. */
13134 : return true;
13135 477 : else if (flags & tf_error)
13136 0 : constexpr_error (loc, fundef_p, "lambda-expression is not a "
13137 : "constant expression before C++17");
13138 : return false;
13139 :
13140 114412 : case NEW_EXPR:
13141 114412 : case VEC_NEW_EXPR:
13142 114412 : case DELETE_EXPR:
13143 114412 : case VEC_DELETE_EXPR:
13144 114412 : if (cxx_dialect >= cxx20)
13145 : /* In C++20, new-expressions are potentially constant. */
13146 : return true;
13147 1077 : else if (flags & tf_error)
13148 0 : constexpr_error (loc, fundef_p, "new-expression is not a "
13149 : "constant expression before C++20");
13150 : return false;
13151 :
13152 85447 : case DYNAMIC_CAST_EXPR:
13153 85447 : case PSEUDO_DTOR_EXPR:
13154 85447 : case OMP_PARALLEL:
13155 85447 : case OMP_TASK:
13156 85447 : case OMP_FOR:
13157 85447 : case OMP_SIMD:
13158 85447 : case OMP_DISTRIBUTE:
13159 85447 : case OMP_TASKLOOP:
13160 85447 : case OMP_LOOP:
13161 85447 : case OMP_TEAMS:
13162 85447 : case OMP_TARGET_DATA:
13163 85447 : case OMP_TARGET:
13164 85447 : case OMP_SECTIONS:
13165 85447 : case OMP_ORDERED:
13166 85447 : case OMP_CRITICAL:
13167 85447 : case OMP_SINGLE:
13168 85447 : case OMP_SCAN:
13169 85447 : case OMP_SCOPE:
13170 85447 : case OMP_SECTION:
13171 85447 : case OMP_MASTER:
13172 85447 : case OMP_MASKED:
13173 85447 : case OMP_TASKGROUP:
13174 85447 : case OMP_TARGET_UPDATE:
13175 85447 : case OMP_TARGET_ENTER_DATA:
13176 85447 : case OMP_TARGET_EXIT_DATA:
13177 85447 : case OMP_ATOMIC:
13178 85447 : case OMP_ATOMIC_READ:
13179 85447 : case OMP_ATOMIC_CAPTURE_OLD:
13180 85447 : case OMP_ATOMIC_CAPTURE_NEW:
13181 85447 : case OMP_DEPOBJ:
13182 85447 : case OACC_PARALLEL:
13183 85447 : case OACC_KERNELS:
13184 85447 : case OACC_SERIAL:
13185 85447 : case OACC_DATA:
13186 85447 : case OACC_HOST_DATA:
13187 85447 : case OACC_LOOP:
13188 85447 : case OACC_CACHE:
13189 85447 : case OACC_DECLARE:
13190 85447 : case OACC_ENTER_DATA:
13191 85447 : case OACC_EXIT_DATA:
13192 85447 : case OACC_UPDATE:
13193 85447 : case OMP_ARRAY_SECTION:
13194 : /* GCC internal stuff. */
13195 85447 : case VA_ARG_EXPR:
13196 85447 : case TRANSACTION_EXPR:
13197 85447 : case AT_ENCODE_EXPR:
13198 85447 : fail:
13199 85447 : if (flags & tf_error)
13200 23 : constexpr_error (loc, fundef_p, "expression %qE is not a constant "
13201 : "expression", t);
13202 : return false;
13203 :
13204 : case OMP_DECLARE_MAPPER:
13205 : /* This can be used to initialize VAR_DECLs: it's treated as a magic
13206 : constant. */
13207 : return true;
13208 :
13209 27003 : case THROW_EXPR:
13210 27003 : if (cxx_dialect < cxx26)
13211 291 : goto fail;
13212 26712 : return RECUR (TREE_OPERAND (t, 0), rval);
13213 :
13214 531 : case ASM_EXPR:
13215 531 : if (flags & tf_error)
13216 6 : inline_asm_in_constexpr_error (loc, fundef_p);
13217 : return false;
13218 :
13219 545351 : case OBJ_TYPE_REF:
13220 545351 : if (cxx_dialect >= cxx20)
13221 : /* In C++20 virtual calls can be constexpr, don't give up yet. */
13222 : return true;
13223 9122 : else if (flags & tf_error)
13224 0 : constexpr_error (loc, fundef_p, "virtual functions cannot be "
13225 : "%<constexpr%> before C++20");
13226 : return false;
13227 :
13228 6657 : case TYPEID_EXPR:
13229 : /* In C++20, a typeid expression whose operand is of polymorphic
13230 : class type can be constexpr. */
13231 6657 : {
13232 6657 : tree e = TREE_OPERAND (t, 0);
13233 6657 : if (cxx_dialect < cxx20
13234 26 : && strict
13235 26 : && !TYPE_P (e)
13236 19 : && !type_dependent_expression_p (e)
13237 7 : && CLASS_TYPE_P (TREE_TYPE (e))
13238 6662 : && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
13239 : {
13240 4 : if (flags & tf_error)
13241 1 : constexpr_error (loc, fundef_p, "%<typeid%> is not a "
13242 : "constant expression because %qE is "
13243 : "of polymorphic type", e);
13244 : return false;
13245 : }
13246 : return true;
13247 : }
13248 :
13249 31614571 : case POINTER_DIFF_EXPR:
13250 31614571 : case MINUS_EXPR:
13251 31614571 : want_rval = true;
13252 31614571 : goto binary;
13253 :
13254 85874432 : case LT_EXPR:
13255 85874432 : case LE_EXPR:
13256 85874432 : case GT_EXPR:
13257 85874432 : case GE_EXPR:
13258 85874432 : case EQ_EXPR:
13259 85874432 : case NE_EXPR:
13260 85874432 : case SPACESHIP_EXPR:
13261 85874432 : want_rval = true;
13262 85874432 : goto binary;
13263 :
13264 2011896 : case PREINCREMENT_EXPR:
13265 2011896 : case POSTINCREMENT_EXPR:
13266 2011896 : case PREDECREMENT_EXPR:
13267 2011896 : case POSTDECREMENT_EXPR:
13268 2011896 : if (cxx_dialect < cxx14)
13269 9456 : goto fail;
13270 2002440 : goto unary;
13271 :
13272 1292198 : case BIT_NOT_EXPR:
13273 : /* A destructor. */
13274 1292198 : if (TYPE_P (TREE_OPERAND (t, 0)))
13275 : return true;
13276 : /* fall through. */
13277 :
13278 48846415 : case CONJ_EXPR:
13279 48846415 : case SAVE_EXPR:
13280 48846415 : case FIX_TRUNC_EXPR:
13281 48846415 : case FLOAT_EXPR:
13282 48846415 : case NEGATE_EXPR:
13283 48846415 : case ABS_EXPR:
13284 48846415 : case ABSU_EXPR:
13285 48846415 : case TRUTH_NOT_EXPR:
13286 48846415 : case FIXED_CONVERT_EXPR:
13287 48846415 : case UNARY_PLUS_EXPR:
13288 48846415 : case UNARY_LEFT_FOLD_EXPR:
13289 48846415 : case UNARY_RIGHT_FOLD_EXPR:
13290 48846415 : case VEC_DUPLICATE_EXPR:
13291 1292198 : unary:
13292 48846415 : return RECUR (TREE_OPERAND (t, 0), rval);
13293 :
13294 31865516 : case CAST_EXPR:
13295 31865516 : case CONST_CAST_EXPR:
13296 31865516 : case STATIC_CAST_EXPR:
13297 31865516 : case REINTERPRET_CAST_EXPR:
13298 31865516 : case IMPLICIT_CONV_EXPR:
13299 31865516 : if (!cast_valid_in_integral_constant_expression_p (TREE_TYPE (t)))
13300 : /* In C++98, a conversion to non-integral type can't be part of a
13301 : constant expression. */
13302 : {
13303 344 : if (flags & tf_error)
13304 0 : constexpr_error (loc, fundef_p,
13305 : "cast to non-integral type %qT in a constant "
13306 0 : "expression", TREE_TYPE (t));
13307 : return false;
13308 : }
13309 : /* This might be a conversion from a class to a (potentially) literal
13310 : type. Let's consider it potentially constant since the conversion
13311 : might be a constexpr user-defined conversion. */
13312 31865172 : else if (cxx_dialect >= cxx11
13313 31842711 : && (dependent_type_p (TREE_TYPE (t))
13314 11223550 : || !COMPLETE_TYPE_P (TREE_TYPE (t))
13315 11208780 : || literal_type_p (TREE_TYPE (t)))
13316 31804375 : && TREE_OPERAND (t, 0)
13317 63422457 : && (TREE_CODE (t) != CAST_EXPR
13318 23926619 : || !TREE_CHAIN (TREE_OPERAND (t, 0))))
13319 : {
13320 31513904 : tree from = TREE_OPERAND (t, 0);
13321 31513904 : if (TREE_CODE (t) == CAST_EXPR)
13322 23883238 : from = TREE_VALUE (from);
13323 31513904 : tree type = TREE_TYPE (from);
13324 : /* If this is a dependent type, it could end up being a class
13325 : with conversions. */
13326 31513904 : if (type == NULL_TREE || WILDCARD_TYPE_P (type))
13327 : return true;
13328 : /* Or a non-dependent class which has conversions. */
13329 597505 : else if (CLASS_TYPE_P (type)
13330 597505 : && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
13331 : return true;
13332 : }
13333 :
13334 25320133 : return (RECUR (TREE_OPERAND (t, 0),
13335 25320133 : !TYPE_REF_P (TREE_TYPE (t))));
13336 :
13337 14657851 : case BIND_EXPR:
13338 14657851 : return RECUR (BIND_EXPR_BODY (t), want_rval);
13339 :
13340 71720870 : case CLEANUP_POINT_EXPR:
13341 71720870 : case MUST_NOT_THROW_EXPR:
13342 71720870 : case TRY_CATCH_EXPR:
13343 : /* Even for C++26 handle TRY_BLOCK conservatively, if we detect the
13344 : body could throw, even with catch (...) among handlers we'd need
13345 : to analyze them in detail if they couldn't rethrow it. More
13346 : importantly though, throws (jump_target) is just conservative,
13347 : and there could be e.g.
13348 : try
13349 : {
13350 : possibly_throwing_fn (args);
13351 : break;
13352 : }
13353 : catch (...)
13354 : {
13355 : }
13356 : or continue or return instead of break. So, clearing *jump_target
13357 : because we see catch (...) handler might mean we missed break
13358 : etc. */
13359 71720870 : case TRY_BLOCK:
13360 71720870 : case EH_SPEC_BLOCK:
13361 71720870 : case EXPR_STMT:
13362 71720870 : case PAREN_EXPR:
13363 : /* For convenience. */
13364 71720870 : case LOOP_EXPR:
13365 71720870 : case EXIT_EXPR:
13366 71720870 : return RECUR (TREE_OPERAND (t, 0), want_rval);
13367 :
13368 13067763 : case DECL_EXPR:
13369 13067763 : tmp = DECL_EXPR_DECL (t);
13370 8682429 : if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)
13371 19159812 : && (processing_template_decl
13372 5604993 : ? !decl_maybe_constant_var_p (tmp)
13373 5117937 : : !decl_constant_var_p (tmp)))
13374 : {
13375 5038511 : if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
13376 : {
13377 8 : if (flags & tf_error)
13378 3 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
13379 : "%qD defined %<thread_local%> in "
13380 : "%<constexpr%> context", tmp);
13381 : return false;
13382 : }
13383 5038503 : else if (TREE_STATIC (tmp))
13384 : {
13385 148 : if (flags & tf_error)
13386 36 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
13387 : "%qD defined %<static%> in %<constexpr%> "
13388 : "context", tmp);
13389 : return false;
13390 : }
13391 5038355 : else if (!check_for_uninitialized_const_var
13392 5038355 : (tmp, /*constexpr_context_p=*/true, flags))
13393 : return false;
13394 : }
13395 13062662 : if (VAR_P (tmp))
13396 8677328 : return RECUR (DECL_INITIAL (tmp), want_rval);
13397 : return true;
13398 :
13399 44143 : case TRY_FINALLY_EXPR:
13400 44143 : return (RECUR (TREE_OPERAND (t, 0), want_rval)
13401 44143 : && RECUR (TREE_OPERAND (t, 1), any));
13402 :
13403 0 : case EH_ELSE_EXPR:
13404 : /* maybe_apply_function_contracts uses this to check postconditions only
13405 : on normal return. */
13406 0 : return (RECUR (TREE_OPERAND (t, 1), any)
13407 0 : || RECUR (TREE_OPERAND (t, 0), any));
13408 :
13409 24836412 : case SCOPE_REF:
13410 24836412 : return RECUR (TREE_OPERAND (t, 1), want_rval);
13411 :
13412 49969305 : case TARGET_EXPR:
13413 49969305 : if (!TARGET_EXPR_DIRECT_INIT_P (t)
13414 49759132 : && !TARGET_EXPR_ELIDING_P (t)
13415 89969772 : && !literal_type_p (TREE_TYPE (t)))
13416 : {
13417 910201 : if (flags & tf_error)
13418 : {
13419 25 : auto_diagnostic_group d;
13420 25 : if (constexpr_error (loc, fundef_p,
13421 : "temporary of non-literal type %qT in a "
13422 25 : "constant expression", TREE_TYPE (t)))
13423 25 : explain_non_literal_class (TREE_TYPE (t));
13424 25 : }
13425 : return false;
13426 : }
13427 : /* FALLTHRU */
13428 77973570 : case INIT_EXPR:
13429 77973570 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
13430 : return true;
13431 77852260 : return RECUR (TREE_OPERAND (t, 1), rval);
13432 :
13433 40395521 : case CONSTRUCTOR:
13434 40395521 : {
13435 40395521 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
13436 40395521 : constructor_elt *ce;
13437 5266338119 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
13438 237722418 : if (!RECUR (ce->value, want_rval))
13439 : return false;
13440 : return true;
13441 : }
13442 :
13443 21434637 : case TREE_LIST:
13444 21434637 : {
13445 21434637 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
13446 : || DECL_P (TREE_PURPOSE (t)));
13447 21434637 : if (!RECUR (TREE_VALUE (t), want_rval))
13448 : return false;
13449 19212556 : if (TREE_CHAIN (t) == NULL_TREE)
13450 : return true;
13451 55559 : return RECUR (TREE_CHAIN (t), want_rval);
13452 : }
13453 :
13454 15562758 : case TRUNC_DIV_EXPR:
13455 15562758 : case CEIL_DIV_EXPR:
13456 15562758 : case FLOOR_DIV_EXPR:
13457 15562758 : case ROUND_DIV_EXPR:
13458 15562758 : case TRUNC_MOD_EXPR:
13459 15562758 : case CEIL_MOD_EXPR:
13460 15562758 : case ROUND_MOD_EXPR:
13461 15562758 : {
13462 15562758 : tree denom = TREE_OPERAND (t, 1);
13463 15562758 : if (!RECUR (denom, rval))
13464 : return false;
13465 : /* We can't call cxx_eval_outermost_constant_expr on an expression
13466 : that hasn't been through instantiate_non_dependent_expr yet. */
13467 15037544 : if (!processing_template_decl)
13468 7981667 : denom = cxx_eval_outermost_constant_expr (denom, true);
13469 15037544 : if (integer_zerop (denom))
13470 : {
13471 378 : if (flags & tf_error)
13472 38 : constexpr_error (input_location, fundef_p,
13473 : "division by zero is not a constant expression");
13474 : return false;
13475 : }
13476 : else
13477 : {
13478 15037166 : want_rval = true;
13479 15037166 : return RECUR (TREE_OPERAND (t, 0), want_rval);
13480 : }
13481 : }
13482 :
13483 9787178 : case COMPOUND_EXPR:
13484 9787178 : {
13485 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
13486 : COMPOUND_EXPR; don't get confused. */
13487 9787178 : tree op0 = TREE_OPERAND (t, 0);
13488 9787178 : tree op1 = TREE_OPERAND (t, 1);
13489 9787178 : STRIP_NOPS (op1);
13490 9787178 : if (TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
13491 2745406 : return RECUR (op0, want_rval);
13492 : else
13493 7041772 : goto binary;
13494 : }
13495 :
13496 : /* If the first operand is the non-short-circuit constant, look at
13497 : the second operand; otherwise we only care about the first one for
13498 : potentiality. */
13499 19007530 : case TRUTH_AND_EXPR:
13500 19007530 : case TRUTH_ANDIF_EXPR:
13501 19007530 : tmp = boolean_true_node;
13502 19007530 : goto truth;
13503 7704407 : case TRUTH_OR_EXPR:
13504 7704407 : case TRUTH_ORIF_EXPR:
13505 7704407 : tmp = boolean_false_node;
13506 26711937 : truth:
13507 26711937 : {
13508 26711937 : tree op0 = TREE_OPERAND (t, 0);
13509 26711937 : tree op1 = TREE_OPERAND (t, 1);
13510 26711937 : if (!RECUR (op0, rval))
13511 : return false;
13512 18434816 : if (!(flags & tf_error) && RECUR (op1, rval))
13513 : /* When quiet, try to avoid expensive trial evaluation by first
13514 : checking potentiality of the second operand. */
13515 : return true;
13516 1859036 : if (!processing_template_decl)
13517 1454158 : op0 = cxx_eval_outermost_constant_expr (op0, true);
13518 1859036 : if (tree_int_cst_equal (op0, tmp))
13519 9124 : return (flags & tf_error) ? RECUR (op1, rval) : false;
13520 : else
13521 : return true;
13522 : }
13523 :
13524 : case PLUS_EXPR:
13525 : case MULT_EXPR:
13526 : case POINTER_PLUS_EXPR:
13527 : case RDIV_EXPR:
13528 : case EXACT_DIV_EXPR:
13529 : case MIN_EXPR:
13530 : case MAX_EXPR:
13531 : case LSHIFT_EXPR:
13532 : case RSHIFT_EXPR:
13533 : case LROTATE_EXPR:
13534 : case RROTATE_EXPR:
13535 : case BIT_IOR_EXPR:
13536 : case BIT_XOR_EXPR:
13537 : case BIT_AND_EXPR:
13538 : case TRUTH_XOR_EXPR:
13539 : case UNORDERED_EXPR:
13540 : case ORDERED_EXPR:
13541 : case UNLT_EXPR:
13542 : case UNLE_EXPR:
13543 : case UNGT_EXPR:
13544 : case UNGE_EXPR:
13545 : case UNEQ_EXPR:
13546 : case LTGT_EXPR:
13547 : case RANGE_EXPR:
13548 : case COMPLEX_EXPR:
13549 240172675 : want_rval = true;
13550 : /* Fall through. */
13551 252587547 : case ARRAY_REF:
13552 252587547 : case ARRAY_RANGE_REF:
13553 252587547 : case MEMBER_REF:
13554 252587547 : case DOTSTAR_EXPR:
13555 252587547 : case MEM_REF:
13556 252587547 : case BINARY_LEFT_FOLD_EXPR:
13557 252587547 : case BINARY_RIGHT_FOLD_EXPR:
13558 252587547 : binary:
13559 556687654 : for (i = 0; i < 2; ++i)
13560 411931492 : if (!RECUR (TREE_OPERAND (t, i), want_rval))
13561 : return false;
13562 : return true;
13563 :
13564 : case VEC_PERM_EXPR:
13565 121529 : for (i = 0; i < 3; ++i)
13566 120583 : if (!RECUR (TREE_OPERAND (t, i), true))
13567 : return false;
13568 : return true;
13569 :
13570 7654530 : case COND_EXPR:
13571 7654530 : if (COND_EXPR_IS_VEC_DELETE (t) && cxx_dialect < cxx20)
13572 : {
13573 8 : if (flags & tf_error)
13574 2 : constexpr_error (loc, fundef_p, "%<delete[]%> is not a "
13575 : "constant expression");
13576 : return false;
13577 : }
13578 : /* Fall through. */
13579 18441292 : case IF_STMT:
13580 18441292 : case VEC_COND_EXPR:
13581 : /* If the condition is a known constant, we know which of the legs we
13582 : care about; otherwise we only require that the condition and
13583 : either of the legs be potentially constant. */
13584 18441292 : tmp = TREE_OPERAND (t, 0);
13585 18441292 : if (!RECUR (tmp, rval))
13586 : return false;
13587 16114956 : if (!processing_template_decl)
13588 14042837 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13589 : /* potential_constant_expression* isn't told if it is called for
13590 : manifestly_const_eval or not, so for consteval if always
13591 : process both branches as if the condition is not a known
13592 : constant. */
13593 16114956 : if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
13594 : {
13595 16037436 : if (integer_zerop (tmp))
13596 3462615 : return RECUR (TREE_OPERAND (t, 2), want_rval);
13597 12574821 : else if (TREE_CODE (tmp) == INTEGER_CST)
13598 3837466 : return RECUR (TREE_OPERAND (t, 1), want_rval);
13599 : }
13600 8814875 : tmp = *jump_target;
13601 10178935 : for (i = 1; i < 3; ++i)
13602 : {
13603 10028492 : tree this_jump_target = tmp;
13604 10028492 : if (potential_constant_expression_1 (TREE_OPERAND (t, i),
13605 : want_rval, strict, now, fundef_p,
13606 : tf_none, &this_jump_target))
13607 : {
13608 8965334 : if (returns (&this_jump_target) || throws (&this_jump_target))
13609 2487015 : *jump_target = this_jump_target;
13610 6177417 : else if (!returns (jump_target) && !throws (jump_target))
13611 : {
13612 6177417 : if (breaks (&this_jump_target)
13613 6177417 : || continues (&this_jump_target))
13614 45 : *jump_target = this_jump_target;
13615 6177417 : if (i == 1)
13616 : {
13617 : /* If the then branch is potentially constant, but
13618 : does not return, check if the else branch
13619 : couldn't return, break or continue. */
13620 5114917 : hash_set<tree> pset;
13621 5114917 : check_for_return_continue_data data = { &pset, NULL_TREE,
13622 : NULL_TREE,
13623 5114917 : false };
13624 10229834 : if (tree ret_expr
13625 5114917 : = cp_walk_tree (&TREE_OPERAND (t, 2),
13626 : check_for_return_continue, &data,
13627 : &pset))
13628 81055 : *jump_target = ret_expr;
13629 5033862 : else if (*jump_target == NULL_TREE)
13630 : {
13631 5033820 : if (data.continue_stmt)
13632 0 : *jump_target = data.continue_stmt;
13633 5033820 : else if (data.break_stmt)
13634 13 : *jump_target = data.break_stmt;
13635 : }
13636 5114917 : if (data.could_throw)
13637 56327 : *jump_target = void_node;
13638 5114917 : }
13639 : }
13640 8664432 : return true;
13641 : }
13642 : }
13643 150443 : if (flags & tf_error)
13644 : {
13645 3 : if (TREE_CODE (t) == IF_STMT)
13646 3 : constexpr_error (loc, fundef_p, "neither branch of %<if%> is a "
13647 : "constant expression");
13648 : else
13649 0 : constexpr_error (loc, fundef_p, "expression %qE is not a "
13650 : "constant expression", t);
13651 : }
13652 : return false;
13653 :
13654 1750 : case VEC_INIT_EXPR:
13655 1750 : if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
13656 : return true;
13657 869 : if (flags & tf_error)
13658 : {
13659 3 : if (constexpr_error (loc, fundef_p, "non-constant array "
13660 : "initialization"))
13661 2 : diagnose_non_constexpr_vec_init (t);
13662 : }
13663 : return false;
13664 :
13665 : case TYPE_DECL:
13666 : case TAG_DEFN:
13667 : /* We can see these in statement-expressions. */
13668 : return true;
13669 :
13670 1504142 : case CLEANUP_STMT:
13671 1504142 : if (!RECUR (CLEANUP_BODY (t), any))
13672 : return false;
13673 2512312 : if (!CLEANUP_EH_ONLY (t) && !RECUR (CLEANUP_EXPR (t), any))
13674 : return false;
13675 : return true;
13676 :
13677 : case EMPTY_CLASS_EXPR:
13678 : return true;
13679 :
13680 128 : case GOTO_EXPR:
13681 128 : {
13682 128 : tree *target = &TREE_OPERAND (t, 0);
13683 : /* Gotos representing break, continue and cdtor return are OK. */
13684 128 : if (breaks (target) || continues (target) || returns (target))
13685 : {
13686 108 : *jump_target = *target;
13687 108 : return true;
13688 : }
13689 20 : if (TREE_CODE (*target) == LABEL_DECL && DECL_ARTIFICIAL (*target))
13690 : /* The user didn't write this goto, this isn't the problem. */
13691 : return true;
13692 16 : if (flags & tf_error)
13693 3 : constexpr_error (loc, fundef_p, "%<goto%> is not a constant "
13694 : "expression");
13695 : return false;
13696 : }
13697 :
13698 : case ASSERTION_STMT:
13699 : case PRECONDITION_STMT:
13700 : case POSTCONDITION_STMT:
13701 : /* Contracts are not supposed to alter this; we have to check that this
13702 : is not violated at a later time. */
13703 : return true;
13704 :
13705 228 : case LABEL_EXPR:
13706 228 : t = LABEL_EXPR_LABEL (t);
13707 228 : if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
13708 : return true;
13709 25 : else if (flags & tf_error)
13710 5 : constexpr_error (loc, fundef_p, "label definition in %<constexpr%> "
13711 : "function only available with %<-std=c++23%> or "
13712 : "%<-std=gnu++23%>");
13713 : return false;
13714 :
13715 10342 : case ANNOTATE_EXPR:
13716 10342 : return RECUR (TREE_OPERAND (t, 0), rval);
13717 :
13718 189276 : case BIT_CAST_EXPR:
13719 189276 : return RECUR (TREE_OPERAND (t, 0), rval);
13720 :
13721 : /* Coroutine await, yield and return expressions are not. */
13722 768 : case CO_AWAIT_EXPR:
13723 768 : case CO_YIELD_EXPR:
13724 768 : case CO_RETURN_EXPR:
13725 768 : case TEMPLATE_FOR_STMT:
13726 768 : if (flags & tf_error)
13727 3 : constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p,
13728 : "%qE is not a constant expression", t);
13729 : return false;
13730 :
13731 : /* Assume a TU-local entity is not constant, we'll error later when
13732 : instantiating. */
13733 : case TU_LOCAL_ENTITY:
13734 : return false;
13735 :
13736 : /* A splice expression is dependent, but will be constant after
13737 : substitution. */
13738 : case SPLICE_EXPR:
13739 : return true;
13740 :
13741 30 : case NONTYPE_ARGUMENT_PACK:
13742 30 : {
13743 30 : tree args = ARGUMENT_PACK_ARGS (t);
13744 30 : int len = TREE_VEC_LENGTH (args);
13745 90 : for (int i = 0; i < len; ++i)
13746 60 : if (!RECUR (TREE_VEC_ELT (args, i), any))
13747 : return false;
13748 : return true;
13749 : }
13750 :
13751 0 : default:
13752 0 : if (objc_non_constant_expr_p (t))
13753 : return false;
13754 :
13755 0 : sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
13756 0 : gcc_unreachable ();
13757 : return false;
13758 : }
13759 : #undef RECUR
13760 4989517667 : }
13761 :
13762 : bool
13763 1783325047 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
13764 : bool fundef_p, tsubst_flags_t flags)
13765 : {
13766 1783325047 : if (flags & tf_error)
13767 : {
13768 : /* Check potentiality quietly first, as that could be performed more
13769 : efficiently in some cases (currently only for TRUTH_*_EXPR). If
13770 : that fails, replay the check noisily to give errors. */
13771 11315725 : flags &= ~tf_error;
13772 11315725 : if (potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13773 : flags))
13774 : return true;
13775 1103 : flags |= tf_error;
13776 : }
13777 :
13778 1772010425 : tree target = NULL_TREE;
13779 1772010425 : return potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13780 1772010425 : flags, &target);
13781 : }
13782 :
13783 : /* The main entry point to the above. */
13784 :
13785 : bool
13786 450710032 : potential_constant_expression (tree t)
13787 : {
13788 450710032 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13789 : /*now*/false, /*fundef_p*/false,
13790 450710032 : tf_none);
13791 : }
13792 :
13793 : /* As above, but require a constant rvalue. */
13794 :
13795 : bool
13796 35893826 : potential_rvalue_constant_expression (tree t)
13797 : {
13798 35893826 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13799 : /*now*/false, /*fundef_p*/false,
13800 35893826 : tf_none);
13801 : }
13802 :
13803 : /* Like above, but complain about non-constant expressions. */
13804 :
13805 : bool
13806 88 : require_potential_constant_expression (tree t)
13807 : {
13808 88 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13809 : /*now*/false, /*fundef_p*/false,
13810 88 : tf_warning_or_error);
13811 : }
13812 :
13813 : /* Cross product of the above. */
13814 :
13815 : bool
13816 133475 : require_potential_rvalue_constant_expression (tree t)
13817 : {
13818 133475 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13819 : /*now*/false, /*fundef_p*/false,
13820 133475 : tf_warning_or_error);
13821 : }
13822 :
13823 : /* Like require_potential_rvalue_constant_expression, but fundef_p is true. */
13824 :
13825 : bool
13826 296 : require_potential_rvalue_constant_expression_fncheck (tree t)
13827 : {
13828 296 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13829 : /*now*/false, /*fundef_p*/true,
13830 296 : tf_warning_or_error);
13831 : }
13832 :
13833 : /* Like above, but don't consider PARM_DECL a potential_constant_expression. */
13834 :
13835 : bool
13836 1149 : require_rvalue_constant_expression (tree t)
13837 : {
13838 1149 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13839 : /*now*/true, /*fundef_p*/false,
13840 1149 : tf_warning_or_error);
13841 : }
13842 :
13843 : /* Like potential_constant_expression, but don't consider possible constexpr
13844 : substitution of the current function. That is, PARM_DECL qualifies under
13845 : potential_constant_expression, but not here.
13846 :
13847 : This is basically what you can check when any actual constant values might
13848 : be value-dependent. */
13849 :
13850 : bool
13851 939118224 : is_constant_expression (tree t)
13852 : {
13853 939118224 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13854 : /*now*/true, /*fundef_p*/false,
13855 939118224 : tf_none);
13856 : }
13857 :
13858 : /* As above, but expect an rvalue. */
13859 :
13860 : bool
13861 158399313 : is_rvalue_constant_expression (tree t)
13862 : {
13863 158399313 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13864 : /*now*/true, /*fundef_p*/false,
13865 158399313 : tf_none);
13866 : }
13867 :
13868 : /* Like above, but complain about non-constant expressions. */
13869 :
13870 : bool
13871 11180717 : require_constant_expression (tree t)
13872 : {
13873 11180717 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13874 : /*now*/true, /*fundef_p*/false,
13875 11180717 : tf_warning_or_error);
13876 : }
13877 :
13878 : /* Like is_constant_expression, but allow const variables that are not allowed
13879 : under constexpr rules. */
13880 :
13881 : bool
13882 176572202 : is_static_init_expression (tree t)
13883 : {
13884 176572202 : return potential_constant_expression_1 (t, /*want_rval*/false,
13885 : /*strict*/false, /*now*/true,
13886 176572202 : /*fundef_p*/false, tf_none);
13887 : }
13888 :
13889 : /* Returns true if T is a potential constant expression that is not
13890 : instantiation-dependent, and therefore a candidate for constant folding even
13891 : in a template. */
13892 :
13893 : bool
13894 907001135 : is_nondependent_constant_expression (tree t)
13895 : {
13896 907001135 : return (!type_unknown_p (t)
13897 907001085 : && is_constant_expression (t)
13898 1702171640 : && !instantiation_dependent_expression_p (t));
13899 : }
13900 :
13901 : /* Returns true if T is a potential static initializer expression that is not
13902 : instantiation-dependent. */
13903 :
13904 : bool
13905 176572202 : is_nondependent_static_init_expression (tree t)
13906 : {
13907 176572202 : return (!type_unknown_p (t)
13908 176572202 : && is_static_init_expression (t)
13909 319294251 : && !instantiation_dependent_expression_p (t));
13910 : }
13911 :
13912 : /* True iff FN is an implicitly constexpr function. */
13913 :
13914 : bool
13915 466494 : decl_implicit_constexpr_p (tree fn)
13916 : {
13917 466494 : if (!(flag_implicit_constexpr
13918 3 : && TREE_CODE (fn) == FUNCTION_DECL
13919 3 : && DECL_DECLARED_CONSTEXPR_P (fn)))
13920 : return false;
13921 :
13922 3 : if (DECL_CLONED_FUNCTION_P (fn))
13923 0 : fn = DECL_CLONED_FUNCTION (fn);
13924 :
13925 3 : return (DECL_LANG_SPECIFIC (fn)
13926 3 : && DECL_LANG_SPECIFIC (fn)->u.fn.implicit_constexpr);
13927 : }
13928 :
13929 : /* Finalize constexpr processing after parsing. */
13930 :
13931 : void
13932 99779 : fini_constexpr (void)
13933 : {
13934 : /* The contexpr call and fundef copies tables are no longer needed. */
13935 99779 : constexpr_call_table = NULL;
13936 99779 : fundef_copies_table = NULL;
13937 99779 : }
13938 :
13939 : #include "gt-cp-constexpr.h"
|