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 196430166 : is_instantiation_of_constexpr (tree fun)
62 : {
63 272004584 : return ((DECL_TEMPLOID_INSTANTIATION (fun)
64 121353792 : && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
65 291945898 : || (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 195505138 : literal_type_p (tree t)
73 : {
74 197165598 : if (SCALAR_TYPE_P (t)
75 92511830 : || VECTOR_TYPE_P (t)
76 92480177 : || TYPE_REF_P (t)
77 76664455 : || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
78 : return true;
79 73358724 : if (CLASS_TYPE_P (t))
80 : {
81 71698052 : t = complete_type (t);
82 71698052 : gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
83 71698052 : return CLASSTYPE_LITERAL_P (t);
84 : }
85 1660672 : if (TREE_CODE (t) == ARRAY_TYPE)
86 1660460 : 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 341409774 : ensure_literal_type_for_constexpr_object (tree decl)
96 : {
97 341409774 : tree type = TREE_TYPE (decl);
98 341409774 : if (VAR_P (decl)
99 128768096 : && (DECL_DECLARED_CONSTEXPR_P (decl)
100 89873160 : || var_in_constexpr_fn (decl))
101 400080120 : && !processing_template_decl)
102 : {
103 38038402 : tree stype = strip_array_types (type);
104 38038402 : 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 38038396 : else if (!literal_type_p (type))
108 : {
109 24291 : 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 24238 : else if (cxx_dialect < cxx23)
119 : {
120 18446 : 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 18446 : cp_function_chain->invalid_constexpr = true;
131 : }
132 : }
133 38014105 : else if (DECL_DECLARED_CONSTEXPR_P (decl)
134 38014105 : && 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 341409774 : 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 949719032 : constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
201 : const constexpr_fundef *rhs)
202 : {
203 921801319 : 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 910416812 : constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
211 : {
212 910416812 : return DECL_UID (fundef->decl);
213 : }
214 :
215 : /* Return a previously saved definition of function FUN. */
216 :
217 : constexpr_fundef *
218 111254409 : retrieve_constexpr_fundef (tree fun)
219 : {
220 111254409 : if (constexpr_fundef_table == NULL)
221 : return NULL;
222 :
223 111250373 : constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
224 111250373 : 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 32077018 : is_valid_constexpr_fn (tree fun, bool complain)
232 : {
233 32077018 : bool ret = true;
234 :
235 64154036 : if (DECL_INHERITED_CTOR (fun)
236 3728962 : && 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 32077018 : for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
246 64789941 : parm != NULL_TREE; parm = TREE_CHAIN (parm))
247 32712923 : if (!literal_type_p (TREE_TYPE (parm)))
248 : {
249 13260 : ret = false;
250 13260 : 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 53197292 : 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 64154028 : 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 32077014 : else if (!DECL_CONSTRUCTOR_P (fun) && !DECL_DESTRUCTOR_P (fun))
278 : {
279 27666189 : tree rettype = TREE_TYPE (TREE_TYPE (fun));
280 27666189 : if (!literal_type_p (rettype))
281 : {
282 51040 : ret = false;
283 51040 : 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 27666189 : if (cxx_dialect < cxx14
295 32980 : && DECL_IOBJ_MEMBER_FUNCTION_P (fun)
296 27667312 : && !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 4410825 : 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 32077018 : 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 4575 : 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 4575 : auto_vec<tree, 2> fields;
344 9246 : do
345 : {
346 9246 : fields.safe_push (TREE_OPERAND (member, 1));
347 9246 : member = TREE_OPERAND (member, 0);
348 : }
349 9246 : while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
350 18498 : && 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 9246 : while (field = fields.pop(),
357 9246 : ANON_AGGR_TYPE_P (TREE_TYPE (field)))
358 : {
359 4671 : tree ctor;
360 : /* If there is already an outer constructor entry for the anonymous
361 : aggregate FIELD, use it; otherwise, insert one. */
362 4671 : if (vec_safe_is_empty (*vec)
363 198 : || (*vec)->last().index != field)
364 : {
365 4569 : ctor = build_constructor (TREE_TYPE (field), NULL);
366 4569 : CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
367 : }
368 : else
369 102 : ctor = (*vec)->last().value;
370 4671 : 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 4575 : gcc_assert (fields.is_empty());
376 4575 : CONSTRUCTOR_APPEND_ELT (*vec, field, init);
377 :
378 4575 : return true;
379 4575 : }
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 6152443 : build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
389 : {
390 6868668 : tree member, init;
391 6868668 : if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
392 3133230 : t = TREE_OPERAND (t, 0);
393 6868668 : if (TREE_CODE (t) == EXPR_STMT)
394 3132016 : t = TREE_OPERAND (t, 0);
395 6868668 : if (t == error_mark_node)
396 : return false;
397 6868659 : if (TREE_CODE (t) == STATEMENT_LIST)
398 : {
399 1622133 : for (tree stmt : tsi_range (t))
400 910808 : if (! build_data_member_initialization (stmt, vec))
401 6152443 : return false;
402 : return true;
403 : }
404 6157334 : 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 681927 : return build_data_member_initialization (CLEANUP_BODY (t), vec);
412 : }
413 5475407 : if (TREE_CODE (t) == CONVERT_EXPR)
414 3055758 : t = TREE_OPERAND (t, 0);
415 5475407 : if (TREE_CODE (t) == INIT_EXPR)
416 : {
417 2908963 : member = TREE_OPERAND (t, 0);
418 2908963 : init = break_out_target_exprs (TREE_OPERAND (t, 1));
419 : }
420 2566444 : else if (TREE_CODE (t) == CALL_EXPR)
421 : {
422 2087064 : tree fn = get_callee_fndecl (t);
423 4174128 : if (!fn || !DECL_CONSTRUCTOR_P (fn))
424 : /* We're only interested in calls to subobject constructors. */
425 : return true;
426 1672851 : 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 1672851 : init = break_out_target_exprs (t);
431 : }
432 479380 : else if (TREE_CODE (t) == BIND_EXPR)
433 34298 : 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 4581814 : if (INDIRECT_REF_P (member))
438 61951 : member = TREE_OPERAND (member, 0);
439 4581814 : if (TREE_CODE (member) == NOP_EXPR)
440 : {
441 565951 : tree op = member;
442 565951 : STRIP_NOPS (op);
443 565951 : 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 565237 : else if (op == current_class_ptr
453 1130323 : && (same_type_ignoring_top_level_qualifiers_p
454 565086 : (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 487256 : gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
463 : }
464 : }
465 4581814 : if (TREE_CODE (member) == ADDR_EXPR)
466 1169565 : member = TREE_OPERAND (member, 0);
467 4581814 : if (TREE_CODE (member) == COMPONENT_REF)
468 : {
469 3990637 : tree aggr = TREE_OPERAND (member, 0);
470 3990637 : if (TREE_CODE (aggr) == VAR_DECL)
471 : /* Initializing a local variable, don't add anything. */
472 : return true;
473 3990635 : if (TREE_CODE (aggr) != COMPONENT_REF)
474 : /* Normal member initialization. */
475 3986057 : member = TREE_OPERAND (member, 1);
476 4578 : else if (VAR_P (get_base_address (aggr)))
477 : /* Initializing a local variable, don't add anything. */
478 : return true;
479 4575 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
480 : /* Initializing a member of an anonymous union. */
481 4575 : 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 5714391 : if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
491 80 : (*vec)->last().value = init;
492 : else
493 4577154 : 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 3762 : check_constexpr_bind_expr_vars (tree t)
503 : {
504 3762 : gcc_assert (TREE_CODE (t) == BIND_EXPR);
505 :
506 4600 : 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 8607 : check_constexpr_ctor_body_1 (tree last, tree list)
518 : {
519 8607 : 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 3419 : case BIND_EXPR:
532 3419 : if (!check_constexpr_bind_expr_vars (list)
533 3419 : || !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 6110265 : 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 6110265 : if (cxx_dialect >= cxx14)
556 : return true;
557 :
558 15236 : bool ok = true;
559 15236 : if (TREE_CODE (list) == STATEMENT_LIST)
560 : {
561 13848 : tree_stmt_iterator i = tsi_last (list);
562 20996 : for (; !tsi_end_p (i); tsi_prev (&i))
563 : {
564 18838 : tree t = tsi_stmt (i);
565 18838 : if (t == last)
566 : break;
567 7219 : if (!check_constexpr_ctor_body_1 (last, t))
568 : {
569 : ok = false;
570 : break;
571 : }
572 : }
573 : }
574 1388 : else if (list != last
575 1388 : && !check_constexpr_ctor_body_1 (last, list))
576 : ok = false;
577 15236 : 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 3650153 : sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
594 : {
595 3650153 : tree pri = CLASSTYPE_PRIMARY_BINFO (type);
596 3650153 : tree field_type;
597 3650153 : unsigned i;
598 3650153 : constructor_elt *ce;
599 :
600 3650153 : if (pri)
601 90017 : field_type = BINFO_TYPE (pri);
602 3560136 : else if (TYPE_CONTAINS_VPTR_P (type))
603 37907 : 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 169891 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
610 131860 : if (TREE_TYPE (ce->index) == field_type)
611 : break;
612 :
613 150314 : 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 3728091 : build_constexpr_constructor_member_initializers (tree type, tree body)
630 : {
631 3728091 : vec<constructor_elt, va_gc> *vec = NULL;
632 3728091 : bool ok = true;
633 5811019 : while (true)
634 5811019 : switch (TREE_CODE (body))
635 : {
636 2082849 : case MUST_NOT_THROW_EXPR:
637 2082849 : case EH_SPEC_BLOCK:
638 2082849 : case TRY_FINALLY_EXPR: // For C++26 postconditions.
639 2082849 : body = TREE_OPERAND (body, 0);
640 2082849 : break;
641 :
642 79 : case STATEMENT_LIST:
643 2083113 : 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 3728091 : case BIND_EXPR:
652 3728091 : body = BIND_EXPR_BODY (body);
653 3728091 : goto found;
654 :
655 0 : default:
656 0 : gcc_unreachable ();
657 : }
658 3728091 : found:
659 3728091 : 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 3728091 : if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
666 : {
667 2010534 : body = TREE_OPERAND (body, 0);
668 2010534 : if (TREE_CODE (body) == EXPR_STMT)
669 2010498 : body = TREE_OPERAND (body, 0);
670 2010534 : if (TREE_CODE (body) == INIT_EXPR
671 2010534 : && (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 2010534 : ok = build_data_member_initialization (body, &vec);
679 : }
680 1717557 : else if (TREE_CODE (body) == STATEMENT_LIST)
681 : {
682 4937719 : for (tree stmt : tsi_range (body))
683 : {
684 3225632 : ok = build_data_member_initialization (stmt, &vec);
685 3225632 : if (!ok)
686 : break;
687 : }
688 : }
689 5469 : else if (EXPR_P (body))
690 5469 : ok = build_data_member_initialization (body, &vec);
691 : else
692 0 : gcc_assert (errorcount > 0);
693 3728091 : if (ok)
694 : {
695 3728082 : if (vec_safe_length (vec) > 0)
696 : {
697 : /* In a delegating constructor, return the target. */
698 3444526 : constructor_elt *ce = &(*vec)[0];
699 3444526 : if (ce->index == current_class_ptr)
700 : {
701 77929 : body = ce->value;
702 77929 : vec_free (vec);
703 77929 : return body;
704 : }
705 : }
706 3650153 : vec = sort_constexpr_mem_initializers (type, vec);
707 3650153 : 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 569002258 : get_function_named_in_call (tree t)
719 : {
720 569002258 : tree callee = cp_get_callee (t);
721 569002258 : tree fun = cp_get_fndecl_from_callee (callee, /*fold*/false);
722 569002258 : 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 70613 : constexpr_fn_retval (tree body)
732 : {
733 77429 : 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 33034 : case RETURN_EXPR:
755 33034 : 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 6479 : case CLEANUP_POINT_EXPR:
768 6479 : 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 31361908 : massage_constexpr_body (tree fun, tree body)
799 : {
800 62723816 : if (DECL_CONSTRUCTOR_P (fun))
801 3728091 : body = build_constexpr_constructor_member_initializers
802 3728091 : (DECL_CONTEXT (fun), body);
803 27633817 : else if (cxx_dialect < cxx14)
804 : {
805 32849 : if (TREE_CODE (body) == EH_SPEC_BLOCK)
806 1 : body = EH_SPEC_STMTS (body);
807 32849 : if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
808 21455 : body = TREE_OPERAND (body, 0);
809 32849 : body = constexpr_fn_retval (body);
810 : }
811 31361908 : 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 3378999 : cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
819 : {
820 : /* We allow uninitialized bases/fields in C++20. */
821 3378999 : if (cxx_dialect >= cxx20)
822 : return false;
823 :
824 13763 : unsigned nelts = 0;
825 :
826 13763 : if (body)
827 : {
828 13759 : if (TREE_CODE (body) != CONSTRUCTOR)
829 : return false;
830 13706 : nelts = CONSTRUCTOR_NELTS (body);
831 : }
832 13710 : tree field = TYPE_FIELDS (ctype);
833 :
834 13710 : 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 28852 : for (unsigned i = 0; i <= nelts; ++i)
850 : {
851 28852 : tree index = NULL_TREE;
852 28852 : if (i < nelts)
853 : {
854 15252 : index = CONSTRUCTOR_ELT (body, i)->index;
855 : /* Skip vptr adjustment represented with a COMPONENT_REF. */
856 15252 : if (TREE_CODE (index) != FIELD_DECL)
857 627 : continue;
858 : }
859 :
860 498208 : for (; field != index; field = DECL_CHAIN (field))
861 : {
862 469989 : tree ftype;
863 469989 : if (TREE_CODE (field) != FIELD_DECL)
864 469961 : 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 28219 : if (field == NULL_TREE)
906 : break;
907 :
908 14625 : 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 14625 : 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 169405511 : maybe_save_constexpr_fundef (tree fun)
928 : {
929 169405511 : if (processing_template_decl
930 69925056 : || cp_function_chain->invalid_constexpr
931 239312230 : || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
932 138043897 : 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 53445845 : bool implicit = false;
937 53445845 : 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 53445845 : if (!DECL_DECLARED_CONSTEXPR_P (fun) && !implicit)
952 : return;
953 :
954 31417787 : bool complain = !DECL_GENERATED_P (fun) && !implicit;
955 :
956 31417787 : if (!is_valid_constexpr_fn (fun, complain))
957 : return;
958 :
959 31361828 : tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
960 31361828 : 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 31361792 : bool potential = potential_rvalue_constant_expression (massaged);
969 31361792 : if (!potential && complain)
970 264 : require_potential_rvalue_constant_expression_fncheck (massaged);
971 :
972 35089860 : if (DECL_CONSTRUCTOR_P (fun) && potential
973 35085745 : && !DECL_DEFAULTED_FN (fun))
974 : {
975 3378943 : if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
976 : massaged, complain))
977 : potential = false;
978 3378917 : 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 3374055 : massaged = DECL_SAVED_TREE (fun);
983 3374055 : potential = potential_rvalue_constant_expression (massaged);
984 3374055 : if (!potential && complain)
985 20 : require_potential_rvalue_constant_expression_fncheck (massaged);
986 : }
987 : }
988 :
989 31361792 : 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 31361625 : 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 31361614 : constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
1013 31361614 : bool clear_ctx = false;
1014 31361614 : if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
1015 : {
1016 31361614 : clear_ctx = true;
1017 31361614 : DECL_CONTEXT (DECL_RESULT (fun)) = fun;
1018 : }
1019 31361614 : tree saved_fn = current_function_decl;
1020 31361614 : current_function_decl = fun;
1021 31361614 : entry.body = copy_fn (entry.decl, entry.parms, entry.result);
1022 31361614 : current_function_decl = saved_fn;
1023 31361614 : if (clear_ctx)
1024 31361614 : DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
1025 31361614 : 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 61262 : entry.result = error_mark_node;
1030 :
1031 31361614 : 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 31399949 : register_constexpr_fundef (const constexpr_fundef &value)
1039 : {
1040 : /* Create the constexpr function table if necessary. */
1041 31399949 : if (constexpr_fundef_table == NULL)
1042 27967 : constexpr_fundef_table
1043 27967 : = hash_table<constexpr_fundef_hasher>::create_ggc (101);
1044 :
1045 31399949 : constexpr_fundef **slot = constexpr_fundef_table->find_slot
1046 31399949 : (const_cast<constexpr_fundef *> (&value), INSERT);
1047 :
1048 31399949 : gcc_assert (*slot == NULL);
1049 31399949 : *slot = ggc_alloc<constexpr_fundef> ();
1050 31399949 : **slot = value;
1051 31399949 : }
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 65173248 : 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 580835290 : constexpr_global_ctx ()
1238 580835290 : : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
1239 580835290 : consteval_block (NULL_TREE), heap_dealloc_count (0),
1240 580835290 : uncaught_exceptions (0), contract_statement (NULL_TREE),
1241 580835290 : contract_condition_non_const (false), state_dependent (false) {}
1242 :
1243 467417409 : bool is_outside_lifetime (tree t)
1244 : {
1245 467417409 : if (tree *p = values.get (t))
1246 210564124 : if (*p == void_node || *p == void_list_node)
1247 268 : return true;
1248 : return false;
1249 : }
1250 591723983 : tree get_value (tree t)
1251 : {
1252 591723983 : if (tree *p = values.get (t))
1253 310020708 : if (*p != void_node && *p != void_list_node)
1254 301867885 : return *p;
1255 : return NULL_TREE;
1256 : }
1257 5036 : tree *get_raw_value_ptr (tree t)
1258 : {
1259 5036 : return values.get (t);
1260 : }
1261 126066637 : tree *get_value_ptr (tree t, bool initializing)
1262 : {
1263 126066637 : if (modifiable && !modifiable->contains (t))
1264 : return nullptr;
1265 126066620 : if (tree *p = values.get (t))
1266 : {
1267 126057068 : if (*p != void_node && *p != void_list_node)
1268 : return p;
1269 63 : else if (initializing)
1270 : {
1271 21 : *p = NULL_TREE;
1272 21 : return p;
1273 : }
1274 : }
1275 : return nullptr;
1276 : }
1277 303858421 : void put_value (tree t, tree v)
1278 : {
1279 : /* If modifiable is not null, any key that was not previously in the
1280 : map, or that has been destroyed and freed (as indicated by
1281 : void_list_node), is tracked in modifiable. If the object is there,
1282 : or its storage remains (as indicated by void_node), then we don't
1283 : track it as modifiable. */
1284 303858421 : bool already_in_map;
1285 303858421 : tree &slot = values.get_or_insert (t, &already_in_map);
1286 303858421 : bool newval = !already_in_map || slot == void_list_node;
1287 303858421 : slot = v;
1288 303858421 : if (newval && modifiable)
1289 64 : modifiable->add (t);
1290 303858421 : }
1291 243618173 : void destroy_value (tree t, bool past_storage_end = true)
1292 : {
1293 243618173 : if (TREE_CODE (t) == VAR_DECL
1294 243618173 : || TREE_CODE (t) == PARM_DECL
1295 : || TREE_CODE (t) == RESULT_DECL)
1296 243909315 : values.put (t, past_storage_end ? void_list_node : void_node);
1297 : else
1298 9269 : values.remove (t);
1299 243618173 : }
1300 19279988 : void clear_value (tree t)
1301 : {
1302 38559976 : values.remove (t);
1303 : }
1304 : };
1305 :
1306 : /* Helper class for constexpr_global_ctx. In some cases we want to avoid
1307 : side-effects from evaluation of a particular subexpression of a
1308 : constant-expression. In such cases we use modifiable_tracker to prevent
1309 : modification of variables created outside of that subexpression. Keep and
1310 : then restore the original value of global->modifiable so that tracker
1311 : instantiations can nest.
1312 :
1313 : ??? We could change the hash_set to a hash_map, allow and track external
1314 : modifications, and roll them back in the destructor. It's not clear to me
1315 : that this would be worthwhile. */
1316 :
1317 : class modifiable_tracker
1318 : {
1319 : hash_set<tree> set;
1320 : constexpr_global_ctx *global;
1321 : hash_set<tree> *previous_set;
1322 : public:
1323 173612 : modifiable_tracker (constexpr_global_ctx *g)
1324 173612 : : global (g), previous_set (g->modifiable)
1325 : {
1326 173612 : global->modifiable = &set;
1327 173612 : }
1328 173612 : ~modifiable_tracker ()
1329 : {
1330 173676 : for (tree t: set)
1331 64 : global->clear_value (t);
1332 173612 : global->modifiable = previous_set;
1333 173612 : }
1334 : };
1335 :
1336 : /* The constexpr expansion context. CALL is the current function
1337 : expansion, CTOR is the current aggregate initializer, OBJECT is the
1338 : object being initialized by CTOR, either a VAR_DECL or a _REF. */
1339 :
1340 : struct constexpr_ctx {
1341 : /* The part of the context that needs to be unique to the whole
1342 : cxx_eval_outermost_constant_expr invocation. */
1343 : constexpr_global_ctx *global;
1344 : /* The innermost call we're evaluating. */
1345 : constexpr_call *call;
1346 : /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen
1347 : within the current LOOP_EXPR. NULL if we aren't inside a loop. */
1348 : vec<tree> *save_exprs;
1349 : /* The CONSTRUCTOR we're currently building up for an aggregate
1350 : initializer. */
1351 : tree ctor;
1352 : /* The object we're building the CONSTRUCTOR for. */
1353 : tree object;
1354 : /* If inside SWITCH_EXPR. */
1355 : constexpr_switch_state *css_state;
1356 : /* The aggregate initialization context inside which this one is nested. This
1357 : is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs. */
1358 : const constexpr_ctx *parent;
1359 :
1360 : /* Whether we should error on a non-constant expression or fail quietly.
1361 : This flag needs to be here, but some of the others could move to global
1362 : if they get larger than a word. */
1363 : bool quiet;
1364 : /* Whether we are strictly conforming to constant expression rules or
1365 : trying harder to get a constant value. */
1366 : bool strict;
1367 : /* Whether __builtin_is_constant_evaluated () should be true. */
1368 : mce_value manifestly_const_eval;
1369 : };
1370 :
1371 : /* Return ctx->quiet. For use in reflect.cc. */
1372 :
1373 : bool
1374 1376 : cxx_constexpr_quiet_p (const constexpr_ctx *ctx)
1375 : {
1376 1376 : return ctx->quiet;
1377 : }
1378 :
1379 : /* Return ctx->manifestly_const_eval. For use in reflect.cc. */
1380 :
1381 : mce_value
1382 388 : cxx_constexpr_manifestly_const_eval (const constexpr_ctx *ctx)
1383 : {
1384 388 : return ctx->manifestly_const_eval;
1385 : }
1386 :
1387 : /* Return ctx->call->fundef->decl or NULL_TREE. For use in
1388 : reflect.cc. */
1389 :
1390 : tree
1391 2120 : cxx_constexpr_caller (const constexpr_ctx *ctx)
1392 : {
1393 2120 : if (ctx->call)
1394 958 : return ctx->call->fundef->decl;
1395 : else
1396 : return NULL_TREE;
1397 : }
1398 :
1399 : /* Return ctx->global->consteval_block. For use in reflect.cc. */
1400 :
1401 : tree
1402 158 : cxx_constexpr_consteval_block (const constexpr_ctx *ctx)
1403 : {
1404 158 : return ctx->global->consteval_block;
1405 : }
1406 :
1407 : /* Predicates for the meaning of *jump_target. */
1408 :
1409 : static bool
1410 110979997 : returns (tree *jump_target)
1411 : {
1412 19378215 : return *jump_target && TREE_CODE (*jump_target) == RETURN_EXPR;
1413 : }
1414 :
1415 : static bool
1416 105529948 : breaks (tree *jump_target)
1417 : {
1418 105529948 : return (*jump_target
1419 105529948 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1420 339 : && LABEL_DECL_BREAK (*jump_target))
1421 1378760 : || TREE_CODE (*jump_target) == BREAK_STMT
1422 1240097 : || TREE_CODE (*jump_target) == EXIT_EXPR));
1423 : }
1424 :
1425 : static bool
1426 142479884 : continues (tree *jump_target)
1427 : {
1428 142479884 : return (*jump_target
1429 142479884 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1430 339 : && LABEL_DECL_CONTINUE (*jump_target))
1431 1255568 : || TREE_CODE (*jump_target) == CONTINUE_STMT));
1432 : }
1433 :
1434 : static bool
1435 12972816 : switches (tree *jump_target)
1436 : {
1437 78169 : return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST;
1438 : }
1439 :
1440 : static bool
1441 1929408073 : throws (tree *jump_target)
1442 : {
1443 : /* void_node is for use in potential_constant_expression_1, otherwise
1444 : it should an artificial VAR_DECL created by constant evaluation
1445 : of __cxa_allocate_exception (). */
1446 214302577 : return (*jump_target && (VAR_P (*jump_target) || *jump_target == void_node));
1447 : }
1448 :
1449 : /* True if the constexpr relaxations afforded by P2280R4 for unknown
1450 : references and objects are in effect. */
1451 :
1452 : static bool
1453 271634400 : p2280_active_p (const constexpr_ctx *ctx)
1454 : {
1455 34647859 : if (ctx->manifestly_const_eval != mce_true)
1456 : /* Disable these relaxations during speculative constexpr folding,
1457 : as it can significantly increase compile time/memory use
1458 : (PR119387). */
1459 : return false;
1460 :
1461 : /* P2280R4 was accepted as a DR against C++11. */
1462 0 : return cxx_dialect >= cxx11;
1463 : }
1464 :
1465 : /* Remove T from the global values map, checking for attempts to destroy
1466 : a value that has already finished its lifetime. */
1467 :
1468 : static void
1469 243235121 : destroy_value_checked (const constexpr_ctx* ctx, tree t, bool *non_constant_p)
1470 : {
1471 243235121 : if (t == error_mark_node || TREE_TYPE (t) == error_mark_node)
1472 : return;
1473 :
1474 : /* Don't error again here if we've already reported a problem. */
1475 243235060 : if (!*non_constant_p
1476 211765775 : && DECL_P (t)
1477 : /* Non-trivial destructors have their lifetimes ended explicitly
1478 : with a clobber, so don't worry about it here. */
1479 211756712 : && (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (t))
1480 : /* ...except parameters are remapped in cxx_eval_call_expression,
1481 : and the destructor call during cleanup won't be able to tell that
1482 : this value has already been destroyed, so complain now. This is
1483 : not quite unobservable, but is extremely unlikely to crop up in
1484 : practice; see g++.dg/cpp2a/constexpr-lifetime2.C. */
1485 771463 : || TREE_CODE (t) == PARM_DECL)
1486 454221760 : && ctx->global->is_outside_lifetime (t))
1487 : {
1488 54 : if (!ctx->quiet)
1489 : {
1490 18 : auto_diagnostic_group d;
1491 18 : error ("destroying %qE outside its lifetime", t);
1492 18 : inform (DECL_SOURCE_LOCATION (t), "declared here");
1493 18 : }
1494 54 : *non_constant_p = true;
1495 : }
1496 243235060 : ctx->global->destroy_value (t);
1497 : }
1498 :
1499 : /* This internal flag controls whether we should avoid doing anything during
1500 : constexpr evaluation that would cause extra DECL_UID generation, such as
1501 : template instantiation and function body copying. */
1502 :
1503 : static bool uid_sensitive_constexpr_evaluation_value;
1504 :
1505 : /* An internal counter that keeps track of the number of times
1506 : uid_sensitive_constexpr_evaluation_p returned true. */
1507 :
1508 : static unsigned uid_sensitive_constexpr_evaluation_true_counter;
1509 :
1510 : /* The accessor for uid_sensitive_constexpr_evaluation_value which also
1511 : increments the corresponding counter. */
1512 :
1513 : static bool
1514 9108785 : uid_sensitive_constexpr_evaluation_p ()
1515 : {
1516 9022899 : if (uid_sensitive_constexpr_evaluation_value)
1517 : {
1518 243275 : ++uid_sensitive_constexpr_evaluation_true_counter;
1519 243266 : return true;
1520 : }
1521 : else
1522 : return false;
1523 : }
1524 :
1525 : /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel
1526 : enables the internal flag for uid_sensitive_constexpr_evaluation_p
1527 : during the lifetime of the sentinel object. Upon its destruction, the
1528 : previous value of uid_sensitive_constexpr_evaluation_p is restored. */
1529 :
1530 81652970 : uid_sensitive_constexpr_evaluation_sentinel
1531 : ::uid_sensitive_constexpr_evaluation_sentinel ()
1532 81652970 : : ovr (uid_sensitive_constexpr_evaluation_value, true)
1533 : {
1534 81652970 : }
1535 :
1536 : /* The default constructor for uid_sensitive_constexpr_evaluation_checker
1537 : records the current number of times that uid_sensitive_constexpr_evaluation_p
1538 : has been called and returned true. */
1539 :
1540 3887163765 : uid_sensitive_constexpr_evaluation_checker
1541 : ::uid_sensitive_constexpr_evaluation_checker ()
1542 3887163765 : : saved_counter (uid_sensitive_constexpr_evaluation_true_counter)
1543 : {
1544 3887163765 : }
1545 :
1546 : /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and
1547 : some constexpr evaluation was restricted due to u_s_c_e_p being called
1548 : and returning true during the lifetime of this checker object. */
1549 :
1550 : bool
1551 2578379431 : uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const
1552 : {
1553 2578379431 : return (uid_sensitive_constexpr_evaluation_value
1554 2578379431 : && saved_counter != uid_sensitive_constexpr_evaluation_true_counter);
1555 : }
1556 :
1557 :
1558 : /* A table of all constexpr calls that have been evaluated by the
1559 : compiler in this translation unit. */
1560 :
1561 : static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
1562 :
1563 : /* Compute a hash value for a constexpr call representation. */
1564 :
1565 : inline hashval_t
1566 226855870 : constexpr_call_hasher::hash (constexpr_call *info)
1567 : {
1568 226855870 : return info->hash;
1569 : }
1570 :
1571 : /* Return true if the objects pointed to by P and Q represent calls
1572 : to the same constexpr function with the same arguments.
1573 : Otherwise, return false. */
1574 :
1575 : bool
1576 242619910 : constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
1577 : {
1578 242619910 : if (lhs == rhs)
1579 : return true;
1580 242619910 : if (lhs->hash != rhs->hash)
1581 : return false;
1582 27917713 : if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
1583 : return false;
1584 27917713 : return cp_tree_equal (lhs->bindings, rhs->bindings);
1585 : }
1586 :
1587 : /* Initialize the constexpr call table, if needed. */
1588 :
1589 : static void
1590 37138139 : maybe_initialize_constexpr_call_table (void)
1591 : {
1592 37138139 : if (constexpr_call_table == NULL)
1593 18795 : constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
1594 37138139 : }
1595 :
1596 : /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
1597 : a function happens to get called recursively, we unshare the callee
1598 : function's body and evaluate this unshared copy instead of evaluating the
1599 : original body.
1600 :
1601 : FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function
1602 : copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map
1603 : that's keyed off of the original FUNCTION_DECL and whose value is a
1604 : TREE_LIST of this function's unused copies awaiting reuse.
1605 :
1606 : This is not GC-deletable to avoid GC affecting UID generation. */
1607 :
1608 : static GTY(()) decl_tree_map *fundef_copies_table;
1609 :
1610 : /* Reuse a copy or create a new unshared copy of the function FUN.
1611 : Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE
1612 : is parms, TYPE is result. */
1613 :
1614 : static tree
1615 87300997 : get_fundef_copy (constexpr_fundef *fundef)
1616 : {
1617 87300997 : tree copy;
1618 87300997 : bool existed;
1619 87300997 : tree *slot = &(hash_map_safe_get_or_insert<hm_ggc>
1620 87300997 : (fundef_copies_table, fundef->decl, &existed, 127));
1621 :
1622 87300997 : if (!existed)
1623 : {
1624 : /* There is no cached function available, or in use. We can use
1625 : the function directly. That the slot is now created records
1626 : that this function is now in use. */
1627 7647513 : copy = build_tree_list (fundef->body, fundef->parms);
1628 7647513 : TREE_TYPE (copy) = fundef->result;
1629 : }
1630 79653484 : else if (*slot == NULL_TREE)
1631 : {
1632 4438 : if (uid_sensitive_constexpr_evaluation_p ())
1633 9 : return NULL_TREE;
1634 :
1635 : /* We've already used the function itself, so make a copy. */
1636 4429 : copy = build_tree_list (NULL, NULL);
1637 4429 : tree saved_body = DECL_SAVED_TREE (fundef->decl);
1638 4429 : tree saved_parms = DECL_ARGUMENTS (fundef->decl);
1639 4429 : tree saved_result = DECL_RESULT (fundef->decl);
1640 4429 : tree saved_fn = current_function_decl;
1641 4429 : DECL_SAVED_TREE (fundef->decl) = fundef->body;
1642 4429 : DECL_ARGUMENTS (fundef->decl) = fundef->parms;
1643 4429 : DECL_RESULT (fundef->decl) = fundef->result;
1644 4429 : current_function_decl = fundef->decl;
1645 4429 : TREE_PURPOSE (copy) = copy_fn (fundef->decl, TREE_VALUE (copy),
1646 4429 : TREE_TYPE (copy));
1647 4429 : current_function_decl = saved_fn;
1648 4429 : DECL_RESULT (fundef->decl) = saved_result;
1649 4429 : DECL_ARGUMENTS (fundef->decl) = saved_parms;
1650 4429 : DECL_SAVED_TREE (fundef->decl) = saved_body;
1651 : }
1652 : else
1653 : {
1654 : /* We have a cached function available. */
1655 79649046 : copy = *slot;
1656 79649046 : *slot = TREE_CHAIN (copy);
1657 : }
1658 :
1659 : return copy;
1660 : }
1661 :
1662 : /* Save the copy COPY of function FUN for later reuse by
1663 : get_fundef_copy(). By construction, there will always be an entry
1664 : to find. */
1665 :
1666 : static void
1667 87300984 : save_fundef_copy (tree fun, tree copy)
1668 : {
1669 87300984 : tree *slot = fundef_copies_table->get (fun);
1670 87300984 : TREE_CHAIN (copy) = *slot;
1671 87300984 : *slot = copy;
1672 87300984 : }
1673 :
1674 : static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree,
1675 : value_cat, bool *, bool *, tree *);
1676 : static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree,
1677 : bool *, tree *);
1678 : static tree find_heap_var_refs (tree *, int *, void *);
1679 :
1680 : /* For exception object EXC if it has class type and usable what () method
1681 : which returns cv char * return the xmalloced string literal which it returns
1682 : if possible, otherwise return NULL. */
1683 :
1684 : static char *
1685 396 : exception_what_str (const constexpr_ctx *ctx, tree exc)
1686 : {
1687 396 : tree type = strip_array_types (TREE_TYPE (exc));
1688 396 : if (!CLASS_TYPE_P (type))
1689 : return NULL;
1690 340 : tree std_exception = lookup_qualified_name (std_node, "exception",
1691 : LOOK_want::NORMAL, false);
1692 340 : if (TREE_CODE (std_exception) != TYPE_DECL)
1693 : return NULL;
1694 334 : if (!CLASS_TYPE_P (TREE_TYPE (std_exception)))
1695 : return NULL;
1696 334 : base_kind b_kind;
1697 334 : tree binfo = lookup_base (type, TREE_TYPE (std_exception), ba_check, &b_kind,
1698 : tf_none);
1699 334 : if (binfo == NULL_TREE || binfo == error_mark_node)
1700 : return NULL;
1701 326 : if (type != TREE_TYPE (exc))
1702 288 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1703 326 : tree call
1704 326 : = finish_class_member_access_expr (exc, get_identifier ("what"), false,
1705 : tf_none);
1706 326 : if (call == error_mark_node)
1707 : return NULL;
1708 326 : releasing_vec what_args;
1709 326 : call = finish_call_expr (call, &what_args, false, false, tf_none);
1710 326 : if (call == error_mark_node)
1711 : return NULL;
1712 326 : if (TREE_CODE (TREE_TYPE (call)) != POINTER_TYPE
1713 326 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1714 326 : || !COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1715 326 : || !tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (call))),
1716 326 : TYPE_SIZE_UNIT (char_type_node))
1717 652 : || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (call))) != BITS_PER_UNIT)
1718 : return NULL;
1719 326 : if (!potential_constant_expression (call))
1720 : return NULL;
1721 326 : bool non_constant_p = false, overflow_p = false;
1722 326 : tree jmp_target = NULL;
1723 326 : tree ptr = cxx_eval_constant_expression (ctx, call, vc_prvalue,
1724 : &non_constant_p, &overflow_p,
1725 : &jmp_target);
1726 652 : if (throws (&jmp_target) || non_constant_p)
1727 : return NULL;
1728 326 : if (reduced_constant_expression_p (ptr))
1729 42 : if (const char *msg = c_getstr (ptr))
1730 42 : return xstrdup (msg);
1731 284 : auto_vec <char, 32> v;
1732 11754 : for (unsigned i = 0; i < INT_MAX; ++i)
1733 : {
1734 11754 : tree t = call;
1735 11754 : if (i)
1736 11470 : t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, size_int (i));
1737 11754 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
1738 11754 : non_constant_p = false;
1739 11754 : overflow_p = false;
1740 11754 : jmp_target = NULL;
1741 11754 : tree t2 = cxx_eval_constant_expression (ctx, t, vc_prvalue,
1742 : &non_constant_p, &overflow_p,
1743 : &jmp_target);
1744 11754 : if (throws (&jmp_target)
1745 11754 : || non_constant_p
1746 11754 : || !tree_fits_shwi_p (t2))
1747 0 : return NULL;
1748 11754 : char c = tree_to_shwi (t2);
1749 11754 : v.safe_push (c);
1750 11754 : if (c == '\0')
1751 : break;
1752 : }
1753 568 : return xstrdup (v.address ());
1754 610 : }
1755 :
1756 : /* Diagnose constant expression evaluation encountering call to
1757 : std::terminate due to exception EXC. */
1758 :
1759 : static void
1760 22 : diagnose_std_terminate (location_t loc, const constexpr_ctx *ctx, tree exc)
1761 : {
1762 22 : tree type = strip_array_types (TREE_TYPE (exc));
1763 22 : if (char *str = exception_what_str (ctx, exc))
1764 : {
1765 4 : error_at (loc, "%qs called after throwing an exception of type %qT; "
1766 : "%<what()%>: %qs", "std::terminate", type, str);
1767 4 : free (str);
1768 : }
1769 : else
1770 : {
1771 18 : if (type != TREE_TYPE (exc))
1772 18 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1773 18 : bool non_constant_p = false, overflow_p = false;
1774 18 : tree jmp_target = NULL;
1775 18 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1776 : &non_constant_p, &overflow_p,
1777 : &jmp_target);
1778 18 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1779 18 : if (reduced_constant_expression_p (val))
1780 18 : error_at (loc, "%qs called after throwing an exception %qE",
1781 : "std::terminate", val);
1782 : else
1783 0 : error_at (loc, "%qs called after throwing an exception of type %qT",
1784 : "std::terminate", type);
1785 : }
1786 22 : }
1787 :
1788 : /* Diagnose constant expression evaluation encountering call to
1789 : uncaught exception EXC. */
1790 :
1791 : static void
1792 374 : diagnose_uncaught_exception (location_t loc, const constexpr_ctx *ctx, tree exc)
1793 : {
1794 374 : tree type = strip_array_types (TREE_TYPE (exc));
1795 374 : if (char *str = exception_what_str (ctx, exc))
1796 : {
1797 322 : error_at (loc, "uncaught exception of type %qT; %<what()%>: %qs", type, str);
1798 322 : free (str);
1799 : }
1800 : else
1801 : {
1802 52 : if (type != TREE_TYPE (exc))
1803 52 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1804 52 : bool non_constant_p = false, overflow_p = false;
1805 52 : tree jmp_target = NULL;
1806 52 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1807 : &non_constant_p, &overflow_p,
1808 : &jmp_target);
1809 52 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1810 52 : if (reduced_constant_expression_p (val))
1811 50 : error_at (loc, "uncaught exception %qE", val);
1812 : else
1813 2 : error_at (loc, "uncaught exception of type %qT", type);
1814 : }
1815 374 : }
1816 :
1817 : /* Kinds of __cxa_* functions (and a few other EH related ones) we handle as
1818 : magic constexpr functions for C++26. */
1819 :
1820 : enum cxa_builtin {
1821 : CXA_NONE = 0,
1822 : CXA_ALLOCATE_EXCEPTION = 1,
1823 : CXA_FREE_EXCEPTION = 2,
1824 : CXA_THROW = 3,
1825 : CXA_BEGIN_CATCH = 4,
1826 : CXA_END_CATCH = 5,
1827 : CXA_RETHROW = 6,
1828 : CXA_GET_EXCEPTION_PTR = 7,
1829 : CXA_BAD_CAST = 8,
1830 : CXA_BAD_TYPEID = 9,
1831 : CXA_THROW_BAD_ARRAY_NEW_LENGTH = 10,
1832 : STD_RETHROW_EXCEPTION = 11,
1833 : BUILTIN_EH_PTR_ADJUST_REF = 12,
1834 : BUILTIN_UNCAUGHT_EXCEPTIONS = 13,
1835 : BUILTIN_CURRENT_EXCEPTION = 14
1836 : };
1837 :
1838 : /* Return cxa_builtin if FNDECL is a __cxa_* function handled as
1839 : magic constexpr function for C++26. Return CXA_NONE otherwise. */
1840 :
1841 : static enum cxa_builtin
1842 37025039 : cxx_cxa_builtin_fn_p (tree fndecl)
1843 : {
1844 37025039 : if (cxx_dialect < cxx26)
1845 : return CXA_NONE;
1846 3671258 : if (DECL_LANGUAGE (fndecl) != lang_c)
1847 : {
1848 3062571 : if (!decl_in_std_namespace_p (fndecl))
1849 : return CXA_NONE;
1850 1292517 : if (id_equal (DECL_NAME (fndecl), "rethrow_exception"))
1851 : return STD_RETHROW_EXCEPTION;
1852 1292475 : return CXA_NONE;
1853 : }
1854 608687 : if (!startswith (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__cxa_"))
1855 : return CXA_NONE;
1856 81510 : if (id_equal (DECL_NAME (fndecl), "__cxa_allocate_exception"))
1857 : return CXA_ALLOCATE_EXCEPTION;
1858 25481 : if (id_equal (DECL_NAME (fndecl), "__cxa_free_exception"))
1859 : return CXA_FREE_EXCEPTION;
1860 25479 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw"))
1861 : return CXA_THROW;
1862 16130 : if (id_equal (DECL_NAME (fndecl), "__cxa_begin_catch"))
1863 : return CXA_BEGIN_CATCH;
1864 4827 : if (id_equal (DECL_NAME (fndecl), "__cxa_end_catch"))
1865 : return CXA_END_CATCH;
1866 1084 : if (id_equal (DECL_NAME (fndecl), "__cxa_rethrow"))
1867 : return CXA_RETHROW;
1868 978 : if (id_equal (DECL_NAME (fndecl), "__cxa_get_exception_ptr"))
1869 : return CXA_GET_EXCEPTION_PTR;
1870 934 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_cast"))
1871 : return CXA_BAD_CAST;
1872 638 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_typeid"))
1873 : return CXA_BAD_TYPEID;
1874 625 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw_bad_array_new_length"))
1875 33 : return CXA_THROW_BAD_ARRAY_NEW_LENGTH;
1876 : return CXA_NONE;
1877 : }
1878 :
1879 : /* Helper function for cxx_eval_cxa_builtin_fn.
1880 : Check if ARG is a valid first argument of __cxa_throw or
1881 : __cxa_free_exception or __builtin_eh_ptr_adjust_ref. Return NULL_TREE if
1882 : not, otherwise return the artificial __cxa_allocate_exception allocated
1883 : VAR_DECL. FREE_EXC is true for __cxa_free_exception, false otherwise. */
1884 :
1885 : static tree
1886 1916 : cxa_check_throw_arg (tree arg, bool free_exc)
1887 : {
1888 1916 : STRIP_NOPS (arg);
1889 1916 : if (TREE_CODE (arg) != ADDR_EXPR)
1890 : return NULL_TREE;
1891 1916 : arg = TREE_OPERAND (arg, 0);
1892 1916 : if (!VAR_P (arg)
1893 1916 : || !DECL_ARTIFICIAL (arg)
1894 1916 : || ((!free_exc || DECL_NAME (arg) != heap_uninit_identifier)
1895 1916 : && DECL_NAME (arg) != heap_identifier)
1896 3832 : || !DECL_LANG_SPECIFIC (arg))
1897 0 : return NULL_TREE;
1898 : return arg;
1899 : }
1900 :
1901 : /* Helper function for cxx_eval_cxa_builtin_fn.
1902 : "Allocate" on the constexpr heap an exception object of TYPE
1903 : with REFCOUNT. */
1904 :
1905 : static tree
1906 17917 : cxa_allocate_exception (location_t loc, const constexpr_ctx *ctx, tree type,
1907 : tree refcount)
1908 : {
1909 17917 : tree var = build_decl (loc, VAR_DECL, heap_uninit_identifier, type);
1910 17917 : DECL_ARTIFICIAL (var) = 1;
1911 17917 : retrofit_lang_decl (var);
1912 17917 : DECL_EXCEPTION_REFCOUNT (var) = refcount;
1913 17917 : ctx->global->heap_vars.safe_push (var);
1914 17917 : return var;
1915 : }
1916 :
1917 : /* Evaluate various __cxa_* calls as magic constexpr builtins for
1918 : C++26 constexpr exception support (P3068R5). */
1919 :
1920 : static tree
1921 30389 : cxx_eval_cxa_builtin_fn (const constexpr_ctx *ctx, tree call,
1922 : enum cxa_builtin kind, tree fndecl,
1923 : bool *non_constant_p, bool *overflow_p,
1924 : tree *jump_target)
1925 : {
1926 30389 : int nargs = call_expr_nargs (call);
1927 30389 : location_t loc = cp_expr_loc_or_input_loc (call);
1928 30389 : tree args[4], arg;
1929 30389 : if (nargs > 4)
1930 : {
1931 0 : invalid_nargs:
1932 0 : if (!ctx->quiet)
1933 0 : error_at (loc, "call to %qD function with incorrect "
1934 : "number of arguments", fndecl);
1935 0 : *non_constant_p = true;
1936 0 : return call;
1937 : }
1938 30389 : if ((kind == CXA_BEGIN_CATCH || kind == CXA_GET_EXCEPTION_PTR)
1939 7561 : && nargs == 1
1940 7561 : && (arg = CALL_EXPR_ARG (call, 0))
1941 7561 : && TREE_CODE (arg) == CALL_EXPR
1942 7561 : && call_expr_nargs (arg) == 1
1943 37950 : && integer_zerop (CALL_EXPR_ARG (arg, 0)))
1944 7561 : if (tree fun = get_function_named_in_call (arg))
1945 7561 : if (fndecl_built_in_p (fun, BUILT_IN_EH_POINTER))
1946 : {
1947 7561 : if (ctx->global->caught_exceptions.length () < 2)
1948 : {
1949 3786 : no_caught_exceptions:
1950 3786 : if (!ctx->quiet)
1951 0 : error_at (loc, "%qD called with no caught exceptions pending",
1952 : fndecl);
1953 3786 : *non_constant_p = true;
1954 3786 : return call;
1955 : }
1956 : /* Both __cxa_get_exception_ptr (__builtin_eh_pointer (0))
1957 : and __cxa_begin_catch (__builtin_eh_pointer (0)) calls expect
1958 : ctx->global->caught_exceptions vector to end with
1959 : __cxa_allocate_exception created artificial VAR_DECL (the
1960 : exception object) followed by handler type, pushed by TRY_BLOCK
1961 : evaluation. The only difference between the functions is that
1962 : __cxa_begin_catch pops the handler type from the vector and keeps
1963 : the VAR_DECL last and decreases uncaught_exceptions. The
1964 : VAR_DECL after __cxa_begin_catch serves as the current exception
1965 : and is then popped in __cxa_end_catch evaluation. */
1966 3775 : tree handler_type = ctx->global->caught_exceptions.last ();
1967 3775 : if (handler_type && (VAR_P (handler_type)
1968 3693 : || TREE_CODE (handler_type) == TREE_LIST))
1969 0 : goto no_caught_exceptions;
1970 3775 : unsigned idx = ctx->global->caught_exceptions.length () - 2;
1971 3775 : arg = ctx->global->caught_exceptions[idx];
1972 3775 : if (TREE_CODE (arg) == TREE_LIST)
1973 0 : arg = TREE_VALUE (arg);
1974 3775 : gcc_assert (VAR_P (arg));
1975 3775 : if (kind == CXA_BEGIN_CATCH)
1976 : {
1977 3747 : ctx->global->caught_exceptions.pop ();
1978 3747 : --ctx->global->uncaught_exceptions;
1979 : }
1980 3775 : if (handler_type == NULL_TREE)
1981 : /* Used for catch (...). Just return void. */
1982 82 : return void_node;
1983 3693 : else if (POINTER_TYPE_P (handler_type))
1984 : {
1985 : /* Used for catch of a pointer. */
1986 66 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
1987 66 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
1988 : size_zero_node, NULL_TREE, NULL_TREE);
1989 66 : arg = cp_convert (handler_type, arg,
1990 66 : ctx->quiet ? tf_none : tf_warning_or_error);
1991 66 : if (arg == error_mark_node)
1992 : {
1993 0 : *non_constant_p = true;
1994 0 : return call;
1995 : }
1996 : }
1997 : else
1998 : {
1999 : /* Used for catch of a non-pointer type. */
2000 3627 : tree exc_type = strip_array_types (TREE_TYPE (arg));
2001 3607 : if (TYPE_PTRMEM_P (handler_type)
2002 3673 : && !same_type_ignoring_top_level_qualifiers_p
2003 46 : (handler_type, exc_type))
2004 : {
2005 46 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
2006 46 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
2007 : size_zero_node, NULL_TREE, NULL_TREE);
2008 46 : arg = cp_convert (handler_type, arg,
2009 46 : ctx->quiet ? tf_none
2010 : : tf_warning_or_error);
2011 46 : if (arg == error_mark_node)
2012 : {
2013 0 : *non_constant_p = true;
2014 0 : return call;
2015 : }
2016 46 : tree var = build_decl (loc, VAR_DECL, heap_identifier,
2017 46 : handler_type);
2018 46 : DECL_ARTIFICIAL (var) = 1;
2019 46 : ctx->global->heap_vars.safe_push (var);
2020 46 : ctx->global->put_value (var, NULL_TREE);
2021 46 : tree init = build2_loc (loc, INIT_EXPR, handler_type,
2022 : var, arg);
2023 46 : arg = ctx->global->caught_exceptions[idx];
2024 46 : if (TREE_CODE (arg) == TREE_LIST)
2025 : {
2026 0 : DECL_CHAIN (var) = TREE_PURPOSE (arg);
2027 0 : TREE_PURPOSE (arg) = var;
2028 : }
2029 : else
2030 46 : ctx->global->caught_exceptions[idx]
2031 92 : = build_tree_list (var, arg);
2032 46 : arg = cp_build_addr_expr (var, tf_none);
2033 46 : arg = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (arg),
2034 : init, arg);
2035 : }
2036 : else
2037 : {
2038 3581 : tree exc_ptr_type = build_pointer_type (exc_type);
2039 3581 : arg = build_fold_addr_expr_with_type (arg, exc_ptr_type);
2040 3581 : if (CLASS_TYPE_P (handler_type))
2041 : {
2042 3491 : tree ptr_type = build_pointer_type (handler_type);
2043 3491 : arg = cp_convert (ptr_type, arg,
2044 3491 : ctx->quiet ? tf_none
2045 : : tf_warning_or_error);
2046 3491 : if (arg == error_mark_node)
2047 : {
2048 0 : *non_constant_p = true;
2049 0 : return call;
2050 : }
2051 : }
2052 : }
2053 : }
2054 3693 : return cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2055 : non_constant_p, overflow_p,
2056 3693 : jump_target);
2057 : }
2058 42984 : for (int i = 0; i < nargs; ++i)
2059 : {
2060 20156 : args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (call, i),
2061 : vc_prvalue, non_constant_p,
2062 : overflow_p, jump_target);
2063 20156 : if (*non_constant_p)
2064 : return call;
2065 20156 : if (*jump_target)
2066 : return NULL_TREE;
2067 : }
2068 22828 : switch (kind)
2069 : {
2070 14618 : case CXA_ALLOCATE_EXCEPTION:
2071 14618 : if (nargs != 1)
2072 0 : goto invalid_nargs;
2073 14618 : if (!tree_fits_uhwi_p (args[0]))
2074 : {
2075 0 : if (!ctx->quiet)
2076 0 : error_at (loc, "cannot allocate exception: size not constant");
2077 0 : *non_constant_p = true;
2078 0 : return call;
2079 : }
2080 : else
2081 : {
2082 29236 : tree type = build_array_type_nelts (char_type_node,
2083 14618 : tree_to_uhwi (args[0]));
2084 14618 : tree var = cxa_allocate_exception (loc, ctx, type, size_zero_node);
2085 14618 : ctx->global->put_value (var, NULL_TREE);
2086 14618 : return fold_convert (ptr_type_node, build_address (var));
2087 : }
2088 2 : case CXA_FREE_EXCEPTION:
2089 2 : if (nargs != 1)
2090 0 : goto invalid_nargs;
2091 2 : arg = cxa_check_throw_arg (args[0], true);
2092 2 : if (arg == NULL_TREE)
2093 : {
2094 0 : invalid_ptr:
2095 0 : if (!ctx->quiet)
2096 0 : error_at (loc, "first argument to %qD function not result of "
2097 : "%<__cxa_allocate_exception%>", fndecl);
2098 0 : *non_constant_p = true;
2099 0 : return call;
2100 : }
2101 2 : DECL_NAME (arg) = heap_deleted_identifier;
2102 2 : ctx->global->destroy_value (arg);
2103 2 : ctx->global->heap_dealloc_count++;
2104 2 : return void_node;
2105 1748 : case CXA_THROW:
2106 1748 : if (nargs != 3)
2107 0 : goto invalid_nargs;
2108 1748 : arg = cxa_check_throw_arg (args[0], false);
2109 1748 : if (arg == NULL_TREE)
2110 0 : goto invalid_ptr;
2111 1748 : DECL_EXCEPTION_REFCOUNT (arg)
2112 1748 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2113 : size_one_node);
2114 1748 : ++ctx->global->uncaught_exceptions;
2115 1748 : *jump_target = arg;
2116 1748 : return void_node;
2117 0 : case CXA_BEGIN_CATCH:
2118 0 : case CXA_GET_EXCEPTION_PTR:
2119 0 : goto invalid_nargs;
2120 3743 : case CXA_END_CATCH:
2121 3743 : if (nargs != 0)
2122 0 : goto invalid_nargs;
2123 3743 : if (ctx->global->caught_exceptions.is_empty ())
2124 : {
2125 0 : no_active_exc:
2126 0 : if (!ctx->quiet)
2127 0 : error_at (loc, "%qD called with no caught exceptions active",
2128 : fndecl);
2129 0 : *non_constant_p = true;
2130 0 : return call;
2131 : }
2132 : else
2133 : {
2134 3743 : arg = ctx->global->caught_exceptions.pop ();
2135 3743 : if (arg == NULL_TREE
2136 3743 : || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2137 0 : goto no_active_exc;
2138 3743 : if (TREE_CODE (arg) == TREE_LIST)
2139 : {
2140 92 : for (tree aux = TREE_PURPOSE (arg); aux; aux = DECL_CHAIN (aux))
2141 : {
2142 46 : DECL_NAME (aux) = heap_deleted_identifier;
2143 46 : ctx->global->destroy_value (aux);
2144 46 : ctx->global->heap_dealloc_count++;
2145 : }
2146 46 : arg = TREE_VALUE (arg);
2147 : }
2148 3743 : DECL_CHAIN (arg) = NULL_TREE;
2149 3821 : free_except:
2150 3821 : DECL_EXCEPTION_REFCOUNT (arg)
2151 3821 : = size_binop (MINUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2152 : size_one_node);
2153 3821 : if (integer_zerop (DECL_EXCEPTION_REFCOUNT (arg)))
2154 : {
2155 3611 : if (type_build_dtor_call (TREE_TYPE (arg)))
2156 : {
2157 : /* So that we don't complain about out-of-consteval use. */
2158 3393 : temp_override<tree> ovr (current_function_decl);
2159 3393 : if (ctx->call && ctx->call->fundef)
2160 3393 : current_function_decl = ctx->call->fundef->decl;
2161 3393 : tree cleanup
2162 3415 : = cxx_maybe_build_cleanup (arg, (ctx->quiet ? tf_none
2163 : : tf_warning_or_error));
2164 3393 : if (cleanup == error_mark_node)
2165 0 : *non_constant_p = true;
2166 3393 : tree jmp_target = NULL_TREE;
2167 3393 : cxx_eval_constant_expression (ctx, cleanup, vc_discard,
2168 : non_constant_p, overflow_p,
2169 : &jmp_target);
2170 3393 : if (throws (&jmp_target))
2171 0 : *jump_target = jmp_target;
2172 3393 : }
2173 3611 : DECL_NAME (arg) = heap_deleted_identifier;
2174 3611 : ctx->global->destroy_value (arg);
2175 3611 : ctx->global->heap_dealloc_count++;
2176 : }
2177 : }
2178 3821 : return void_node;
2179 98 : case CXA_RETHROW:
2180 98 : if (nargs != 0)
2181 0 : goto invalid_nargs;
2182 98 : unsigned idx;
2183 196 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2184 82 : if (arg == NULL_TREE || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2185 0 : --idx;
2186 : else
2187 : break;
2188 98 : if (arg == NULL_TREE)
2189 : {
2190 16 : if (!ctx->quiet)
2191 4 : error_at (loc, "%qD called with no caught exceptions active",
2192 : fndecl);
2193 16 : *non_constant_p = true;
2194 16 : return call;
2195 : }
2196 82 : if (TREE_CODE (arg) == TREE_LIST)
2197 0 : arg = TREE_VALUE (arg);
2198 82 : DECL_EXCEPTION_REFCOUNT (arg)
2199 82 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2200 82 : ++ctx->global->uncaught_exceptions;
2201 : /* Don't cache calls which rethrow, they depend on the current
2202 : exception which might be caught in the caller. */
2203 82 : ctx->global->state_dependent = true;
2204 82 : *jump_target = arg;
2205 82 : return void_node;
2206 163 : case CXA_BAD_CAST:
2207 163 : case CXA_BAD_TYPEID:
2208 163 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2209 163 : if (nargs != 0)
2210 0 : goto invalid_nargs;
2211 : else
2212 : {
2213 163 : tree name;
2214 163 : switch (kind)
2215 : {
2216 123 : case CXA_BAD_CAST:
2217 123 : name = get_identifier ("bad_cast");
2218 123 : break;
2219 7 : case CXA_BAD_TYPEID:
2220 7 : name = get_identifier ("bad_typeid");
2221 7 : break;
2222 33 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2223 33 : name = get_identifier ("bad_array_new_length");
2224 33 : break;
2225 : default:
2226 : gcc_unreachable ();
2227 : }
2228 163 : tree decl = lookup_qualified_name (std_node, name);
2229 163 : if (TREE_CODE (decl) != TYPE_DECL
2230 135 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2231 298 : || !type_build_ctor_call (TREE_TYPE (decl)))
2232 : {
2233 28 : if (!ctx->quiet)
2234 8 : error_at (loc, "%qD called without %<std::%D%> being defined",
2235 : fndecl, name);
2236 28 : *non_constant_p = true;
2237 28 : return call;
2238 : }
2239 135 : tree type = TREE_TYPE (decl);
2240 135 : tree var = cxa_allocate_exception (loc, ctx, type, size_one_node);
2241 135 : tree ctor
2242 135 : = build_special_member_call (var, complete_ctor_identifier,
2243 : NULL, type, LOOKUP_NORMAL,
2244 135 : ctx->quiet ? tf_none
2245 : : tf_warning_or_error);
2246 135 : if (ctor == error_mark_node)
2247 : {
2248 0 : *non_constant_p = true;
2249 0 : return call;
2250 : }
2251 135 : if (TREE_CONSTANT (ctor))
2252 0 : ctx->global->put_value (var, ctor);
2253 : else
2254 : {
2255 135 : ctx->global->put_value (var, NULL_TREE);
2256 135 : cxx_eval_constant_expression (ctx, ctor, vc_discard,
2257 : non_constant_p, overflow_p,
2258 : jump_target);
2259 135 : if (*non_constant_p)
2260 : return call;
2261 135 : if (throws (jump_target))
2262 : return NULL_TREE;
2263 : }
2264 135 : ++ctx->global->uncaught_exceptions;
2265 135 : *jump_target = var;
2266 : }
2267 135 : return void_node;
2268 82 : case BUILTIN_UNCAUGHT_EXCEPTIONS:
2269 82 : if (nargs != 0)
2270 0 : goto invalid_nargs;
2271 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2272 : want to give a definite answer during mce_unknown evaluation,
2273 : because that might prevent evaluation later on when some
2274 : exceptions might be uncaught. But unlike that, we don't
2275 : want to constant fold it even during cp_fold, because at runtime
2276 : std::uncaught_exceptions () might still be non-zero. */
2277 82 : if (ctx->manifestly_const_eval != mce_true)
2278 : {
2279 46 : *non_constant_p = true;
2280 46 : return call;
2281 : }
2282 : /* Don't cache calls which call __builtin_uncaught_exceptions (),
2283 : they depend on the current uncaught exceptions which might
2284 : be the state from their caller. */
2285 36 : ctx->global->state_dependent = true;
2286 36 : return build_int_cst (integer_type_node,
2287 36 : ctx->global->uncaught_exceptions);
2288 2208 : case BUILTIN_CURRENT_EXCEPTION:
2289 2208 : if (nargs != 0)
2290 0 : goto invalid_nargs;
2291 : else
2292 : {
2293 2208 : tree name = get_identifier ("exception_ptr");
2294 2208 : tree decl = lookup_qualified_name (std_node, name);
2295 2208 : tree fld;
2296 2208 : if (TREE_CODE (decl) != TYPE_DECL
2297 2208 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2298 2208 : || !COMPLETE_TYPE_P (TREE_TYPE (decl))
2299 2208 : || !(fld = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (decl))))
2300 2208 : || DECL_ARTIFICIAL (fld)
2301 2208 : || TREE_CODE (TREE_TYPE (fld)) != POINTER_TYPE
2302 2208 : || next_aggregate_field (DECL_CHAIN (fld))
2303 4416 : || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (decl)),
2304 2208 : TYPE_SIZE (TREE_TYPE (fld))))
2305 : {
2306 0 : if (!ctx->quiet)
2307 0 : error_at (loc, "%qD called without supportable %qs",
2308 : fndecl, "std::exception_ptr");
2309 0 : *non_constant_p = true;
2310 0 : return call;
2311 : }
2312 4416 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2313 42 : if (arg == NULL_TREE
2314 42 : || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2315 0 : --idx;
2316 : else
2317 : break;
2318 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2319 : want to give a definite answer during mce_unknown evaluation,
2320 : because that might prevent evaluation later on when some
2321 : exceptions might be current. But unlike that, we don't
2322 : want to constant fold it to null even during cp_fold, because
2323 : at runtime std::current_exception () might still be non-null. */
2324 2208 : if (ctx->manifestly_const_eval != mce_true && arg == NULL_TREE)
2325 : {
2326 2154 : *non_constant_p = true;
2327 2154 : return call;
2328 : }
2329 54 : if (arg == NULL_TREE)
2330 12 : arg = build_zero_cst (TREE_TYPE (fld));
2331 : else
2332 : {
2333 42 : if (TREE_CODE (arg) == TREE_LIST)
2334 0 : arg = TREE_VALUE (arg);
2335 42 : DECL_EXCEPTION_REFCOUNT (arg)
2336 42 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2337 : size_one_node);
2338 42 : arg = fold_convert (ptr_type_node, build_address (arg));
2339 : }
2340 : /* Don't cache calls which call __builtin_current_exception (),
2341 : they depend on the current exception which might be caught
2342 : in the caller. */
2343 54 : ctx->global->state_dependent = true;
2344 54 : return build_constructor_single (TREE_TYPE (decl), fld, arg);
2345 : }
2346 40 : case STD_RETHROW_EXCEPTION:
2347 40 : if (nargs != 1)
2348 0 : goto invalid_nargs;
2349 40 : if (TYPE_REF_P (TREE_TYPE (args[0])))
2350 : {
2351 40 : arg = args[0];
2352 40 : STRIP_NOPS (arg);
2353 40 : if (TREE_CODE (arg) == ADDR_EXPR)
2354 : {
2355 40 : args[0]
2356 40 : = cxx_eval_constant_expression (ctx, TREE_OPERAND (arg, 0),
2357 : vc_prvalue, non_constant_p,
2358 : overflow_p, jump_target);
2359 40 : if (*non_constant_p)
2360 : return call;
2361 40 : if (*jump_target)
2362 : return NULL_TREE;
2363 : }
2364 : }
2365 40 : if (TREE_CODE (args[0]) != CONSTRUCTOR
2366 40 : || CONSTRUCTOR_NELTS (args[0]) != 1)
2367 : {
2368 0 : invalid_std_rethrow:
2369 0 : if (!ctx->quiet)
2370 0 : error_at (loc, "%qD called with unexpected %qs argument",
2371 : fndecl, "std::exception_ptr");
2372 0 : *non_constant_p = true;
2373 0 : return void_node;
2374 : }
2375 40 : arg = cxa_check_throw_arg (CONSTRUCTOR_ELT (args[0], 0)->value, false);
2376 40 : if (arg == NULL_TREE)
2377 0 : goto invalid_std_rethrow;
2378 40 : DECL_EXCEPTION_REFCOUNT (arg)
2379 40 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2380 40 : ++ctx->global->uncaught_exceptions;
2381 40 : *jump_target = arg;
2382 40 : return void_node;
2383 126 : case BUILTIN_EH_PTR_ADJUST_REF:
2384 126 : if (nargs != 2)
2385 0 : goto invalid_nargs;
2386 126 : arg = cxa_check_throw_arg (args[0], false);
2387 126 : if (arg == NULL_TREE)
2388 0 : goto invalid_ptr;
2389 126 : if (integer_onep (args[1]))
2390 48 : DECL_EXCEPTION_REFCOUNT (arg)
2391 96 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2392 : size_one_node);
2393 78 : else if (integer_minus_onep (args[1]))
2394 78 : goto free_except;
2395 : else
2396 : {
2397 0 : if (!ctx->quiet)
2398 0 : error_at (loc, "%qD called with second argument "
2399 : "other than 1 or -1", fndecl);
2400 0 : *non_constant_p = true;
2401 : }
2402 48 : return void_node;
2403 0 : default:
2404 0 : gcc_unreachable ();
2405 : }
2406 : }
2407 :
2408 : /* Variables and functions to manage constexpr call expansion context.
2409 : These do not need to be marked for PCH or GC. */
2410 :
2411 : /* FIXME remember and print actual constant arguments. */
2412 : static vec<tree> call_stack;
2413 : static int call_stack_tick;
2414 : static int last_cx_error_tick;
2415 :
2416 : /* Attempt to evaluate T which represents a call to __builtin_constexpr_diag.
2417 : The arguments should be an integer (0 for inform, 1 for warning, 2 for
2418 : error) optionally with 16 ored in if it should use caller's caller location
2419 : instead of caller's location and 2 messages which are either a pointer to
2420 : a STRING_CST or class with data () and size () member functions like
2421 : string_view or u8string_view. The first message is a tag, with "" passed
2422 : for no tag, data () should return const char *, the tag should only contain
2423 : alphanumeric letters or underscores. The second message is the diagnostic
2424 : message, data () can be either const char * or const char8_t *. size ()
2425 : should return the corresponding length of the strings in bytes as an
2426 : integer. */
2427 :
2428 : static tree
2429 210 : cxx_eval_constexpr_diag (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
2430 : bool *overflow_p, tree *jump_target)
2431 : {
2432 210 : location_t loc = EXPR_LOCATION (t);
2433 210 : if (call_expr_nargs (t) != 3)
2434 : {
2435 12 : if (!ctx->quiet)
2436 12 : error_at (loc, "wrong number of arguments to %qs call",
2437 : "__builtin_constexpr_diag");
2438 12 : *non_constant_p = true;
2439 12 : return t;
2440 : }
2441 : tree args[3];
2442 792 : for (int i = 0; i < 3; ++i)
2443 : {
2444 594 : tree arg = convert_from_reference (CALL_EXPR_ARG (t, i));
2445 594 : arg = cxx_eval_constant_expression (ctx, arg,
2446 : (i == 0
2447 534 : || POINTER_TYPE_P (TREE_TYPE (arg)))
2448 990 : ? vc_prvalue : vc_glvalue,
2449 : non_constant_p, overflow_p,
2450 : jump_target);
2451 594 : if (*jump_target)
2452 : return NULL_TREE;
2453 594 : if (*non_constant_p)
2454 : return t;
2455 594 : args[i] = arg;
2456 : }
2457 396 : if (TREE_CODE (args[0]) != INTEGER_CST
2458 198 : || wi::to_widest (args[0]) < 0
2459 194 : || wi::to_widest (args[0]) > 18
2460 396 : || (wi::to_widest (args[0]) & 15) > 2)
2461 : {
2462 8 : if (!ctx->quiet)
2463 8 : error_at (loc, "first %qs call argument should be 0, 1, 2, 16, 17 or "
2464 : "18", "__builtin_constexpr_diag");
2465 8 : *non_constant_p = true;
2466 8 : return t;
2467 : }
2468 190 : const char *msgs[2] = {};
2469 190 : int lens[3] = {};
2470 950 : cexpr_str cstrs[2];
2471 478 : diagnostics::kind kind = diagnostics::kind::error;
2472 478 : for (int i = 1; i < 3; ++i)
2473 : {
2474 344 : tree arg = args[i];
2475 344 : if (POINTER_TYPE_P (TREE_TYPE (arg)))
2476 : {
2477 206 : tree str = arg;
2478 206 : STRIP_NOPS (str);
2479 206 : if (TREE_CODE (str) == ADDR_EXPR
2480 206 : && TREE_CODE (TREE_OPERAND (str, 0)) == STRING_CST)
2481 : {
2482 206 : str = TREE_OPERAND (str, 0);
2483 206 : tree eltype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)));
2484 206 : if (eltype == char_type_node
2485 24 : || (i == 2 && eltype == char8_type_node))
2486 344 : arg = str;
2487 : }
2488 : }
2489 344 : cstrs[i - 1].message = arg;
2490 344 : if (!cstrs[i - 1].type_check (loc, i == 2))
2491 : {
2492 40 : *non_constant_p = true;
2493 40 : return t;
2494 : }
2495 304 : if (!cstrs[i - 1].extract (loc, msgs[i - 1], lens[i - 1], ctx,
2496 : non_constant_p, overflow_p, jump_target))
2497 : {
2498 16 : if (*jump_target)
2499 : return NULL_TREE;
2500 16 : *non_constant_p = true;
2501 16 : return t;
2502 : }
2503 : }
2504 134 : if (msgs[0])
2505 : {
2506 726 : for (int i = 0; i < lens[0]; ++i)
2507 596 : if (!ISALNUM (msgs[0][i]) && msgs[0][i] != '_')
2508 : {
2509 4 : if (!ctx->quiet)
2510 4 : error_at (loc, "%qs tag string contains %qc character other than"
2511 : " letters, digits or %<_%>",
2512 : "__builtin_constexpr_diag", msgs[0][i]);
2513 4 : *non_constant_p = true;
2514 4 : return t;
2515 : }
2516 : }
2517 130 : if (ctx->manifestly_const_eval == mce_unknown)
2518 : {
2519 0 : *non_constant_p = true;
2520 0 : return t;
2521 : }
2522 130 : int arg0 = tree_to_uhwi (args[0]);
2523 130 : if (arg0 & 16)
2524 : {
2525 32 : arg0 &= 15;
2526 32 : if (!call_stack.is_empty ())
2527 : {
2528 32 : tree call = call_stack.last ();
2529 32 : if (EXPR_HAS_LOCATION (call))
2530 32 : loc = EXPR_LOCATION (call);
2531 : }
2532 : }
2533 130 : if (arg0 == 0)
2534 : kind = diagnostics::kind::note;
2535 82 : else if (arg0 == 1)
2536 36 : kind = diagnostics::kind::warning;
2537 130 : if (lens[0])
2538 : {
2539 88 : const char *color = "error";
2540 88 : if (kind == diagnostics::kind::note)
2541 : color = "note";
2542 60 : else if (kind == diagnostics::kind::warning)
2543 32 : color = "warning";
2544 88 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s [%r%.*s%R]",
2545 : lens[1], msgs[1], color, lens[0], msgs[0]);
2546 : }
2547 : else
2548 42 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s",
2549 : lens[1], msgs[1]);
2550 130 : return void_node;
2551 570 : }
2552 :
2553 : static tree eval_and_check_array_index (const constexpr_ctx *, tree, bool,
2554 : bool *, bool *, tree *);
2555 :
2556 : /* Helper function for cxx_eval_is_within_lifetime and
2557 : cxx_eval_start_lifetime. Check if ARG is within lifetime. */
2558 :
2559 : static tree
2560 5078 : is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun,
2561 : tree arg, bool *non_constant_p, bool *overflow_p,
2562 : tree *jump_target)
2563 : {
2564 5078 : auto_vec <tree, 4> refs;
2565 5078 : tree obj;
2566 12113 : for (obj = arg; ; obj = TREE_OPERAND (obj, 0))
2567 : {
2568 12113 : switch (TREE_CODE (obj))
2569 : {
2570 7035 : case COMPONENT_REF:
2571 7035 : case ARRAY_REF:
2572 7035 : case REALPART_EXPR:
2573 7035 : case IMAGPART_EXPR:
2574 7035 : refs.safe_push (obj);
2575 7035 : continue;
2576 5078 : default:
2577 5078 : break;
2578 : }
2579 5078 : break;
2580 : }
2581 5078 : tree *valp = nullptr;
2582 5078 : bool check_mutable = false;
2583 5078 : if (DECL_P (obj))
2584 : {
2585 5036 : valp = ctx->global->get_raw_value_ptr (obj);
2586 5036 : if (!valp
2587 1162 : && VAR_P (obj)
2588 1162 : && TREE_STATIC (obj)
2589 5458 : && decl_constant_var_p (obj))
2590 : {
2591 410 : valp = &DECL_INITIAL (obj);
2592 410 : check_mutable = true;
2593 : }
2594 : }
2595 5036 : if (!valp || *valp == void_list_node)
2596 : {
2597 980 : if (!ctx->quiet)
2598 : {
2599 57 : auto_diagnostic_group d;
2600 57 : if (DECL_P (obj) && DECL_NAME (obj) == heap_deleted_identifier)
2601 : {
2602 3 : error_at (loc, "%qE on allocated storage after deallocation "
2603 3 : "is not a constant expression", DECL_NAME (fun));
2604 3 : inform (DECL_SOURCE_LOCATION (obj), "allocated here");
2605 : }
2606 54 : else if (DECL_P (obj) && ctx->global->is_outside_lifetime (obj))
2607 : {
2608 45 : error_at (loc, "%qE on %qE after its storage has been released "
2609 45 : "is not a constant expression", DECL_NAME (fun), obj);
2610 45 : inform (DECL_SOURCE_LOCATION (obj), "declared here");
2611 : }
2612 : else
2613 9 : error_at (loc, "%qE on %qE from outside current evaluation "
2614 9 : "is not a constant expression", DECL_NAME (fun), obj);
2615 57 : }
2616 980 : *non_constant_p = true;
2617 980 : return t;
2618 : }
2619 4098 : tree val = *valp;
2620 4098 : if (val == void_node)
2621 15 : return boolean_false_node;
2622 4083 : unsigned i;
2623 4083 : tree ref;
2624 : /* Magic value used for val when inside the following loop when
2625 : inside of an omitted part of initializer due to it being
2626 : uninitialized. In this case return boolean_true_node unless
2627 : there is some union member access, in unitialized union
2628 : no member is within lifetime. */
2629 4083 : const tree val_uninit = global_namespace;
2630 : /* Magic value used for val when inside the following loop when
2631 : inside of an omitted part of initializer due to it being
2632 : zero initialized. In this case return boolean_true_node unless
2633 : there is some union member access except for the first member. */
2634 4083 : const tree val_zero_init = std_node;
2635 4083 : if (val == NULL_TREE)
2636 141 : val = val_uninit;
2637 12571 : FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
2638 5193 : switch (TREE_CODE (ref))
2639 : {
2640 18 : case REALPART_EXPR:
2641 18 : case IMAGPART_EXPR:
2642 18 : if (TREE_CODE (val) == COMPLEX_EXPR
2643 18 : && (TREE_OPERAND (val, TREE_CODE (ref) == IMAGPART_EXPR)
2644 12 : == void_node))
2645 6 : return boolean_false_node;
2646 12 : return boolean_true_node;
2647 4151 : case COMPONENT_REF:
2648 4151 : if (check_mutable && DECL_MUTABLE_P (TREE_OPERAND (ref, 1)))
2649 : {
2650 12 : if (!ctx->quiet)
2651 3 : error_at (loc, "%qE on %<mutable%> sub-object %qD",
2652 3 : DECL_NAME (fun), TREE_OPERAND (ref, 1));
2653 12 : *non_constant_p = true;
2654 12 : return t;
2655 : }
2656 4139 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
2657 : {
2658 1280 : tree union_type = TREE_TYPE (TREE_OPERAND (ref, 0));
2659 1280 : if (val == val_zero_init)
2660 : {
2661 48 : if (TREE_OPERAND (ref, 1)
2662 24 : != next_aggregate_field (TYPE_FIELDS (union_type)))
2663 15 : return boolean_false_node;
2664 9 : continue;
2665 : }
2666 1256 : else if (val == val_uninit)
2667 102 : return boolean_false_node;
2668 1154 : else if (val == error_mark_node)
2669 : return val;
2670 : else
2671 : {
2672 1154 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2673 1154 : if (CONSTRUCTOR_NELTS (val) == 0)
2674 : {
2675 147 : if (CONSTRUCTOR_NO_CLEARING (val))
2676 135 : return boolean_false_node;
2677 12 : tree first
2678 12 : = next_aggregate_field (TYPE_FIELDS (union_type));
2679 12 : if (first != TREE_OPERAND (ref, 1))
2680 3 : return boolean_false_node;
2681 9 : val = val_zero_init;
2682 9 : continue;
2683 9 : }
2684 : else
2685 : {
2686 1007 : if (CONSTRUCTOR_ELT (val, 0)->index
2687 1007 : != TREE_OPERAND (ref, 1))
2688 287 : return boolean_false_node;
2689 720 : val = CONSTRUCTOR_ELT (val, 0)->value;
2690 720 : if (val == void_node)
2691 0 : return boolean_false_node;
2692 720 : continue;
2693 : }
2694 : }
2695 : }
2696 2859 : if (val == val_zero_init || val == val_uninit)
2697 80 : continue;
2698 2779 : if (val == error_mark_node)
2699 : return val;
2700 2767 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2701 : unsigned int j;
2702 : tree field, value;
2703 4202 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (val), j, field, value)
2704 2628 : if (field == TREE_OPERAND (ref, 1))
2705 : {
2706 1193 : if (value == void_node)
2707 6 : return boolean_false_node;
2708 : val = value;
2709 : ref = NULL_TREE;
2710 : break;
2711 : }
2712 2761 : if (ref == NULL_TREE)
2713 1187 : continue;
2714 1574 : if (CONSTRUCTOR_NO_CLEARING (val))
2715 : {
2716 1457 : if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
2717 75 : return boolean_false_node;
2718 : val = val_uninit;
2719 : }
2720 : else
2721 : val = val_zero_init;
2722 1499 : continue;
2723 1024 : case ARRAY_REF:
2724 1024 : field = eval_and_check_array_index (ctx, ref, false,
2725 : non_constant_p, overflow_p,
2726 : jump_target);
2727 1024 : if (*jump_target)
2728 : return NULL_TREE;
2729 1024 : if (*non_constant_p)
2730 : return t;
2731 1012 : if (val == val_zero_init || val == val_uninit)
2732 33 : continue;
2733 979 : if (val == error_mark_node)
2734 : return val;
2735 979 : if (TREE_CODE (val) == STRING_CST)
2736 0 : return boolean_true_node;
2737 979 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2738 979 : HOST_WIDE_INT idx;
2739 979 : idx = find_array_ctor_elt (val, field, false);
2740 979 : if (idx != -1)
2741 : {
2742 595 : val = CONSTRUCTOR_ELT (val, idx)->value;
2743 595 : if (val == void_node)
2744 72 : return boolean_false_node;
2745 523 : continue;
2746 : }
2747 384 : if (CONSTRUCTOR_NO_CLEARING (val))
2748 : {
2749 159 : if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
2750 39 : return boolean_false_node;
2751 : val = val_uninit;
2752 : }
2753 : else
2754 : val = val_zero_init;
2755 345 : continue;
2756 0 : default:
2757 0 : gcc_unreachable ();
2758 1844 : }
2759 3295 : return boolean_true_node;
2760 5078 : }
2761 :
2762 : /* Attempt to evaluate T which represents a call to
2763 : __builtin_is_within_lifetime. */
2764 :
2765 : static tree
2766 3952 : cxx_eval_is_within_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
2767 : bool *non_constant_p, bool *overflow_p,
2768 : tree *jump_target)
2769 : {
2770 3952 : location_t loc = EXPR_LOCATION (t);
2771 3952 : tree arg = CALL_EXPR_ARG (t, 0);
2772 3952 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2773 : non_constant_p, overflow_p,
2774 : jump_target);
2775 3952 : if (*jump_target)
2776 : return NULL_TREE;
2777 3952 : if (*non_constant_p)
2778 : return t;
2779 : /* Need to strip casts to pointers to void, but should preserve
2780 : pointer casts within the innermost pointer to void cast if
2781 : any, so that e.g. pointers to heap allocations are handled
2782 : correctly. */
2783 : tree p = arg;
2784 6290 : while (CONVERT_EXPR_P (p) || TREE_CODE (p) == NON_LVALUE_EXPR)
2785 : {
2786 2754 : if (!TYPE_PTR_P (TREE_TYPE (p)))
2787 : break;
2788 2754 : if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (p))))
2789 174 : arg = TREE_OPERAND (p, 0);
2790 2754 : p = TREE_OPERAND (p, 0);
2791 : }
2792 3536 : if (integer_zerop (arg))
2793 : {
2794 24 : if (!ctx->quiet)
2795 6 : error_at (loc, "%qE called with a null pointer",
2796 6 : DECL_NAME (fun));
2797 24 : *non_constant_p = true;
2798 24 : return t;
2799 : }
2800 3512 : if (POINTER_TYPE_P (TREE_TYPE (arg))
2801 3512 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == FUNCTION_TYPE
2802 3491 : || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == METHOD_TYPE))
2803 : {
2804 21 : if (!ctx->quiet)
2805 6 : error_at (loc, "%qE called with pointer to function",
2806 6 : DECL_NAME (fun));
2807 21 : *non_constant_p = true;
2808 21 : return t;
2809 : }
2810 3491 : arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
2811 3491 : arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
2812 : non_constant_p, overflow_p,
2813 : jump_target);
2814 3491 : if (*jump_target)
2815 : return NULL_TREE;
2816 3491 : if (*non_constant_p)
2817 : return t;
2818 3491 : return is_within_lifetime (loc, ctx, t, fun, arg,
2819 3491 : non_constant_p, overflow_p, jump_target);
2820 : }
2821 :
2822 : static tree cxx_eval_store_expression (const constexpr_ctx *, tree,
2823 : value_cat, bool *, bool *,
2824 : tree *);
2825 :
2826 : /* Attempt to evaluate T which represents a call to
2827 : __builtin_start_lifetime. */
2828 :
2829 : static tree
2830 1593 : cxx_eval_start_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
2831 : bool *non_constant_p, bool *overflow_p,
2832 : tree *jump_target)
2833 : {
2834 1593 : location_t loc = EXPR_LOCATION (t);
2835 1593 : tree arg = CALL_EXPR_ARG (t, 0), within_lifetime;
2836 1593 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2837 : non_constant_p, overflow_p,
2838 : jump_target);
2839 1593 : if (*jump_target)
2840 : return NULL_TREE;
2841 1593 : if (*non_constant_p)
2842 : return t;
2843 1593 : arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
2844 1593 : arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
2845 : non_constant_p, overflow_p,
2846 : jump_target);
2847 1593 : if (*jump_target)
2848 : return NULL_TREE;
2849 1593 : if (*non_constant_p)
2850 : return t;
2851 1593 : switch (TREE_CODE (arg))
2852 : {
2853 1587 : case COMPONENT_REF:
2854 1587 : case ARRAY_REF:
2855 1587 : case REALPART_EXPR:
2856 1587 : case IMAGPART_EXPR:
2857 1587 : within_lifetime
2858 1587 : = is_within_lifetime (loc, ctx, t, fun, TREE_OPERAND (arg, 0),
2859 : non_constant_p, overflow_p, jump_target);
2860 1587 : if (*jump_target)
2861 : return NULL_TREE;
2862 1587 : if (*non_constant_p)
2863 : return t;
2864 1587 : if (within_lifetime != boolean_true_node)
2865 : {
2866 90 : if (!ctx->quiet)
2867 30 : error_at (loc, "%qE with containing object not within lifetime",
2868 30 : DECL_NAME (fun));
2869 90 : *non_constant_p = true;
2870 90 : return t;
2871 : }
2872 : break;
2873 : default:
2874 : break;
2875 : }
2876 1503 : tree ctor = build_constructor (TREE_TYPE (arg), NULL);
2877 1503 : CONSTRUCTOR_NO_CLEARING (ctor) = 1;
2878 1503 : CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
2879 1503 : tree modopexpr
2880 1503 : = build3_loc (loc, MODOP_EXPR, TREE_TYPE (arg), arg, ctor, NULL_TREE);
2881 1503 : arg = cxx_eval_store_expression (ctx, modopexpr, vc_discard, non_constant_p,
2882 : overflow_p, jump_target);
2883 1503 : ggc_free (modopexpr);
2884 1503 : if (*jump_target)
2885 : return NULL_TREE;
2886 1503 : if (*non_constant_p)
2887 : return t;
2888 1499 : return void_node;
2889 : }
2890 :
2891 : /* Attempt to evaluate T which represents a call to a builtin function.
2892 : We assume here that all builtin functions evaluate to scalar types
2893 : represented by _CST nodes. */
2894 :
2895 : static tree
2896 20768459 : cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
2897 : value_cat lval,
2898 : bool *non_constant_p, bool *overflow_p,
2899 : tree *jump_target)
2900 : {
2901 20768459 : const int nargs = call_expr_nargs (t);
2902 20768459 : tree *args = (tree *) alloca (nargs * sizeof (tree));
2903 20768459 : tree new_call;
2904 20768459 : int i;
2905 :
2906 : /* Don't fold __builtin_constant_p within a constexpr function. */
2907 20768459 : bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
2908 :
2909 : /* If we aren't requiring a constant expression, defer __builtin_constant_p
2910 : in a constexpr function until we have values for the parameters. */
2911 3571814 : if (bi_const_p
2912 3571814 : && ctx->manifestly_const_eval != mce_true
2913 1753666 : && current_function_decl
2914 1752537 : && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2915 : {
2916 1400126 : *non_constant_p = true;
2917 1400126 : return t;
2918 : }
2919 :
2920 19368333 : if (fndecl_built_in_p (fun, BUILT_IN_FRONTEND))
2921 4006207 : switch (DECL_FE_FUNCTION_CODE (fun))
2922 : {
2923 3982008 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
2924 : /* For __builtin_is_constant_evaluated, defer it if not
2925 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
2926 : without manifestly_const_eval even expressions or parts thereof
2927 : which will later be manifestly const_eval evaluated), otherwise fold
2928 : it to true. */
2929 3982008 : if (ctx->manifestly_const_eval == mce_unknown)
2930 : {
2931 3933781 : *non_constant_p = true;
2932 3933781 : return t;
2933 : }
2934 48227 : return constant_boolean_node (ctx->manifestly_const_eval == mce_true,
2935 48227 : boolean_type_node);
2936 :
2937 10925 : case CP_BUILT_IN_SOURCE_LOCATION:
2938 10925 : {
2939 10925 : temp_override<tree> ovr (current_function_decl);
2940 10925 : if (ctx->call && ctx->call->fundef)
2941 2753 : current_function_decl = ctx->call->fundef->decl;
2942 10925 : return fold_builtin_source_location (t);
2943 10925 : }
2944 :
2945 126 : case CP_BUILT_IN_EH_PTR_ADJUST_REF:
2946 126 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_EH_PTR_ADJUST_REF,
2947 : fun, non_constant_p, overflow_p,
2948 126 : jump_target);
2949 :
2950 2208 : case CP_BUILT_IN_CURRENT_EXCEPTION:
2951 2208 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_CURRENT_EXCEPTION,
2952 : fun, non_constant_p, overflow_p,
2953 2208 : jump_target);
2954 :
2955 82 : case CP_BUILT_IN_UNCAUGHT_EXCEPTIONS:
2956 82 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_UNCAUGHT_EXCEPTIONS,
2957 : fun, non_constant_p, overflow_p,
2958 82 : jump_target);
2959 :
2960 210 : case CP_BUILT_IN_CONSTEXPR_DIAG:
2961 210 : return cxx_eval_constexpr_diag (ctx, t, non_constant_p, overflow_p,
2962 210 : jump_target);
2963 :
2964 3952 : case CP_BUILT_IN_IS_WITHIN_LIFETIME:
2965 3952 : return cxx_eval_is_within_lifetime (ctx, t, fun, non_constant_p,
2966 3952 : overflow_p, jump_target);
2967 :
2968 1593 : case CP_BUILT_IN_START_LIFETIME:
2969 1593 : return cxx_eval_start_lifetime (ctx, t, fun, non_constant_p,
2970 1593 : overflow_p, jump_target);
2971 :
2972 : default:
2973 : break;
2974 : }
2975 :
2976 15367229 : int strops = 0;
2977 15367229 : int strret = 0;
2978 15367229 : bool bos = false;
2979 15367229 : if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
2980 14019951 : switch (DECL_FUNCTION_CODE (fun))
2981 : {
2982 : case BUILT_IN_STRLEN:
2983 : case BUILT_IN_STRNLEN:
2984 15367078 : strops = 1;
2985 : break;
2986 201561 : case BUILT_IN_MEMCHR:
2987 201561 : case BUILT_IN_STRCHR:
2988 201561 : case BUILT_IN_STRRCHR:
2989 201561 : strops = 1;
2990 201561 : strret = 1;
2991 201561 : break;
2992 112734 : case BUILT_IN_MEMCMP:
2993 112734 : case BUILT_IN_STRCMP:
2994 112734 : strops = 2;
2995 112734 : break;
2996 49991 : case BUILT_IN_STRSTR:
2997 49991 : strops = 2;
2998 49991 : strret = 1;
2999 49991 : break;
3000 66 : case BUILT_IN_ASAN_POINTER_COMPARE:
3001 66 : case BUILT_IN_ASAN_POINTER_SUBTRACT:
3002 66 : case BUILT_IN_OBSERVABLE_CHKPT:
3003 : /* These builtins shall be ignored during constant expression
3004 : evaluation. */
3005 66 : return void_node;
3006 85 : case BUILT_IN_UNREACHABLE:
3007 85 : case BUILT_IN_TRAP:
3008 85 : if (!*non_constant_p && !ctx->quiet)
3009 : {
3010 : /* Do not allow__builtin_unreachable in constexpr function.
3011 : The __builtin_unreachable call with BUILTINS_LOCATION
3012 : comes from cp_maybe_instrument_return. */
3013 25 : if (EXPR_LOCATION (t) == BUILTINS_LOCATION)
3014 0 : error ("%<constexpr%> call flows off the end of the function");
3015 : else
3016 25 : error ("%q+E is not a constant expression", t);
3017 : }
3018 85 : *non_constant_p = true;
3019 85 : return t;
3020 2881 : case BUILT_IN_OBJECT_SIZE:
3021 2881 : case BUILT_IN_DYNAMIC_OBJECT_SIZE:
3022 2881 : bos = ctx->manifestly_const_eval == mce_true;
3023 2881 : break;
3024 : default:
3025 : break;
3026 : }
3027 :
3028 : /* Be permissive for arguments to built-ins; __builtin_constant_p should
3029 : return constant false for a non-constant argument. */
3030 15367078 : constexpr_ctx new_ctx = *ctx;
3031 15367078 : new_ctx.quiet = true;
3032 41755644 : for (i = 0; i < nargs; ++i)
3033 : {
3034 26388568 : tree arg = CALL_EXPR_ARG (t, i);
3035 26388568 : tree oarg = arg;
3036 :
3037 : /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
3038 : expand_builtin doesn't know how to look in the values table. */
3039 26388568 : bool strop = i < strops;
3040 26388568 : if (strop)
3041 : {
3042 689727 : STRIP_NOPS (arg);
3043 689727 : if (TREE_CODE (arg) == ADDR_EXPR)
3044 8231 : arg = TREE_OPERAND (arg, 0);
3045 : else
3046 : strop = false;
3047 : }
3048 :
3049 : /* If builtin_valid_in_constant_expr_p is true,
3050 : potential_constant_expression_1 has not recursed into the arguments
3051 : of the builtin, verify it here. */
3052 26388568 : if (!builtin_valid_in_constant_expr_p (fun)
3053 26388568 : || potential_constant_expression (arg))
3054 : {
3055 26388431 : bool dummy1 = false, dummy2 = false;
3056 26388431 : tree jmp_target = NULL_TREE;
3057 26388431 : arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3058 : &dummy1, &dummy2, &jmp_target);
3059 26388429 : if (jmp_target)
3060 : {
3061 0 : *jump_target = jmp_target;
3062 0 : return NULL_TREE;
3063 : }
3064 : }
3065 :
3066 26388566 : if (bi_const_p)
3067 : /* For __builtin_constant_p, fold all expressions with constant values
3068 : even if they aren't C++ constant-expressions. */
3069 2171686 : arg = cp_fold_rvalue (arg);
3070 24216880 : else if (strop)
3071 : {
3072 8231 : if (TREE_CODE (arg) == CONSTRUCTOR)
3073 76 : arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
3074 8231 : if (TREE_CODE (arg) == STRING_CST)
3075 3073 : arg = build_address (arg);
3076 : else
3077 : arg = oarg;
3078 : }
3079 :
3080 : /* If the argument STRRET refers to didn't end up as the address of a
3081 : STRING_CST, the folded result is already relative to it and must not
3082 : be re-based on the original argument below. */
3083 26388566 : if (i == strret - 1
3084 26388566 : && (TREE_CODE (arg) != ADDR_EXPR
3085 110 : || TREE_CODE (TREE_OPERAND (arg, 0)) != STRING_CST))
3086 : strret = 0;
3087 :
3088 26388566 : args[i] = arg;
3089 : }
3090 15367076 : if (bos)
3091 : {
3092 102 : tree arg = args[0];
3093 102 : STRIP_NOPS (arg);
3094 102 : if (TREE_CODE (arg) == ADDR_EXPR)
3095 102 : args[0] = arg;
3096 : }
3097 :
3098 15367076 : bool save_ffbcp = force_folding_builtin_constant_p;
3099 15367076 : force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true;
3100 15367076 : tree save_cur_fn = current_function_decl;
3101 : /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */
3102 15367076 : if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION)
3103 37 : && ctx->call
3104 15367080 : && ctx->call->fundef)
3105 4 : current_function_decl = ctx->call->fundef->decl;
3106 15367076 : if (fndecl_built_in_p (fun,
3107 : CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
3108 : BUILT_IN_FRONTEND))
3109 : {
3110 336 : location_t loc = EXPR_LOCATION (t);
3111 336 : if (nargs >= 1)
3112 333 : VERIFY_CONSTANT (args[0]);
3113 136 : new_call
3114 136 : = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
3115 : args);
3116 : }
3117 15366740 : else if (fndecl_built_in_p (fun,
3118 : CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
3119 : BUILT_IN_FRONTEND))
3120 : {
3121 471 : location_t loc = EXPR_LOCATION (t);
3122 471 : if (nargs >= 2)
3123 : {
3124 465 : VERIFY_CONSTANT (args[0]);
3125 237 : VERIFY_CONSTANT (args[1]);
3126 : }
3127 243 : new_call = fold_builtin_is_corresponding_member (loc, nargs, args);
3128 : }
3129 15366269 : else if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_STRING_LITERAL,
3130 : BUILT_IN_FRONTEND))
3131 : {
3132 4296 : location_t loc = EXPR_LOCATION (t);
3133 4296 : if (nargs >= 1)
3134 : {
3135 4296 : tree arg = CALL_EXPR_ARG (t, 0);
3136 4296 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3137 : non_constant_p, overflow_p,
3138 : jump_target);
3139 4296 : if (*jump_target)
3140 : return NULL_TREE;
3141 4296 : args[0] = arg;
3142 : }
3143 4296 : new_call = fold_builtin_is_string_literal (loc, nargs, args);
3144 : }
3145 : else
3146 30723946 : new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
3147 15361973 : CALL_EXPR_FN (t), nargs, args);
3148 15366648 : current_function_decl = save_cur_fn;
3149 15366648 : force_folding_builtin_constant_p = save_ffbcp;
3150 15366648 : if (new_call == NULL)
3151 : {
3152 10456614 : if (!*non_constant_p && !ctx->quiet)
3153 : {
3154 0 : new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
3155 0 : CALL_EXPR_FN (t), nargs, args);
3156 0 : error ("%q+E is not a constant expression", new_call);
3157 : }
3158 10456614 : *non_constant_p = true;
3159 10456614 : return t;
3160 : }
3161 :
3162 4910034 : if (!potential_constant_expression (new_call))
3163 : {
3164 861 : if (!*non_constant_p && !ctx->quiet)
3165 4 : error ("%q+E is not a constant expression", new_call);
3166 861 : *non_constant_p = true;
3167 861 : return t;
3168 : }
3169 :
3170 4909173 : if (strret)
3171 : {
3172 : /* memchr returns a pointer into the first argument, but we replaced the
3173 : argument above with a STRING_CST; put it back it now. */
3174 18 : tree op = CALL_EXPR_ARG (t, strret-1);
3175 18 : STRIP_NOPS (new_call);
3176 18 : if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
3177 15 : TREE_OPERAND (new_call, 0) = op;
3178 3 : else if (TREE_CODE (new_call) == ADDR_EXPR)
3179 4909173 : new_call = op;
3180 : }
3181 :
3182 4909173 : return cxx_eval_constant_expression (&new_ctx, new_call, lval,
3183 : non_constant_p, overflow_p,
3184 4909173 : jump_target);
3185 : }
3186 :
3187 : /* TEMP is the constant value of a temporary object of type TYPE. Adjust
3188 : the type of the value to match. */
3189 :
3190 : static tree
3191 137068002 : adjust_temp_type (tree type, tree temp)
3192 : {
3193 137068002 : if (same_type_p (TREE_TYPE (temp), type))
3194 : return temp;
3195 : /* Avoid wrapping an aggregate value in a NOP_EXPR. */
3196 63310767 : if (TREE_CODE (temp) == CONSTRUCTOR)
3197 : {
3198 : /* build_constructor wouldn't retain various CONSTRUCTOR flags. */
3199 3820444 : tree t = copy_node (temp);
3200 3820444 : TREE_TYPE (t) = type;
3201 3820444 : return t;
3202 : }
3203 59490323 : if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
3204 0 : return build0 (EMPTY_CLASS_EXPR, type);
3205 59490323 : gcc_assert (scalarish_type_p (type));
3206 : /* Now we know we're dealing with a scalar, and a prvalue of non-class
3207 : type is cv-unqualified. */
3208 59490323 : return cp_fold_convert (cv_unqualified (type), temp);
3209 : }
3210 :
3211 : /* If T is a CONSTRUCTOR, return an unshared copy of T and any
3212 : sub-CONSTRUCTORs. Otherwise return T.
3213 :
3214 : We use this whenever we initialize an object as a whole, whether it's a
3215 : parameter, a local variable, or a subobject, so that subsequent
3216 : modifications don't affect other places where it was used. */
3217 :
3218 : tree
3219 124120749 : unshare_constructor (tree t MEM_STAT_DECL)
3220 : {
3221 124120749 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
3222 : return t;
3223 18642314 : auto_vec <tree*, 4> ptrs;
3224 18642314 : ptrs.safe_push (&t);
3225 18642314 : while (!ptrs.is_empty ())
3226 : {
3227 24524602 : tree *p = ptrs.pop ();
3228 24524602 : tree n = copy_node (*p PASS_MEM_STAT);
3229 40689550 : CONSTRUCTOR_ELTS (n) = vec_safe_copy (CONSTRUCTOR_ELTS (*p) PASS_MEM_STAT);
3230 24524602 : *p = n;
3231 24524602 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n);
3232 24524602 : constructor_elt *ce;
3233 94209053 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i)
3234 : {
3235 26517535 : if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
3236 780 : ce->index = copy_node (ce->index PASS_MEM_STAT);
3237 26517535 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
3238 5882288 : ptrs.safe_push (&ce->value);
3239 : }
3240 : }
3241 18642314 : return t;
3242 18642314 : }
3243 :
3244 : /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs. */
3245 :
3246 : static void
3247 883018 : free_constructor (tree t)
3248 : {
3249 883018 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
3250 0 : return;
3251 883018 : releasing_vec ctors;
3252 883018 : vec_safe_push (ctors, t);
3253 2688261 : while (!ctors->is_empty ())
3254 : {
3255 922225 : tree c = ctors->pop ();
3256 922225 : if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c))
3257 : {
3258 : constructor_elt *ce;
3259 394174 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
3260 255231 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
3261 39207 : vec_safe_push (ctors, ce->value);
3262 138943 : ggc_free (elts);
3263 : }
3264 922225 : ggc_free (c);
3265 : }
3266 883018 : }
3267 :
3268 : /* Helper function of cxx_bind_parameters_in_call. Return non-NULL
3269 : if *TP is address of a static variable (or part of it) currently being
3270 : constructed or of a heap artificial variable. */
3271 :
3272 : static tree
3273 49002825 : addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data)
3274 : {
3275 49002825 : if (TREE_CODE (*tp) == ADDR_EXPR)
3276 9085599 : if (tree var = get_base_address (TREE_OPERAND (*tp, 0)))
3277 9085599 : if (VAR_P (var) && TREE_STATIC (var))
3278 : {
3279 5680089 : if (DECL_NAME (var) == heap_uninit_identifier
3280 5680089 : || DECL_NAME (var) == heap_identifier
3281 5680089 : || DECL_NAME (var) == heap_vec_uninit_identifier
3282 11360178 : || DECL_NAME (var) == heap_vec_identifier)
3283 : return var;
3284 :
3285 5680089 : constexpr_global_ctx *global = (constexpr_global_ctx *) data;
3286 5680089 : if (global->get_value (var))
3287 : return var;
3288 : }
3289 48555096 : if (TYPE_P (*tp))
3290 2503 : *walk_subtrees = false;
3291 : return NULL_TREE;
3292 : }
3293 :
3294 : /* Subroutine of cxx_eval_call_expression.
3295 : We are processing a call expression (either CALL_EXPR or
3296 : AGGR_INIT_EXPR) in the context of CTX. Evaluate
3297 : all arguments and bind their values to correspondings
3298 : parameters, making up the NEW_CALL context. */
3299 :
3300 : static tree
3301 185184767 : cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
3302 : tree orig_fun, bool *non_constant_p,
3303 : bool *overflow_p, bool *non_constant_args,
3304 : tree *jump_target)
3305 : {
3306 185184767 : int nargs = call_expr_nargs (t);
3307 185184767 : tree parms = DECL_ARGUMENTS (fun);
3308 185184767 : int i, j = 0;
3309 185184767 : if (DECL_HAS_IN_CHARGE_PARM_P (fun) && fun != orig_fun)
3310 1523 : ++nargs;
3311 185184767 : if (DECL_HAS_VTT_PARM_P (fun)
3312 1525 : && fun != orig_fun
3313 185186290 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3314 1082 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
3315 463 : ++nargs;
3316 : /* We don't record ellipsis args below. */
3317 185184767 : int nparms = list_length (parms);
3318 185184767 : int nbinds = nargs < nparms ? nargs : nparms;
3319 185184767 : tree binds = make_tree_vec (nbinds);
3320 :
3321 : /* The call is not a constant expression if it involves the cdtor for a type
3322 : with virtual bases before C++26. */
3323 185184767 : if (cxx_dialect < cxx26
3324 185184767 : && (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun)))
3325 : {
3326 17 : if (!ctx->quiet)
3327 : {
3328 3 : error_at (cp_expr_loc_or_input_loc (t),
3329 : "call to non-%<constexpr%> function %qD", fun);
3330 3 : explain_invalid_constexpr_fn (fun);
3331 : }
3332 17 : *non_constant_p = true;
3333 17 : return binds;
3334 : }
3335 :
3336 333295195 : for (i = 0; i < nargs; ++i)
3337 : {
3338 222622967 : tree x, arg;
3339 222622967 : tree type = parms ? TREE_TYPE (parms) : void_type_node;
3340 222622967 : if (parms && DECL_BY_REFERENCE (parms))
3341 27167 : type = TREE_TYPE (type);
3342 222622967 : if (i == 1
3343 222622967 : && j == 0
3344 47717799 : && DECL_HAS_IN_CHARGE_PARM_P (fun)
3345 222624358 : && orig_fun != fun)
3346 : {
3347 1391 : if (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3348 1391 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))
3349 428 : x = boolean_true_node;
3350 : else
3351 963 : x = boolean_false_node;
3352 : j = -1;
3353 : }
3354 222621576 : else if (i == 2
3355 222621576 : && j == -1
3356 1391 : && DECL_HAS_VTT_PARM_P (fun)
3357 1391 : && orig_fun != fun
3358 222622967 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3359 985 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
3360 : {
3361 428 : x = build_zero_cst (type);
3362 428 : j = -2;
3363 : }
3364 : else
3365 222621148 : x = get_nth_callarg (t, i + j);
3366 : /* For member function, the first argument is a pointer to the implied
3367 : object. For a constructor, it might still be a dummy object, in
3368 : which case we get the real argument from ctx. */
3369 326365442 : if (i == 0 && DECL_CONSTRUCTOR_P (fun)
3370 245749705 : && is_dummy_object (x))
3371 : {
3372 11846316 : x = ctx->object;
3373 11846316 : x = build_address (x);
3374 : }
3375 222622967 : if (TREE_ADDRESSABLE (type))
3376 : {
3377 : /* Undo convert_for_arg_passing work here. */
3378 39225 : x = convert_from_reference (x);
3379 39225 : arg = cxx_eval_constant_expression (ctx, x, vc_glvalue,
3380 : non_constant_p, overflow_p,
3381 : jump_target);
3382 : }
3383 : else
3384 : /* Normally we would strip a TARGET_EXPR in an initialization context
3385 : such as this, but here we do the elision differently: we keep the
3386 : TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */
3387 222583742 : arg = cxx_eval_constant_expression (ctx, x, vc_prvalue,
3388 : non_constant_p, overflow_p,
3389 : jump_target);
3390 222622967 : if (*jump_target)
3391 : break;
3392 : /* Check we aren't dereferencing a null pointer when calling a non-static
3393 : member function, which is undefined behaviour. */
3394 163182666 : if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun)
3395 92860452 : && integer_zerop (arg)
3396 : /* But ignore calls from within compiler-generated code, to handle
3397 : cases like lambda function pointer conversion operator thunks
3398 : which pass NULL as the 'this' pointer. */
3399 222797800 : && !(TREE_CODE (t) == CALL_EXPR && CALL_FROM_THUNK_P (t)))
3400 : {
3401 527 : if (!ctx->quiet)
3402 6 : error_at (cp_expr_loc_or_input_loc (x),
3403 : "dereferencing a null pointer");
3404 527 : *non_constant_p = true;
3405 : }
3406 : /* Don't VERIFY_CONSTANT here. */
3407 222622883 : if (*non_constant_p && ctx->quiet)
3408 : break;
3409 : /* Just discard ellipsis args after checking their constantitude. */
3410 148110445 : if (!parms)
3411 360 : continue;
3412 :
3413 148110085 : if (!*non_constant_p)
3414 : {
3415 : /* Make sure the binding has the same type as the parm. But
3416 : only for constant args. */
3417 148109311 : if (TREE_ADDRESSABLE (type))
3418 : {
3419 26088 : if (!same_type_p (type, TREE_TYPE (arg)))
3420 : {
3421 9 : arg = build_fold_addr_expr (arg);
3422 9 : arg = cp_fold_convert (build_reference_type (type), arg);
3423 9 : arg = convert_from_reference (arg);
3424 : }
3425 : }
3426 148083223 : else if (!TYPE_REF_P (type))
3427 105816867 : arg = adjust_temp_type (type, arg);
3428 148109311 : if (!TREE_CONSTANT (arg))
3429 97598861 : *non_constant_args = true;
3430 50510450 : else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
3431 : /* The destructor needs to see any modifications the callee makes
3432 : to the argument. */
3433 0 : *non_constant_args = true;
3434 : /* If arg is or contains address of a heap artificial variable or
3435 : of a static variable being constructed, avoid caching the
3436 : function call, as those variables might be modified by the
3437 : function, or might be modified by the callers in between
3438 : the cached function and just read by the function. */
3439 50510450 : else if (!*non_constant_args
3440 50510450 : && cp_walk_tree (&arg, addr_of_non_const_var, ctx->global,
3441 : NULL))
3442 447729 : *non_constant_args = true;
3443 :
3444 : /* For virtual calls, adjust the this argument, so that it is
3445 : the object on which the method is called, rather than
3446 : one of its bases. */
3447 148109311 : if (i == 0 && DECL_VIRTUAL_P (fun))
3448 : {
3449 27481 : tree addr = arg;
3450 27481 : STRIP_NOPS (addr);
3451 27481 : if (TREE_CODE (addr) == ADDR_EXPR)
3452 : {
3453 27444 : tree obj = TREE_OPERAND (addr, 0);
3454 27444 : while (TREE_CODE (obj) == COMPONENT_REF
3455 11849 : && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))
3456 39371 : && !same_type_ignoring_top_level_qualifiers_p
3457 11756 : (TREE_TYPE (obj), DECL_CONTEXT (fun)))
3458 171 : obj = TREE_OPERAND (obj, 0);
3459 27444 : if (obj != TREE_OPERAND (addr, 0))
3460 168 : arg = build_fold_addr_expr_with_type (obj,
3461 : TREE_TYPE (arg));
3462 : }
3463 : }
3464 148109311 : TREE_VEC_ELT (binds, i) = arg;
3465 : }
3466 148110085 : parms = TREE_CHAIN (parms);
3467 : }
3468 :
3469 : return binds;
3470 : }
3471 :
3472 : static int
3473 110077934 : push_cx_call_context (tree call)
3474 : {
3475 110077934 : ++call_stack_tick;
3476 110077934 : if (!EXPR_HAS_LOCATION (call))
3477 76326 : SET_EXPR_LOCATION (call, input_location);
3478 110077934 : call_stack.safe_push (call);
3479 110077934 : int len = call_stack.length ();
3480 110077934 : if (len > max_constexpr_depth)
3481 33 : return false;
3482 : return len;
3483 : }
3484 :
3485 : static void
3486 110077930 : pop_cx_call_context (void)
3487 : {
3488 110077930 : ++call_stack_tick;
3489 110077930 : call_stack.pop ();
3490 110077930 : }
3491 :
3492 : vec<tree>
3493 259229 : cx_error_context (void)
3494 : {
3495 259229 : vec<tree> r = vNULL;
3496 259229 : if (call_stack_tick != last_cx_error_tick
3497 259229 : && !call_stack.is_empty ())
3498 : r = call_stack;
3499 259229 : last_cx_error_tick = call_stack_tick;
3500 259229 : return r;
3501 : }
3502 :
3503 : /* E is an operand of a failed assertion, fold it either with or without
3504 : constexpr context. */
3505 :
3506 : static tree
3507 829 : fold_operand (tree e, const constexpr_ctx *ctx)
3508 : {
3509 829 : if (ctx)
3510 : {
3511 32 : bool new_non_constant_p = false, new_overflow_p = false;
3512 32 : tree jmp_target = NULL_TREE;
3513 32 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
3514 : &new_non_constant_p,
3515 : &new_overflow_p, &jmp_target);
3516 : }
3517 : else
3518 797 : e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true);
3519 829 : return e;
3520 : }
3521 :
3522 : /* If we have a condition in conjunctive normal form (CNF), find the first
3523 : failing clause. In other words, given an expression like
3524 :
3525 : true && true && false && true && false
3526 :
3527 : return the first 'false'. EXPR is the expression. */
3528 :
3529 : static tree
3530 332 : find_failing_clause_r (const constexpr_ctx *ctx, tree expr)
3531 : {
3532 437 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3533 : {
3534 : /* First check the left side... */
3535 192 : tree e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 0));
3536 192 : if (e == NULL_TREE)
3537 : /* ...if we didn't find a false clause, check the right side. */
3538 105 : e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 1));
3539 : return e;
3540 : }
3541 245 : tree e = contextual_conv_bool (expr, tf_none);
3542 245 : e = fold_operand (e, ctx);
3543 245 : if (integer_zerop (e))
3544 : /* This is the failing clause. */
3545 140 : return expr;
3546 : return NULL_TREE;
3547 : }
3548 :
3549 : /* Wrapper for find_failing_clause_r. */
3550 :
3551 : tree
3552 1984 : find_failing_clause (const constexpr_ctx *ctx, tree expr)
3553 : {
3554 1984 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3555 140 : if (tree e = find_failing_clause_r (ctx, expr))
3556 1984 : expr = e;
3557 1984 : return expr;
3558 : }
3559 :
3560 : /* Emit additional diagnostics for failing condition BAD.
3561 : Used by finish_static_assert and IFN_ASSUME constexpr diagnostics.
3562 : If SHOW_EXPR_P is true, print the condition (because it was
3563 : instantiation-dependent). */
3564 :
3565 : void
3566 1984 : diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p,
3567 : const constexpr_ctx *ctx /* = nullptr */)
3568 : {
3569 : /* Nobody wants to see the artificial (bool) cast. */
3570 1984 : bad = tree_strip_nop_conversions (bad);
3571 1984 : if (TREE_CODE (bad) == CLEANUP_POINT_EXPR)
3572 3 : bad = TREE_OPERAND (bad, 0);
3573 :
3574 1984 : auto_diagnostic_nesting_level sentinel;
3575 :
3576 : /* Actually explain the failure if this is a concept check or a
3577 : requires-expression. */
3578 1984 : if (concept_check_p (bad) || TREE_CODE (bad) == REQUIRES_EXPR)
3579 334 : diagnose_constraints (cloc, bad, NULL_TREE);
3580 : /* Similarly if this is a standard trait. */
3581 1650 : else if (maybe_diagnose_standard_trait (cloc, bad))
3582 : ;
3583 1295 : else if (COMPARISON_CLASS_P (bad)
3584 1295 : && (ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))
3585 76 : || REFLECTION_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))))
3586 : {
3587 292 : tree op0 = fold_operand (TREE_OPERAND (bad, 0), ctx);
3588 292 : tree op1 = fold_operand (TREE_OPERAND (bad, 1), ctx);
3589 292 : tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
3590 292 : inform (cloc, "the comparison reduces to %qE", cond);
3591 : }
3592 1003 : else if (show_expr_p)
3593 755 : inform (cloc, "%qE evaluates to false", bad);
3594 1984 : }
3595 :
3596 : /* Process an assert/assume of ORIG_ARG. If it's not supposed to be evaluated,
3597 : do it without changing the current evaluation state. If it evaluates to
3598 : false, complain and return false; otherwise, return true. */
3599 :
3600 : static bool
3601 173602 : cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg,
3602 : location_t loc, bool evaluated,
3603 : bool *non_constant_p, bool *overflow_p)
3604 : {
3605 173602 : if (*non_constant_p)
3606 : return true;
3607 :
3608 173602 : tree eval, jmp_target = NULL_TREE;
3609 173602 : if (!evaluated)
3610 : {
3611 173602 : if (!potential_rvalue_constant_expression (arg))
3612 16 : return true;
3613 :
3614 173586 : constexpr_ctx new_ctx = *ctx;
3615 173586 : new_ctx.quiet = true;
3616 173586 : bool new_non_constant_p = false, new_overflow_p = false;
3617 : /* Avoid modification of existing values. */
3618 173586 : modifiable_tracker ms (new_ctx.global);
3619 173586 : eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3620 : &new_non_constant_p,
3621 : &new_overflow_p, &jmp_target);
3622 173586 : }
3623 : else
3624 0 : eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3625 : non_constant_p,
3626 : overflow_p, &jmp_target);
3627 173586 : if (jmp_target)
3628 : return true;
3629 :
3630 173586 : if (!*non_constant_p && integer_zerop (eval))
3631 : {
3632 42 : if (!ctx->quiet)
3633 : {
3634 : /* See if we can find which clause was failing
3635 : (for logical AND). */
3636 13 : tree bad = find_failing_clause (ctx, arg);
3637 : /* If not, or its location is unusable, fall back to the
3638 : previous location. */
3639 13 : location_t cloc = cp_expr_loc_or_loc (bad, loc);
3640 :
3641 : /* Report the error. */
3642 13 : auto_diagnostic_group d;
3643 13 : error_at (cloc, msg);
3644 13 : diagnose_failing_condition (bad, cloc, true, ctx);
3645 13 : return bad;
3646 13 : }
3647 29 : *non_constant_p = true;
3648 29 : return false;
3649 : }
3650 :
3651 : return true;
3652 : }
3653 :
3654 : /* Evaluate a call T to a GCC internal function when possible and return
3655 : the evaluated result or, under the control of CTX, give an error, set
3656 : NON_CONSTANT_P, and return the unevaluated call T otherwise. */
3657 :
3658 : static tree
3659 388641 : cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
3660 : value_cat lval,
3661 : bool *non_constant_p, bool *overflow_p,
3662 : tree *jump_target)
3663 : {
3664 388641 : enum tree_code opcode = ERROR_MARK;
3665 :
3666 388641 : switch (CALL_EXPR_IFN (t))
3667 : {
3668 166 : case IFN_UBSAN_NULL:
3669 166 : case IFN_UBSAN_BOUNDS:
3670 166 : case IFN_UBSAN_VPTR:
3671 166 : case IFN_FALLTHROUGH:
3672 166 : return void_node;
3673 :
3674 173602 : case IFN_ASSUME:
3675 173602 : if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0),
3676 : G_("failed %<assume%> attribute assumption"),
3677 173602 : EXPR_LOCATION (t), /*eval*/false,
3678 : non_constant_p, overflow_p))
3679 : return t;
3680 173573 : return void_node;
3681 :
3682 : case IFN_ADD_OVERFLOW:
3683 : opcode = PLUS_EXPR;
3684 : break;
3685 385 : case IFN_SUB_OVERFLOW:
3686 385 : opcode = MINUS_EXPR;
3687 385 : break;
3688 207138 : case IFN_MUL_OVERFLOW:
3689 207138 : opcode = MULT_EXPR;
3690 207138 : break;
3691 :
3692 96 : case IFN_LAUNDER:
3693 96 : return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3694 : vc_prvalue, non_constant_p,
3695 96 : overflow_p, jump_target);
3696 :
3697 0 : case IFN_DEFERRED_INIT:
3698 0 : return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
3699 :
3700 120 : case IFN_BSWAP:
3701 120 : case IFN_BITREVERSE:
3702 120 : {
3703 120 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3704 : vc_prvalue, non_constant_p,
3705 : overflow_p, jump_target);
3706 120 : if (*jump_target)
3707 : return NULL_TREE;
3708 120 : if (*non_constant_p)
3709 : return t;
3710 60 : location_t loc = cp_expr_loc_or_input_loc (t);
3711 60 : if (TREE_CODE (arg) != INTEGER_CST
3712 60 : || !INTEGRAL_TYPE_P (TREE_TYPE (arg))
3713 60 : || !TYPE_UNSIGNED (TREE_TYPE (arg))
3714 120 : || (CALL_EXPR_IFN (t) == IFN_BSWAP
3715 30 : && (TYPE_PRECISION (TREE_TYPE (arg)) % 8) != 0))
3716 : {
3717 0 : if (!ctx->quiet)
3718 0 : error_at (loc, "call to internal function %qE", t);
3719 0 : *non_constant_p = true;
3720 0 : return t;
3721 : }
3722 60 : return fold_build_builtin_bswapg_bitreverseg (loc, CALL_EXPR_IFN (t),
3723 60 : arg);
3724 : }
3725 :
3726 6634 : case IFN_VEC_CONVERT:
3727 6634 : {
3728 6634 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3729 : vc_prvalue, non_constant_p,
3730 : overflow_p, jump_target);
3731 6634 : if (*jump_target)
3732 : return NULL_TREE;
3733 6634 : if (TREE_CODE (arg) == VECTOR_CST)
3734 6237 : if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
3735 : return r;
3736 : }
3737 : /* FALLTHRU */
3738 :
3739 402 : default:
3740 402 : if (!ctx->quiet)
3741 0 : error_at (cp_expr_loc_or_input_loc (t),
3742 : "call to internal function %qE", t);
3743 402 : *non_constant_p = true;
3744 402 : return t;
3745 : }
3746 :
3747 : /* Evaluate constant arguments using OPCODE and return a complex
3748 : number containing the result and the overflow bit. */
3749 208023 : tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval,
3750 : non_constant_p, overflow_p,
3751 : jump_target);
3752 208023 : tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval,
3753 : non_constant_p, overflow_p,
3754 : jump_target);
3755 208023 : if (*jump_target)
3756 : return NULL_TREE;
3757 208023 : if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3758 : {
3759 2 : location_t loc = cp_expr_loc_or_input_loc (t);
3760 2 : tree type = TREE_TYPE (TREE_TYPE (t));
3761 2 : tree result = fold_binary_loc (loc, opcode, type,
3762 : fold_convert_loc (loc, type, arg0),
3763 : fold_convert_loc (loc, type, arg1));
3764 2 : tree ovf
3765 2 : = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1));
3766 : /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */
3767 2 : if (TREE_OVERFLOW (result))
3768 0 : TREE_OVERFLOW (result) = 0;
3769 :
3770 2 : return build_complex (TREE_TYPE (t), result, ovf);
3771 : }
3772 :
3773 208021 : *non_constant_p = true;
3774 208021 : return t;
3775 : }
3776 :
3777 : /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates. */
3778 :
3779 : static void
3780 5994927 : clear_no_implicit_zero (tree ctor)
3781 : {
3782 5994927 : if (CONSTRUCTOR_NO_CLEARING (ctor))
3783 : {
3784 1744082 : CONSTRUCTOR_NO_CLEARING (ctor) = false;
3785 7383252 : for (auto &e: CONSTRUCTOR_ELTS (ctor))
3786 2319608 : if (TREE_CODE (e.value) == CONSTRUCTOR)
3787 729611 : clear_no_implicit_zero (e.value);
3788 : }
3789 5994927 : }
3790 :
3791 : /* Complain about a const object OBJ being modified in a constant expression.
3792 : EXPR is the MODIFY_EXPR expression performing the modification. */
3793 :
3794 : static void
3795 65 : modifying_const_object_error (tree expr, tree obj)
3796 : {
3797 65 : location_t loc = cp_expr_loc_or_input_loc (expr);
3798 65 : auto_diagnostic_group d;
3799 130 : error_at (loc, "modifying a const object %qE is not allowed in "
3800 65 : "a constant expression", TREE_OPERAND (expr, 0));
3801 :
3802 : /* Find the underlying object that was declared as const. */
3803 65 : location_t decl_loc = UNKNOWN_LOCATION;
3804 207 : for (tree probe = obj; decl_loc == UNKNOWN_LOCATION; )
3805 77 : switch (TREE_CODE (probe))
3806 : {
3807 39 : case BIT_FIELD_REF:
3808 39 : case COMPONENT_REF:
3809 39 : {
3810 39 : tree elt = TREE_OPERAND (probe, 1);
3811 39 : if (CP_TYPE_CONST_P (TREE_TYPE (elt)))
3812 27 : decl_loc = DECL_SOURCE_LOCATION (elt);
3813 39 : probe = TREE_OPERAND (probe, 0);
3814 : }
3815 39 : break;
3816 :
3817 0 : case ARRAY_REF:
3818 0 : case REALPART_EXPR:
3819 0 : case IMAGPART_EXPR:
3820 0 : probe = TREE_OPERAND (probe, 0);
3821 0 : break;
3822 :
3823 38 : default:
3824 38 : decl_loc = location_of (probe);
3825 38 : break;
3826 : }
3827 65 : inform (decl_loc, "originally declared %<const%> here");
3828 65 : }
3829 :
3830 : /* Return true if FNDECL is a replaceable global allocation function that
3831 : should be usable during constant expression evaluation. */
3832 :
3833 : static inline bool
3834 38825223 : cxx_replaceable_global_alloc_fn (tree fndecl)
3835 : {
3836 38825223 : return (cxx_dialect >= cxx20
3837 36759735 : && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))
3838 2244716 : && CP_DECL_CONTEXT (fndecl) == global_namespace
3839 41069542 : && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)
3840 928043 : || DECL_IS_OPERATOR_DELETE_P (fndecl)));
3841 : }
3842 :
3843 : /* Return true if FNDECL is a placement new function that should be
3844 : usable during constant expression evaluation of std::construct_at. */
3845 :
3846 : static inline bool
3847 37343033 : cxx_placement_new_fn (tree fndecl)
3848 : {
3849 37343033 : return (cxx_dialect >= cxx20 && std_placement_new_fn_p (fndecl));
3850 : }
3851 :
3852 : /* Return true if FNDECL is std::construct_at. */
3853 :
3854 : static inline bool
3855 2332676 : is_std_construct_at (tree fndecl)
3856 : {
3857 2332676 : if (!decl_in_std_namespace_p (fndecl))
3858 : return false;
3859 :
3860 2288366 : tree name = DECL_NAME (fndecl);
3861 2288366 : return name && id_equal (name, "construct_at");
3862 : }
3863 :
3864 : /* Overload for the above taking constexpr_call*. */
3865 :
3866 : static inline bool
3867 2091160 : is_std_construct_at (const constexpr_call *call)
3868 : {
3869 2091160 : return (call
3870 1928976 : && call->fundef
3871 4020136 : && is_std_construct_at (call->fundef->decl));
3872 : }
3873 :
3874 : /* True if CTX is an instance of std::NAME class. */
3875 :
3876 : bool
3877 12390607 : is_std_class (tree ctx, const char *name)
3878 : {
3879 12390607 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3880 : return false;
3881 :
3882 12389985 : tree decl = TYPE_MAIN_DECL (ctx);
3883 12389985 : tree dname = DECL_NAME (decl);
3884 12389985 : if (dname == NULL_TREE || !id_equal (dname, name))
3885 : return false;
3886 :
3887 879403 : return decl_in_std_namespace_p (decl);
3888 : }
3889 :
3890 : /* True if CTX is an instance of std::allocator. */
3891 :
3892 : bool
3893 715169 : is_std_allocator (tree ctx)
3894 : {
3895 715169 : return is_std_class (ctx, "allocator");
3896 : }
3897 :
3898 : /* Return true if FNDECL is std::allocator<T>::allocate. */
3899 :
3900 : static bool
3901 107439 : is_std_allocator_allocate (tree fndecl)
3902 : {
3903 107439 : tree name = DECL_NAME (fndecl);
3904 107439 : if (name == NULL_TREE || !id_equal (name, "allocate"))
3905 : return false;
3906 :
3907 98873 : return is_std_allocator (DECL_CONTEXT (fndecl));
3908 : }
3909 :
3910 : /* Overload for the above taking constexpr_call*. */
3911 :
3912 : static inline bool
3913 118067 : is_std_allocator_allocate (const constexpr_call *call)
3914 : {
3915 118067 : return (call
3916 107439 : && call->fundef
3917 225506 : && is_std_allocator_allocate (call->fundef->decl));
3918 : }
3919 :
3920 : /* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
3921 :
3922 : static bool
3923 661493 : is_std_allocator_allocate_deallocate (tree fndecl)
3924 : {
3925 661493 : tree name = DECL_NAME (fndecl);
3926 661493 : if (name == NULL_TREE
3927 661493 : || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
3928 : return false;
3929 :
3930 614664 : return is_std_allocator (DECL_CONTEXT (fndecl));
3931 : }
3932 :
3933 : /* Overload for the above taking constexpr_call*. */
3934 :
3935 : static inline bool
3936 495532 : is_std_allocator_allocate_deallocate (const constexpr_call *call)
3937 : {
3938 495532 : return (call
3939 298062 : && call->fundef
3940 793594 : && is_std_allocator_allocate_deallocate (call->fundef->decl));
3941 : }
3942 :
3943 : /* Return true if FNDECL is std::source_location::current. */
3944 :
3945 : static inline bool
3946 58794 : is_std_source_location_current (tree fndecl)
3947 : {
3948 58794 : if (!decl_in_std_namespace_p (fndecl))
3949 : return false;
3950 :
3951 39607 : tree name = DECL_NAME (fndecl);
3952 39607 : if (name == NULL_TREE || !id_equal (name, "current"))
3953 : return false;
3954 :
3955 159 : tree ctx = DECL_CONTEXT (fndecl);
3956 159 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3957 : return false;
3958 :
3959 159 : name = DECL_NAME (TYPE_MAIN_DECL (ctx));
3960 159 : return name && id_equal (name, "source_location");
3961 : }
3962 :
3963 : /* Overload for the above taking constexpr_call*. */
3964 :
3965 : static inline bool
3966 86016 : is_std_source_location_current (const constexpr_call *call)
3967 : {
3968 86016 : return (call
3969 58794 : && call->fundef
3970 144810 : && is_std_source_location_current (call->fundef->decl));
3971 : }
3972 :
3973 : /* Return true if FNDECL is __dynamic_cast. */
3974 :
3975 : static inline bool
3976 37031823 : cxx_dynamic_cast_fn_p (tree fndecl)
3977 : {
3978 37031823 : return (cxx_dialect >= cxx20
3979 34966330 : && id_equal (DECL_NAME (fndecl), "__dynamic_cast")
3980 6788 : && CP_DECL_CONTEXT (fndecl) == abi_node
3981 : /* Only consider implementation-detail __dynamic_cast calls that
3982 : correspond to a dynamic_cast, and ignore direct calls to
3983 : abi::__dynamic_cast. */
3984 37038611 : && DECL_ARTIFICIAL (fndecl));
3985 : }
3986 :
3987 : /* Often, we have an expression in the form of address + offset, e.g.
3988 : "&_ZTV1A + 16". Extract the object from it, i.e. "_ZTV1A". */
3989 :
3990 : static tree
3991 5840 : extract_obj_from_addr_offset (tree expr)
3992 : {
3993 5840 : if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
3994 2786 : expr = TREE_OPERAND (expr, 0);
3995 5840 : STRIP_NOPS (expr);
3996 5840 : if (TREE_CODE (expr) == ADDR_EXPR)
3997 5829 : expr = TREE_OPERAND (expr, 0);
3998 5840 : return expr;
3999 : }
4000 :
4001 : /* Given a PATH like
4002 :
4003 : g.D.2181.D.2154.D.2102.D.2093
4004 :
4005 : find a component with type TYPE. Return NULL_TREE if not found, and
4006 : error_mark_node if the component is not accessible. If STOP is non-null,
4007 : this function will return NULL_TREE if STOP is found before TYPE. */
4008 :
4009 : static tree
4010 2831 : get_component_with_type (tree path, tree type, tree stop)
4011 : {
4012 7921 : while (true)
4013 : {
4014 5376 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path), type))
4015 : /* Found it. */
4016 : return path;
4017 3761 : else if (stop
4018 3761 : && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path),
4019 : stop)))
4020 : return NULL_TREE;
4021 3716 : else if (TREE_CODE (path) == COMPONENT_REF
4022 3716 : && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1)))
4023 : {
4024 : /* We need to check that the component we're accessing is in fact
4025 : accessible. */
4026 3716 : if (TREE_PRIVATE (TREE_OPERAND (path, 1))
4027 3716 : || TREE_PROTECTED (TREE_OPERAND (path, 1)))
4028 1171 : return error_mark_node;
4029 2545 : path = TREE_OPERAND (path, 0);
4030 : }
4031 : else
4032 : return NULL_TREE;
4033 : }
4034 : }
4035 :
4036 : /* Evaluate a call to __dynamic_cast (permitted by P1327R1).
4037 :
4038 : The declaration of __dynamic_cast is:
4039 :
4040 : void* __dynamic_cast (const void* __src_ptr,
4041 : const __class_type_info* __src_type,
4042 : const __class_type_info* __dst_type,
4043 : ptrdiff_t __src2dst);
4044 :
4045 : where src2dst has the following possible values
4046 :
4047 : >-1: src_type is a unique public non-virtual base of dst_type
4048 : dst_ptr + src2dst == src_ptr
4049 : -1: unspecified relationship
4050 : -2: src_type is not a public base of dst_type
4051 : -3: src_type is a multiple public non-virtual base of dst_type */
4052 :
4053 : static tree
4054 3173 : cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
4055 : bool *non_constant_p, bool *overflow_p,
4056 : tree *jump_target)
4057 : {
4058 : /* T will be something like
4059 : __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8)
4060 : dismantle it. */
4061 3173 : gcc_assert (call_expr_nargs (call) == 4);
4062 3173 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
4063 3173 : tree obj = CALL_EXPR_ARG (call, 0);
4064 3173 : tree type = CALL_EXPR_ARG (call, 2);
4065 3173 : HOST_WIDE_INT hint = int_cst_value (CALL_EXPR_ARG (call, 3));
4066 3173 : location_t loc = cp_expr_loc_or_input_loc (call);
4067 :
4068 : /* Get the target type of the dynamic_cast. */
4069 3173 : gcc_assert (TREE_CODE (type) == ADDR_EXPR);
4070 3173 : type = TREE_OPERAND (type, 0);
4071 3173 : type = TREE_TYPE (DECL_NAME (type));
4072 :
4073 : /* TYPE can only be either T* or T&. We can't know which of these it
4074 : is by looking at TYPE, but OBJ will be "(T*) x" in the first case,
4075 : and something like "(T*)(T&)(T*) x" in the second case.
4076 : This is true for the reference cases in C++ < 26 or when exceptions
4077 : aren't enabled, in that case we should diagnose errors. For C++26
4078 : with exceptions we should silently evaluate to null pointer and
4079 : let the callers call __cxa_bad_cast () later to throw an exception. */
4080 3173 : bool fail_for_non_constant_p = false;
4081 12899 : while (CONVERT_EXPR_P (obj) || TREE_CODE (obj) == SAVE_EXPR)
4082 : {
4083 9726 : if (cxx_dialect < cxx26 || !flag_exceptions)
4084 5557 : fail_for_non_constant_p |= TYPE_REF_P (TREE_TYPE (obj));
4085 9726 : obj = TREE_OPERAND (obj, 0);
4086 : }
4087 :
4088 : /* Evaluate the object so that we know its dynamic type. */
4089 3173 : obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p,
4090 : overflow_p, jump_target);
4091 3173 : if (*non_constant_p)
4092 : return call;
4093 3054 : if (*jump_target)
4094 : return NULL_TREE;
4095 :
4096 : /* For dynamic_cast from classes with virtual bases we can get something
4097 : like (virt_base *)(&d + 16) as OBJ. Try to convert that into
4098 : d.D.1234 using cxx_fold_indirect_ref. */
4099 3054 : if (cxx_dialect >= cxx26 && CONVERT_EXPR_P (obj))
4100 : {
4101 1206 : tree objo = obj;
4102 1206 : STRIP_NOPS (objo);
4103 1206 : if (TREE_CODE (objo) == POINTER_PLUS_EXPR)
4104 : {
4105 1152 : objo = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (TREE_TYPE (obj)),
4106 : obj, NULL, jump_target);
4107 1152 : if (objo)
4108 1152 : obj = build_fold_addr_expr (objo);
4109 : }
4110 : }
4111 :
4112 : /* We expect OBJ to be in form of &d.D.2102 when HINT == 0,
4113 : but when HINT is > 0, it can also be something like
4114 : &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET. */
4115 3054 : obj = extract_obj_from_addr_offset (obj);
4116 3054 : const tree objtype = TREE_TYPE (obj);
4117 : /* If OBJ doesn't refer to a base field, we're done. */
4118 6029 : if (tree t = (TREE_CODE (obj) == COMPONENT_REF
4119 3054 : ? TREE_OPERAND (obj, 1) : obj))
4120 3054 : if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t))
4121 : {
4122 79 : if (fail_for_non_constant_p)
4123 : {
4124 55 : if (!ctx->quiet)
4125 : {
4126 2 : auto_diagnostic_group d;
4127 2 : error_at (loc, "reference %<dynamic_cast%> failed");
4128 2 : inform (loc, "dynamic type %qT of its operand does "
4129 : "not have a base class of type %qT",
4130 : objtype, type);
4131 2 : }
4132 55 : *non_constant_p = true;
4133 : }
4134 79 : return integer_zero_node;
4135 : }
4136 :
4137 : /* [class.cdtor] When a dynamic_cast is used in a constructor ...
4138 : or in a destructor ... if the operand of the dynamic_cast refers
4139 : to the object under construction or destruction, this object is
4140 : considered to be a most derived object that has the type of the
4141 : constructor or destructor's class. */
4142 2975 : tree vtable = build_vfield_ref (obj, objtype);
4143 2975 : vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue,
4144 : non_constant_p, overflow_p,
4145 : jump_target);
4146 2975 : if (*non_constant_p)
4147 : return call;
4148 2798 : if (*jump_target)
4149 : return NULL_TREE;
4150 : /* With -fsanitize=vptr, we initialize all vtable pointers to null,
4151 : so it's possible that we got a null pointer now. */
4152 2798 : if (integer_zerop (vtable))
4153 : {
4154 12 : if (!ctx->quiet)
4155 3 : error_at (loc, "virtual table pointer is used uninitialized");
4156 12 : *non_constant_p = true;
4157 12 : return integer_zero_node;
4158 : }
4159 : /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */
4160 2786 : vtable = extract_obj_from_addr_offset (vtable);
4161 2786 : const tree mdtype = DECL_CONTEXT (vtable);
4162 :
4163 : /* Given dynamic_cast<T>(v),
4164 :
4165 : [expr.dynamic.cast] If C is the class type to which T points or refers,
4166 : the runtime check logically executes as follows:
4167 :
4168 : If, in the most derived object pointed (referred) to by v, v points
4169 : (refers) to a public base class subobject of a C object, and if only
4170 : one object of type C is derived from the subobject pointed (referred)
4171 : to by v the result points (refers) to that C object.
4172 :
4173 : In this case, HINT >= 0 or -3. */
4174 2786 : if (hint >= 0 || hint == -3)
4175 : {
4176 : /* Look for a component with type TYPE. */
4177 687 : tree t = get_component_with_type (obj, type, mdtype);
4178 : /* If not accessible, give an error. */
4179 687 : if (t == error_mark_node)
4180 : {
4181 198 : if (fail_for_non_constant_p)
4182 : {
4183 108 : if (!ctx->quiet)
4184 : {
4185 12 : auto_diagnostic_group d;
4186 12 : error_at (loc, "reference %<dynamic_cast%> failed");
4187 12 : inform (loc, "static type %qT of its operand is a "
4188 : "non-public base class of dynamic type %qT",
4189 : objtype, type);
4190 :
4191 12 : }
4192 108 : *non_constant_p = true;
4193 : }
4194 198 : return integer_zero_node;
4195 : }
4196 489 : else if (t)
4197 : /* The result points to the TYPE object. */
4198 444 : return cp_build_addr_expr (t, complain);
4199 : /* Else, TYPE was not found, because the HINT turned out to be wrong.
4200 : Fall through to the normal processing. */
4201 : }
4202 :
4203 : /* Otherwise, if v points (refers) to a public base class subobject of the
4204 : most derived object, and the type of the most derived object has a base
4205 : class, of type C, that is unambiguous and public, the result points
4206 : (refers) to the C subobject of the most derived object.
4207 :
4208 : But it can also be an invalid case. */
4209 :
4210 : /* Get the most derived object. */
4211 2144 : obj = get_component_with_type (obj, mdtype, NULL_TREE);
4212 2144 : if (obj == error_mark_node)
4213 : {
4214 973 : if (fail_for_non_constant_p)
4215 : {
4216 350 : if (!ctx->quiet)
4217 : {
4218 38 : auto_diagnostic_group d;
4219 38 : error_at (loc, "reference %<dynamic_cast%> failed");
4220 38 : inform (loc, "static type %qT of its operand is a non-public"
4221 : " base class of dynamic type %qT", objtype, mdtype);
4222 38 : }
4223 350 : *non_constant_p = true;
4224 : }
4225 973 : return integer_zero_node;
4226 : }
4227 : else
4228 1171 : gcc_assert (obj);
4229 :
4230 : /* Check that the type of the most derived object has a base class
4231 : of type TYPE that is unambiguous and public. */
4232 1171 : base_kind b_kind;
4233 1171 : tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none);
4234 1171 : if (!binfo || binfo == error_mark_node)
4235 : {
4236 441 : if (fail_for_non_constant_p)
4237 : {
4238 134 : if (!ctx->quiet)
4239 : {
4240 16 : auto_diagnostic_group d;
4241 16 : error_at (loc, "reference %<dynamic_cast%> failed");
4242 16 : if (b_kind == bk_ambig)
4243 6 : inform (loc, "%qT is an ambiguous base class of dynamic "
4244 : "type %qT of its operand", type, mdtype);
4245 : else
4246 10 : inform (loc, "dynamic type %qT of its operand does not "
4247 : "have an unambiguous public base class %qT",
4248 : mdtype, type);
4249 16 : }
4250 134 : *non_constant_p = true;
4251 : }
4252 441 : return integer_zero_node;
4253 : }
4254 : /* If so, return the TYPE subobject of the most derived object. */
4255 730 : obj = convert_to_base_statically (obj, binfo);
4256 730 : return cp_build_addr_expr (obj, complain);
4257 : }
4258 :
4259 : /* Data structure used by replace_decl and replace_decl_r. */
4260 :
4261 : struct replace_decl_data
4262 : {
4263 : /* The _DECL we want to replace. */
4264 : tree decl;
4265 : /* The replacement for DECL. */
4266 : tree replacement;
4267 : /* Trees we've visited. */
4268 : hash_set<tree> *pset;
4269 : /* Whether we've performed any replacements. */
4270 : bool changed;
4271 : };
4272 :
4273 : /* Helper function for replace_decl, called through cp_walk_tree. */
4274 :
4275 : static tree
4276 16997430 : replace_decl_r (tree *tp, int *walk_subtrees, void *data)
4277 : {
4278 16997430 : replace_decl_data *d = (replace_decl_data *) data;
4279 :
4280 : /* We could be replacing
4281 : &<retval>.bar -> &foo.bar
4282 : where foo is a static VAR_DECL, so we need to recompute TREE_CONSTANT
4283 : on the ADDR_EXPR around it. */
4284 16997430 : if (TREE_CODE (*tp) == ADDR_EXPR)
4285 : {
4286 1527031 : d->pset->add (*tp);
4287 1527031 : auto save_changed = d->changed;
4288 1527031 : d->changed = false;
4289 1527031 : cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr);
4290 1527031 : if (d->changed)
4291 : {
4292 1855 : cxx_mark_addressable (*tp);
4293 1855 : recompute_tree_invariant_for_addr_expr (*tp);
4294 : }
4295 : else
4296 1525176 : d->changed = save_changed;
4297 1527031 : *walk_subtrees = 0;
4298 : }
4299 15470399 : else if (*tp == d->decl)
4300 : {
4301 2095 : *tp = unshare_expr (d->replacement);
4302 2095 : d->changed = true;
4303 2095 : *walk_subtrees = 0;
4304 : }
4305 15468304 : else if (TYPE_P (*tp)
4306 15468304 : || d->pset->add (*tp))
4307 2835973 : *walk_subtrees = 0;
4308 :
4309 16997430 : return NULL_TREE;
4310 : }
4311 :
4312 : /* Replace every occurrence of DECL with (an unshared copy of)
4313 : REPLACEMENT within the expression *TP. Returns true iff a
4314 : replacement was performed. */
4315 :
4316 : bool
4317 2264936 : replace_decl (tree *tp, tree decl, tree replacement)
4318 : {
4319 2264936 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
4320 : (TREE_TYPE (decl), TREE_TYPE (replacement)));
4321 2264936 : hash_set<tree> pset;
4322 2264936 : replace_decl_data data = { decl, replacement, &pset, false };
4323 2264936 : cp_walk_tree (tp, replace_decl_r, &data, NULL);
4324 2264936 : return data.changed;
4325 2264936 : }
4326 :
4327 : /* Evaluate the call T to virtual function thunk THUNK_FNDECL. */
4328 :
4329 : static tree
4330 44 : cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl,
4331 : value_cat lval,
4332 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
4333 : {
4334 44 : tree function = THUNK_TARGET (thunk_fndecl);
4335 :
4336 44 : if (THUNK_VIRTUAL_OFFSET (thunk_fndecl))
4337 : {
4338 13 : if (!ctx->quiet)
4339 : {
4340 3 : if (!DECL_DECLARED_CONSTEXPR_P (function))
4341 : {
4342 0 : error ("call to non-%<constexpr%> function %qD", function);
4343 0 : explain_invalid_constexpr_fn (function);
4344 : }
4345 : else
4346 : /* virtual_offset is only set for virtual bases, which make the
4347 : class non-literal, so we don't need to handle it here. */
4348 3 : error ("calling constexpr member function %qD through virtual "
4349 : "base subobject", function);
4350 : }
4351 13 : *non_constant_p = true;
4352 13 : return t;
4353 : }
4354 :
4355 31 : tree new_call = copy_node (t);
4356 31 : CALL_EXPR_FN (new_call) = function;
4357 31 : TREE_TYPE (new_call) = TREE_TYPE (TREE_TYPE (function));
4358 :
4359 31 : tree offset = size_int (THUNK_FIXED_OFFSET (thunk_fndecl));
4360 :
4361 31 : if (DECL_THIS_THUNK_P (thunk_fndecl))
4362 : {
4363 : /* 'this'-adjusting thunk. */
4364 19 : tree this_arg = CALL_EXPR_ARG (t, 0);
4365 19 : this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg),
4366 : this_arg, offset);
4367 19 : CALL_EXPR_ARG (new_call, 0) = this_arg;
4368 : }
4369 : else
4370 : {
4371 : /* Return-adjusting thunk. As in expand_thunk, adjust a pointer only
4372 : if it is non-null. */
4373 12 : tree call = new_call;
4374 12 : if (TYPE_PTR_P (TREE_TYPE (call)))
4375 12 : call = save_expr (call);
4376 12 : new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (call), call, offset);
4377 12 : if (TYPE_PTR_P (TREE_TYPE (call)))
4378 12 : new_call = build_if_nonnull (call, new_call, tf_none);
4379 : }
4380 :
4381 31 : tree result = cxx_eval_constant_expression (ctx, new_call, lval,
4382 : non_constant_p, overflow_p,
4383 : jump_target);
4384 31 : if (!*non_constant_p
4385 27 : && !*overflow_p
4386 27 : && !*jump_target
4387 27 : && result != void_node
4388 27 : && INDIRECT_TYPE_P (TREE_TYPE (t))
4389 55 : && !(same_type_ignoring_top_level_qualifiers_p
4390 24 : (TREE_TYPE (result), TREE_TYPE (t))))
4391 15 : result = adjust_temp_type (TREE_TYPE (t), result);
4392 : return result;
4393 : }
4394 :
4395 : /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set
4396 : its TREE_READONLY flag according to READONLY_P. Used for constexpr
4397 : 'tors to detect modifying const objects in a constexpr context. */
4398 :
4399 : static void
4400 11180778 : cxx_set_object_constness (const constexpr_ctx *ctx, tree object,
4401 : bool readonly_p, bool *non_constant_p,
4402 : bool *overflow_p, tree *jump_target)
4403 : {
4404 22361556 : if (CLASS_TYPE_P (TREE_TYPE (object))
4405 22361556 : && CP_TYPE_CONST_P (TREE_TYPE (object)))
4406 : {
4407 : /* Subobjects might not be stored in ctx->global->values but we
4408 : can get its CONSTRUCTOR by evaluating *this. */
4409 1044398 : tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue,
4410 : non_constant_p, overflow_p,
4411 : jump_target);
4412 1044398 : if (!*non_constant_p
4413 12182574 : && !throws (jump_target)
4414 2046194 : && TREE_CODE (e) == CONSTRUCTOR)
4415 1001796 : TREE_READONLY (e) = readonly_p;
4416 : }
4417 11180778 : }
4418 :
4419 : /* Allocate an exception for OBJECT and throw it. */
4420 :
4421 : tree
4422 3164 : cxa_allocate_and_throw_exception (location_t loc, const constexpr_ctx *ctx,
4423 : tree object)
4424 : {
4425 3164 : tree type = TREE_TYPE (object);
4426 : /* This simulates a call to __cxa_allocate_exception. We need
4427 : (struct exception *) &heap -- memory on the heap so that
4428 : it can survive the stack being unwound. */
4429 3164 : tree arr = build_array_of_n_type (type, 1);
4430 3164 : tree var = cxa_allocate_exception (loc, ctx, arr, size_zero_node);
4431 3164 : DECL_NAME (var) = heap_identifier;
4432 3164 : ctx->global->put_value (var, NULL_TREE);
4433 :
4434 : /* *(struct exception *) &heap = exc{ ... } */
4435 3164 : tree ptr = build_nop (build_pointer_type (type), build_address (var));
4436 3164 : object = cp_build_init_expr (cp_build_fold_indirect_ref (ptr), object);
4437 3164 : bool non_constant_p = false, overflow_p = false;
4438 3164 : tree jump_target = NULL_TREE;
4439 3164 : cxx_eval_constant_expression (ctx, object, vc_prvalue, &non_constant_p,
4440 : &overflow_p, &jump_target);
4441 3164 : if (non_constant_p)
4442 : {
4443 0 : if (!ctx->quiet)
4444 0 : error_at (loc, "couldn%'t throw %qT", type);
4445 : return NULL_TREE;
4446 : }
4447 :
4448 : /* Now we can __cxa_throw. */
4449 3164 : DECL_EXCEPTION_REFCOUNT (var)
4450 3164 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (var), size_one_node);
4451 3164 : ++ctx->global->uncaught_exceptions;
4452 :
4453 3164 : return var;
4454 : }
4455 :
4456 : /* Subroutine of cxx_eval_constant_expression.
4457 : Evaluate the call expression tree T in the context of OLD_CALL expression
4458 : evaluation. */
4459 :
4460 : static tree
4461 207676478 : cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
4462 : value_cat lval,
4463 : bool *non_constant_p, bool *overflow_p,
4464 : tree *jump_target)
4465 : {
4466 207676478 : location_t loc = cp_expr_loc_or_input_loc (t);
4467 207676478 : tree fun = get_function_named_in_call (t);
4468 :
4469 207676478 : if (fun == NULL_TREE)
4470 388641 : return cxx_eval_internal_function (ctx, t, lval,
4471 : non_constant_p, overflow_p,
4472 388641 : jump_target);
4473 :
4474 207287837 : if (TREE_CODE (fun) != FUNCTION_DECL)
4475 : {
4476 : /* Might be a constexpr function pointer. */
4477 419754 : fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue,
4478 : non_constant_p, overflow_p,
4479 : jump_target);
4480 419754 : if (*jump_target)
4481 : return NULL_TREE;
4482 419754 : STRIP_NOPS (fun);
4483 419754 : if (TREE_CODE (fun) == ADDR_EXPR)
4484 30552 : fun = TREE_OPERAND (fun, 0);
4485 : /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
4486 : indirection, the called expression is a pointer into the
4487 : virtual table which should contain FDESC_EXPR. Extract the
4488 : FUNCTION_DECL from there. */
4489 : else if (TARGET_VTABLE_USES_DESCRIPTORS
4490 : && TREE_CODE (fun) == POINTER_PLUS_EXPR
4491 : && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
4492 : && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
4493 : {
4494 : tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
4495 : if (VAR_P (d)
4496 : && DECL_VTABLE_OR_VTT_P (d)
4497 : && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
4498 : && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
4499 : && DECL_INITIAL (d)
4500 : && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
4501 : {
4502 : tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
4503 : TYPE_SIZE_UNIT (vtable_entry_type));
4504 : HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
4505 : if (idx >= 0)
4506 : {
4507 : tree fdesc
4508 : = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
4509 : if (TREE_CODE (fdesc) == FDESC_EXPR
4510 : && integer_zerop (TREE_OPERAND (fdesc, 1)))
4511 : fun = TREE_OPERAND (fdesc, 0);
4512 : }
4513 : }
4514 : }
4515 : }
4516 207287837 : if (TREE_CODE (fun) != FUNCTION_DECL)
4517 : {
4518 389202 : if (!ctx->quiet && !*non_constant_p)
4519 0 : error_at (loc, "expression %qE does not designate a %<constexpr%> "
4520 : "function", fun);
4521 389202 : *non_constant_p = true;
4522 389202 : return t;
4523 : }
4524 206898635 : tree orig_fun = fun;
4525 206898635 : if (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun))
4526 24604110 : fun = DECL_CLONED_FUNCTION (fun);
4527 :
4528 206898635 : if (is_ubsan_builtin_p (fun))
4529 58 : return void_node;
4530 :
4531 206898577 : if (fndecl_built_in_p (fun))
4532 20768459 : return cxx_eval_builtin_function_call (ctx, t, fun,
4533 : lval, non_constant_p, overflow_p,
4534 20768457 : jump_target);
4535 186130118 : if (DECL_THUNK_P (fun))
4536 44 : return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p,
4537 44 : jump_target);
4538 186130074 : if (metafunction_p (fun))
4539 : {
4540 : /* To be able to evaluate a metafunction, we may have to instantiate
4541 : constexpr functions. If we're not allowed to instantiate, leave
4542 : this for later. Don't evaluate metafunctions at all when mce_unknown,
4543 : otherwise we might fold those prematurely. See
4544 : g++.dg/reflect/p2996-17.C. */
4545 81448 : if (uid_sensitive_constexpr_evaluation_p ()
4546 80888 : || ctx->manifestly_const_eval == mce_unknown)
4547 : {
4548 21676 : *non_constant_p = true;
4549 21676 : return t;
4550 : }
4551 59772 : ctx->global->state_dependent = true;
4552 59772 : tree e = process_metafunction (ctx, fun, t, non_constant_p, overflow_p,
4553 : jump_target);
4554 59772 : if (*jump_target)
4555 : return NULL_TREE;
4556 56596 : if (*non_constant_p)
4557 : return t;
4558 55524 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
4559 : non_constant_p, overflow_p,
4560 : jump_target);
4561 55524 : if (*jump_target)
4562 : return NULL_TREE;
4563 55524 : if (*non_constant_p)
4564 : return t;
4565 55514 : return e;
4566 : }
4567 186048626 : bool non_constexpr_call = false;
4568 186048626 : if (!maybe_constexpr_fn (fun))
4569 : {
4570 904602 : if (TREE_CODE (t) == CALL_EXPR
4571 897035 : && cxx_replaceable_global_alloc_fn (fun)
4572 1568843 : && (CALL_FROM_NEW_OR_DELETE_P (t)
4573 328932 : || is_std_allocator_allocate_deallocate (ctx->call)))
4574 : {
4575 493993 : const bool new_op_p = IDENTIFIER_NEW_OP_P (DECL_NAME (fun));
4576 493993 : const int nargs = call_expr_nargs (t);
4577 493993 : tree arg0 = NULL_TREE;
4578 783209 : for (int i = 0; i < nargs; ++i)
4579 : {
4580 495062 : tree arg = CALL_EXPR_ARG (t, i);
4581 495062 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4582 : non_constant_p, overflow_p,
4583 : jump_target);
4584 495062 : if (*jump_target)
4585 : return NULL_TREE;
4586 : /* Deleting a non-constant pointer has a better error message
4587 : below. */
4588 495052 : if (new_op_p || i != 0)
4589 415967 : VERIFY_CONSTANT (arg);
4590 210131 : if (i == 0)
4591 : arg0 = arg;
4592 : }
4593 288147 : gcc_assert (arg0);
4594 288147 : if (new_op_p)
4595 : {
4596 209062 : if (!tree_fits_uhwi_p (arg0))
4597 : {
4598 : /* We should not get here; the VERIFY_CONSTANT above
4599 : should have already caught it. */
4600 0 : gcc_checking_assert (false);
4601 : if (!ctx->quiet)
4602 : error_at (loc, "cannot allocate array: size not constant");
4603 : *non_constant_p = true;
4604 : return t;
4605 : }
4606 418124 : tree type = build_array_type_nelts (char_type_node,
4607 209062 : tree_to_uhwi (arg0));
4608 209062 : tree var = build_decl (loc, VAR_DECL,
4609 209062 : (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4610 : & OVL_OP_FLAG_VEC)
4611 : ? heap_vec_uninit_identifier
4612 : : heap_uninit_identifier,
4613 209062 : type);
4614 209062 : DECL_ARTIFICIAL (var) = 1;
4615 209062 : ctx->global->heap_vars.safe_push (var);
4616 209062 : ctx->global->put_value (var, NULL_TREE);
4617 209062 : return fold_convert (ptr_type_node, build_address (var));
4618 : }
4619 : else
4620 : {
4621 79085 : STRIP_NOPS (arg0);
4622 79085 : if (TREE_CODE (arg0) == ADDR_EXPR
4623 79085 : && VAR_P (TREE_OPERAND (arg0, 0)))
4624 : {
4625 79085 : tree var = TREE_OPERAND (arg0, 0);
4626 79085 : if (DECL_NAME (var) == heap_uninit_identifier
4627 79085 : || DECL_NAME (var) == heap_identifier)
4628 : {
4629 78911 : if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4630 : & OVL_OP_FLAG_VEC)
4631 : {
4632 9 : if (!ctx->quiet)
4633 : {
4634 3 : auto_diagnostic_group d;
4635 3 : error_at (loc, "array deallocation of object "
4636 : "allocated with non-array "
4637 : "allocation");
4638 3 : inform (DECL_SOURCE_LOCATION (var),
4639 : "allocation performed here");
4640 3 : }
4641 9 : *non_constant_p = true;
4642 9 : return t;
4643 : }
4644 78902 : DECL_NAME (var) = heap_deleted_identifier;
4645 78902 : ctx->global->destroy_value (var);
4646 78902 : ctx->global->heap_dealloc_count++;
4647 78902 : return void_node;
4648 : }
4649 174 : else if (DECL_NAME (var) == heap_vec_uninit_identifier
4650 174 : || DECL_NAME (var) == heap_vec_identifier)
4651 : {
4652 150 : if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4653 : & OVL_OP_FLAG_VEC) == 0)
4654 : {
4655 9 : if (!ctx->quiet)
4656 : {
4657 3 : auto_diagnostic_group d;
4658 3 : error_at (loc, "non-array deallocation of "
4659 : "object allocated with array "
4660 : "allocation");
4661 3 : inform (DECL_SOURCE_LOCATION (var),
4662 : "allocation performed here");
4663 3 : }
4664 9 : *non_constant_p = true;
4665 9 : return t;
4666 : }
4667 141 : DECL_NAME (var) = heap_deleted_identifier;
4668 141 : ctx->global->destroy_value (var);
4669 141 : ctx->global->heap_dealloc_count++;
4670 141 : return void_node;
4671 : }
4672 24 : else if (DECL_NAME (var) == heap_deleted_identifier)
4673 : {
4674 15 : if (!ctx->quiet)
4675 6 : error_at (loc, "deallocation of already deallocated "
4676 : "storage");
4677 15 : *non_constant_p = true;
4678 15 : return t;
4679 : }
4680 : }
4681 9 : if (!ctx->quiet)
4682 3 : error_at (loc, "deallocation of storage that was "
4683 : "not previously allocated");
4684 9 : *non_constant_p = true;
4685 9 : return t;
4686 : }
4687 : }
4688 : /* Allow placement new in std::construct_at, just return the second
4689 : argument. */
4690 410609 : if (TREE_CODE (t) == CALL_EXPR
4691 403042 : && cxx_placement_new_fn (fun)
4692 591592 : && is_std_construct_at (ctx->call))
4693 : {
4694 45975 : const int nargs = call_expr_nargs (t);
4695 45975 : tree arg1 = NULL_TREE;
4696 137925 : for (int i = 0; i < nargs; ++i)
4697 : {
4698 91950 : tree arg = CALL_EXPR_ARG (t, i);
4699 91950 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4700 : non_constant_p, overflow_p,
4701 : jump_target);
4702 91950 : if (*jump_target)
4703 : return NULL_TREE;
4704 91950 : if (i == 1)
4705 : arg1 = arg;
4706 : else
4707 91950 : VERIFY_CONSTANT (arg);
4708 : }
4709 45975 : gcc_assert (arg1);
4710 : return arg1;
4711 : }
4712 364634 : else if (cxx_dynamic_cast_fn_p (fun))
4713 3173 : return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p,
4714 3173 : jump_target);
4715 361461 : else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun))
4716 27973 : return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun,
4717 : non_constant_p, overflow_p,
4718 27973 : jump_target);
4719 :
4720 : /* Calls to non-constexpr functions can be diagnosed right away
4721 : before C++26, though in C++26 evaluation of the arguments might
4722 : throw and if caught it could be still constant expression.
4723 : So for C++26 this is diagnosed only after
4724 : cxx_bind_parameters_in_call. */
4725 333488 : if (cxx_dialect >= cxx26)
4726 : non_constexpr_call = true;
4727 : else
4728 : {
4729 292745 : if (!ctx->quiet)
4730 : {
4731 208 : if (!lambda_static_thunk_p (fun))
4732 208 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4733 208 : explain_invalid_constexpr_fn (fun);
4734 : }
4735 292745 : *non_constant_p = true;
4736 292745 : return t;
4737 : }
4738 : }
4739 :
4740 185184767 : constexpr_ctx new_ctx = *ctx;
4741 185184767 : ctx = &new_ctx;
4742 208311522 : if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
4743 189181588 : && TREE_CODE (t) == AGGR_INIT_EXPR)
4744 : {
4745 : /* We want to have an initialization target for an AGGR_INIT_EXPR.
4746 : If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
4747 2828 : new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
4748 2828 : tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
4749 2828 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
4750 2828 : ctx->global->put_value (new_ctx.object, ctor);
4751 : }
4752 : /* An immediate invocation is manifestly constant evaluated including the
4753 : arguments of the call, so use mce_true even for the argument
4754 : evaluation. */
4755 370369534 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
4756 3463150 : new_ctx.manifestly_const_eval = mce_true;
4757 :
4758 : /* We used to shortcut trivial constructor/op= here, but nowadays
4759 : we can only get a trivial function here with -fno-elide-constructors. */
4760 185184903 : gcc_checking_assert (!trivial_fn_p (fun)
4761 : || !flag_elide_constructors
4762 : /* Or it's a call from maybe_thunk_body (111075). */
4763 : || (TREE_CODE (t) == CALL_EXPR ? CALL_FROM_THUNK_P (t)
4764 : : AGGR_INIT_FROM_THUNK_P (t))
4765 : /* We don't elide constructors when processing
4766 : a noexcept-expression. */
4767 : || cp_noexcept_operand);
4768 :
4769 185184767 : bool non_constant_args = false;
4770 185184767 : constexpr_call new_call;
4771 185184767 : new_call.bindings
4772 185184767 : = cxx_bind_parameters_in_call (ctx, t, fun, orig_fun, non_constant_p,
4773 : overflow_p, &non_constant_args,
4774 : jump_target);
4775 :
4776 : /* We build up the bindings list before we know whether we already have this
4777 : call cached. If we don't end up saving these bindings, ggc_free them when
4778 : this function exits. */
4779 185184767 : class free_bindings
4780 : {
4781 : tree *bindings;
4782 : public:
4783 185184767 : free_bindings (tree &b): bindings (&b) { }
4784 185184763 : ~free_bindings () { if (bindings) ggc_free (*bindings); }
4785 4668995 : void preserve () { bindings = NULL; }
4786 185184767 : } fb (new_call.bindings);
4787 :
4788 185184767 : if (*jump_target)
4789 : return NULL_TREE;
4790 185184683 : if (*non_constant_p)
4791 : return t;
4792 110671477 : if (non_constexpr_call)
4793 : {
4794 6374 : if (!ctx->quiet)
4795 : {
4796 436 : if (!lambda_static_thunk_p (fun))
4797 436 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4798 436 : explain_invalid_constexpr_fn (fun);
4799 : }
4800 6374 : *non_constant_p = true;
4801 6374 : return t;
4802 : }
4803 :
4804 : /* We can't defer instantiating the function any longer. */
4805 110665103 : if (!DECL_INITIAL (fun)
4806 3147454 : && (DECL_TEMPLOID_INSTANTIATION (fun) || DECL_DEFAULTED_FN (fun))
4807 110665103 : && !uid_sensitive_constexpr_evaluation_p ())
4808 : {
4809 2905383 : location_t save_loc = input_location;
4810 2905383 : input_location = loc;
4811 2905383 : ++function_depth;
4812 2905383 : if (ctx->manifestly_const_eval == mce_true)
4813 368405 : FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true;
4814 2905383 : if (DECL_TEMPLOID_INSTANTIATION (fun))
4815 2905369 : instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
4816 : else
4817 14 : synthesize_method (fun);
4818 2905383 : --function_depth;
4819 2905383 : input_location = save_loc;
4820 : }
4821 :
4822 : /* If in direct recursive call, optimize definition search. */
4823 110665103 : if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun)
4824 29271 : new_call.fundef = ctx->call->fundef;
4825 : else
4826 : {
4827 110635832 : new_call.fundef = retrieve_constexpr_fundef (fun);
4828 110635832 : if (new_call.fundef == NULL || new_call.fundef->body == NULL
4829 110064539 : || new_call.fundef->result == error_mark_node
4830 110048669 : || fun == current_function_decl)
4831 : {
4832 587169 : if (!ctx->quiet)
4833 : {
4834 : /* We need to check for current_function_decl here in case we're
4835 : being called during cp_fold_function, because at that point
4836 : DECL_INITIAL is set properly and we have a fundef but we
4837 : haven't lowered invisirefs yet (c++/70344). */
4838 187 : if (DECL_INITIAL (fun) == error_mark_node
4839 187 : || fun == current_function_decl)
4840 15 : error_at (loc, "%qD called in a constant expression before its "
4841 : "definition is complete", fun);
4842 172 : else if (DECL_INITIAL (fun))
4843 : {
4844 : /* The definition of fun was somehow unsuitable. But pretend
4845 : that lambda static thunks don't exist. */
4846 134 : if (!lambda_static_thunk_p (fun))
4847 122 : error_at (loc, "%qD called in a constant expression", fun);
4848 134 : explain_invalid_constexpr_fn (fun);
4849 : }
4850 : else
4851 38 : error_at (loc, "%qD used before its definition", fun);
4852 : }
4853 587169 : *non_constant_p = true;
4854 587169 : return t;
4855 : }
4856 : }
4857 :
4858 : /* Don't complain about problems evaluating an ill-formed function. */
4859 110077934 : if (function *f = DECL_STRUCT_FUNCTION (fun))
4860 110077934 : if (f->language->erroneous)
4861 978 : new_ctx.quiet = true;
4862 :
4863 110077934 : int depth_ok = push_cx_call_context (t);
4864 :
4865 : /* Remember the object we are constructing or destructing. */
4866 110077934 : tree new_obj = NULL_TREE;
4867 220155868 : if (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))
4868 : {
4869 : /* In a cdtor, it should be the first `this' argument.
4870 : At this point it has already been evaluated in the call
4871 : to cxx_bind_parameters_in_call. */
4872 13814226 : new_obj = TREE_VEC_ELT (new_call.bindings, 0);
4873 13814226 : bool empty_base = false;
4874 13814226 : new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj,
4875 : &empty_base, jump_target);
4876 13814226 : if (*jump_target)
4877 0 : return NULL_TREE;
4878 : /* If we're initializing an empty class, don't set constness, because
4879 : cxx_fold_indirect_ref will return the wrong object to set constness
4880 : of. */
4881 13814226 : if (empty_base)
4882 : new_obj = NULL_TREE;
4883 6891968 : else if (ctx->call && ctx->call->fundef
4884 25022807 : && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl))
4885 : {
4886 3608153 : tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0);
4887 3608153 : STRIP_NOPS (cur_obj);
4888 3608153 : if (TREE_CODE (cur_obj) == ADDR_EXPR)
4889 3605670 : cur_obj = TREE_OPERAND (cur_obj, 0);
4890 3608153 : if (new_obj == cur_obj)
4891 : /* We're calling the target constructor of a delegating
4892 : constructor, or accessing a base subobject through a
4893 : NOP_EXPR as part of a call to a base constructor, so
4894 : there is no new (sub)object. */
4895 13814226 : new_obj = NULL_TREE;
4896 : }
4897 : }
4898 :
4899 110077934 : tree result = NULL_TREE;
4900 :
4901 110077934 : constexpr_call *entry = NULL;
4902 110077934 : if (depth_ok && !non_constant_args && ctx->strict)
4903 : {
4904 37138139 : new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
4905 37138139 : new_call.hash
4906 37138139 : = iterative_hash_template_arg (new_call.bindings, new_call.hash);
4907 :
4908 : /* If we have seen this call before, we are done. */
4909 37138139 : maybe_initialize_constexpr_call_table ();
4910 37138139 : bool insert = depth_ok < constexpr_cache_depth;
4911 37138139 : constexpr_call **slot
4912 50537549 : = constexpr_call_table->find_slot (&new_call,
4913 : insert ? INSERT : NO_INSERT);
4914 37138139 : entry = slot ? *slot : NULL;
4915 32586622 : if (entry == NULL)
4916 : {
4917 : /* Only cache up to constexpr_cache_depth to limit memory use. */
4918 9220512 : if (insert)
4919 : {
4920 : /* We need to keep a pointer to the entry, not just the slot, as
4921 : the slot can move during evaluation of the body. */
4922 4668995 : *slot = entry = ggc_alloc<constexpr_call> ();
4923 4668995 : *entry = new_call;
4924 4668995 : entry->result (ctx->manifestly_const_eval) = unknown_type_node;
4925 4668995 : fb.preserve ();
4926 :
4927 : /* Unshare args going into the hash table to separate them
4928 : from the caller's context, for better GC and to avoid
4929 : problems with verify_gimple. */
4930 4668995 : tree bound = new_call.bindings;
4931 7550956 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
4932 : {
4933 2881961 : tree &arg = TREE_VEC_ELT (bound, i);
4934 2881961 : arg = unshare_expr_without_location (arg);
4935 : }
4936 : }
4937 : }
4938 : /* Calls that are in progress have their result set to unknown_type_node,
4939 : so that we can detect circular dependencies. Now that we only cache
4940 : up to constexpr_cache_depth this won't catch circular dependencies that
4941 : start deeper, but they'll hit the recursion or ops limit. */
4942 27917627 : else if (entry->result (ctx->manifestly_const_eval) == unknown_type_node)
4943 : {
4944 6 : if (!ctx->quiet)
4945 0 : error ("call has circular dependency");
4946 6 : *non_constant_p = true;
4947 6 : entry->result (ctx->manifestly_const_eval) = result = error_mark_node;
4948 : }
4949 : else
4950 27917621 : result = entry->result (ctx->manifestly_const_eval);
4951 : }
4952 :
4953 110077901 : if (!depth_ok)
4954 : {
4955 33 : if (!ctx->quiet)
4956 3 : error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
4957 : "%<-fconstexpr-depth=%> to increase the maximum)",
4958 : max_constexpr_depth);
4959 33 : *non_constant_p = true;
4960 33 : result = error_mark_node;
4961 : }
4962 : else
4963 : {
4964 110077901 : bool cacheable = !!entry;
4965 110077901 : if (result && result != error_mark_node)
4966 : /* OK */;
4967 87300997 : else if (!DECL_SAVED_TREE (fun))
4968 : {
4969 : /* When at_eof >= 3, cgraph has started throwing away
4970 : DECL_SAVED_TREE, so fail quietly. FIXME we get here because of
4971 : late code generation for VEC_INIT_EXPR, which needs to be
4972 : completely reconsidered. */
4973 0 : gcc_assert (at_eof >= 3 && ctx->quiet);
4974 0 : *non_constant_p = true;
4975 : }
4976 87300997 : else if (tree copy = get_fundef_copy (new_call.fundef))
4977 : {
4978 87300988 : tree body, parms, res;
4979 87300988 : releasing_vec ctors;
4980 :
4981 : /* Reuse or create a new unshared copy of this function's body. */
4982 87300988 : body = TREE_PURPOSE (copy);
4983 87300988 : parms = TREE_VALUE (copy);
4984 87300988 : res = TREE_TYPE (copy);
4985 :
4986 : /* Associate the bindings with the remapped parms. */
4987 87300988 : tree bound = new_call.bindings;
4988 87300988 : tree remapped = parms;
4989 213862077 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
4990 : {
4991 126561089 : tree arg = TREE_VEC_ELT (bound, i);
4992 126561089 : if (entry)
4993 : {
4994 : /* Unshare again so the callee doesn't change the
4995 : argument values in the hash table. XXX Could we unshare
4996 : lazily in cxx_eval_store_expression? */
4997 3122775 : arg = unshare_constructor (arg);
4998 3122775 : if (TREE_CODE (arg) == CONSTRUCTOR)
4999 882518 : vec_safe_push (ctors, arg);
5000 : }
5001 126561089 : ctx->global->put_value (remapped, arg);
5002 126561089 : remapped = DECL_CHAIN (remapped);
5003 : }
5004 87300988 : if (remapped)
5005 : {
5006 : /* We shouldn't have any parms without args, but fail gracefully
5007 : in error recovery. */
5008 6 : gcc_checking_assert (seen_error ());
5009 6 : *non_constant_p = true;
5010 : }
5011 : /* Add the RESULT_DECL to the values map, too. */
5012 87300988 : gcc_assert (!DECL_BY_REFERENCE (res));
5013 87300988 : ctx->global->put_value (res, NULL_TREE);
5014 :
5015 : /* Remember the current call we're evaluating. */
5016 87300988 : constexpr_ctx call_ctx = *ctx;
5017 87300988 : call_ctx.call = &new_call;
5018 87300988 : unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
5019 87300988 : unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
5020 87300988 : bool save_state_dependent = ctx->global->state_dependent;
5021 :
5022 : /* Make sure we fold std::is_constant_evaluated to true in an
5023 : immediate function. */
5024 174601976 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
5025 1452328 : call_ctx.manifestly_const_eval = mce_true;
5026 :
5027 : /* If this is a constexpr destructor, the object's const and volatile
5028 : semantics are no longer in effect; see [class.dtor]p5. */
5029 98481766 : if (new_obj && DECL_DESTRUCTOR_P (fun))
5030 1241171 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false,
5031 : non_constant_p, overflow_p, jump_target);
5032 :
5033 : /* If this is a constructor, we are beginning the lifetime of the
5034 : object we are initializing. */
5035 87300988 : if (new_obj
5036 22361556 : && DECL_CONSTRUCTOR_P (fun)
5037 9939607 : && TREE_CODE (new_obj) == COMPONENT_REF
5038 90137314 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE)
5039 : {
5040 8910 : tree ctor = build_constructor (TREE_TYPE (new_obj), NULL);
5041 8910 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
5042 8910 : tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj),
5043 : new_obj, ctor);
5044 8910 : cxx_eval_constant_expression (ctx, activate,
5045 : lval, non_constant_p, overflow_p,
5046 : jump_target);
5047 8910 : ggc_free (activate);
5048 8910 : if (*jump_target)
5049 0 : return NULL_TREE;
5050 : }
5051 :
5052 87300988 : ctx->global->state_dependent = false;
5053 :
5054 87300988 : tree jmp_target = NULL_TREE;
5055 87300988 : cxx_eval_constant_expression (&call_ctx, body,
5056 : vc_discard, non_constant_p, overflow_p,
5057 : &jmp_target);
5058 :
5059 87300984 : if (!*non_constant_p && throws (&jmp_target))
5060 : {
5061 3683 : result = NULL_TREE;
5062 3683 : cacheable = false;
5063 3683 : *jump_target = jmp_target;
5064 : }
5065 87297301 : else if (!*non_constant_p && TREE_THIS_VOLATILE (fun))
5066 : {
5067 : /* Return from a [[noreturn]] function. */
5068 11 : if (!ctx->quiet)
5069 5 : error ("%<[[noreturn]]%> call returns");
5070 11 : *non_constant_p = true;
5071 : }
5072 174594580 : else if (DECL_CONSTRUCTOR_P (fun))
5073 : /* This can be null for a subobject constructor call, in
5074 : which case what we care about is the initialization
5075 : side-effects rather than the value. We could get at the
5076 : value by evaluating *this, but we don't bother; there's
5077 : no need to put such a call in the hash table. */
5078 12405400 : result = lval ? ctx->object : ctx->ctor;
5079 74891890 : else if (VOID_TYPE_P (TREE_TYPE (res)))
5080 7334897 : result = void_node;
5081 : else
5082 : {
5083 67556993 : result = ctx->global->get_value (res);
5084 10992866 : if (result == NULL_TREE && !*non_constant_p
5085 67557213 : && !DECL_DESTRUCTOR_P (fun))
5086 : {
5087 110 : if (!ctx->quiet)
5088 6 : error ("%<constexpr%> call flows off the end "
5089 : "of the function");
5090 110 : *non_constant_p = true;
5091 : }
5092 : }
5093 :
5094 87300984 : if (ctx->global->state_dependent)
5095 59818 : cacheable = false;
5096 87300984 : ctx->global->state_dependent |= save_state_dependent;
5097 :
5098 : /* At this point, the object's constructor will have run, so
5099 : the object is no longer under construction, and its possible
5100 : 'const' semantics now apply. Make a note of this fact by
5101 : marking the CONSTRUCTOR TREE_READONLY. */
5102 98481762 : if (new_obj && DECL_CONSTRUCTOR_P (fun))
5103 9939607 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true,
5104 : non_constant_p, overflow_p, jump_target);
5105 :
5106 : /* Remove the parms/result from the values map. */
5107 87300984 : destroy_value_checked (ctx, res, non_constant_p);
5108 301163061 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
5109 126561093 : destroy_value_checked (ctx, parm, non_constant_p);
5110 :
5111 : /* Free any parameter CONSTRUCTORs we aren't returning directly. */
5112 88183502 : while (!ctors->is_empty ())
5113 : {
5114 882518 : tree c = ctors->pop ();
5115 882518 : if (c != result)
5116 882518 : free_constructor (c);
5117 : }
5118 :
5119 : /* Make the unshared function copy we used available for re-use. */
5120 87300984 : save_fundef_copy (fun, copy);
5121 :
5122 : /* If the call allocated some heap object that hasn't been
5123 : deallocated during the call, or if it deallocated some heap
5124 : object it has not allocated, the call isn't really stateless
5125 : for the constexpr evaluation and should not be cached.
5126 : It is fine if the call allocates something and deallocates it
5127 : too. */
5128 87300984 : if (cacheable
5129 97105783 : && (save_heap_alloc_count != ctx->global->heap_vars.length ()
5130 9800298 : || (save_heap_dealloc_count
5131 9800298 : != ctx->global->heap_dealloc_count)))
5132 : {
5133 4501 : tree heap_var;
5134 4501 : unsigned int i;
5135 4501 : if ((ctx->global->heap_vars.length ()
5136 4501 : - ctx->global->heap_dealloc_count)
5137 4501 : != save_heap_alloc_count - save_heap_dealloc_count)
5138 : cacheable = false;
5139 : else
5140 139075 : FOR_EACH_VEC_ELT_FROM (ctx->global->heap_vars, i, heap_var,
5141 : save_heap_alloc_count)
5142 136450 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
5143 : {
5144 : cacheable = false;
5145 : break;
5146 : }
5147 : }
5148 :
5149 : /* Rewrite all occurrences of the function's RESULT_DECL with the
5150 : current object under construction. */
5151 87300984 : if (!*non_constant_p
5152 72602072 : && ctx->object
5153 17223073 : && CLASS_TYPE_P (TREE_TYPE (res))
5154 90492576 : && !is_empty_class (TREE_TYPE (res)))
5155 : {
5156 2264790 : if (!same_type_ignoring_top_level_qualifiers_p
5157 2264790 : (TREE_TYPE (res), TREE_TYPE (ctx->object)))
5158 0 : *non_constant_p = true;
5159 2264790 : else if (replace_decl (&result, res, ctx->object))
5160 : {
5161 1791 : cacheable = false;
5162 1791 : result = cxx_eval_constant_expression (ctx, result, lval,
5163 : non_constant_p,
5164 : overflow_p,
5165 : jump_target);
5166 1791 : if (*jump_target)
5167 : {
5168 0 : cacheable = false;
5169 0 : result = NULL_TREE;
5170 : }
5171 : }
5172 : }
5173 :
5174 : /* Only cache a permitted result of a constant expression. */
5175 87299193 : if (cacheable && !reduced_constant_expression_p (result))
5176 : cacheable = false;
5177 :
5178 : /* Only cache a result without contract violations. */
5179 82251772 : if (cacheable && ctx->global->contract_statement)
5180 82547762 : cacheable = false;
5181 87300984 : }
5182 : else
5183 : /* Couldn't get a function copy to evaluate. */
5184 9 : *non_constant_p = true;
5185 :
5186 110077897 : if (result == error_mark_node)
5187 6 : *non_constant_p = true;
5188 110077897 : if (*non_constant_p || *overflow_p)
5189 14699077 : result = error_mark_node;
5190 95378820 : else if (!result)
5191 3954491 : result = void_node;
5192 110077897 : if (entry)
5193 : {
5194 65173240 : entry->result (ctx->manifestly_const_eval)
5195 32586620 : = cacheable ? result : error_mark_node;
5196 :
5197 32586620 : if (result != error_mark_node
5198 27603933 : && ctx->manifestly_const_eval == mce_unknown)
5199 : {
5200 : /* Evaluation succeeded and was independent of whether we're in a
5201 : manifestly constant-evaluated context, so we can also reuse
5202 : this result when evaluating this call with a fixed context. */
5203 1928210 : if (!entry->result (mce_true))
5204 715982 : entry->result (mce_true) = entry->result (mce_unknown);
5205 1928210 : if (!entry->result (mce_false))
5206 682763 : entry->result (mce_false) = entry->result (mce_unknown);
5207 : }
5208 : }
5209 : }
5210 :
5211 : /* The result of a constexpr function must be completely initialized.
5212 :
5213 : However, in C++20, a constexpr constructor doesn't necessarily have
5214 : to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
5215 : in order to detect reading an uninitialized object in constexpr instead
5216 : of value-initializing it. (reduced_constant_expression_p is expected to
5217 : take care of clearing the flag.) */
5218 110077930 : if (TREE_CODE (result) == CONSTRUCTOR
5219 110077930 : && (cxx_dialect < cxx20
5220 21476470 : || !DECL_CONSTRUCTOR_P (fun)))
5221 5265316 : clear_no_implicit_zero (result);
5222 :
5223 110077930 : pop_cx_call_context ();
5224 :
5225 : /* A virtual call with a zero-offset covariant return needs no thunk, so
5226 : constant evaluation can evaluate the final overrider directly. The
5227 : result then has the overrider's return type rather than the static type
5228 : of the call. Adjust after caching so a direct call can reuse the result
5229 : with its original type. */
5230 110077930 : if (!*non_constant_p
5231 95378976 : && !*overflow_p
5232 95378820 : && !*jump_target
5233 95375137 : && DECL_VIRTUAL_P (fun)
5234 26537 : && result != void_node
5235 2173 : && INDIRECT_TYPE_P (TREE_TYPE (t))
5236 110078939 : && !(same_type_ignoring_top_level_qualifiers_p
5237 1009 : (TREE_TYPE (result), TREE_TYPE (t))))
5238 11 : result = adjust_temp_type (TREE_TYPE (t), result);
5239 :
5240 110077930 : return result;
5241 185184763 : }
5242 :
5243 : /* Return true if T is a valid constant initializer. If a CONSTRUCTOR
5244 : initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
5245 : cleared. If called recursively on a FIELD_DECL's CONSTRUCTOR, SZ
5246 : is DECL_SIZE of the FIELD_DECL, otherwise NULL.
5247 : UNION_ELEMENTAL_SUBOBJECT is true when recursing on union elemental
5248 : subobjects.
5249 : FIXME speed this up, it's taking 16% of compile time on sieve testcase. */
5250 :
5251 : bool
5252 1252273314 : reduced_constant_expression_p (tree t, tree sz /* = NULL_TREE */,
5253 : bool union_elemental_subobject /* = false */)
5254 : {
5255 1252273314 : if (t == NULL_TREE)
5256 : return false;
5257 :
5258 1247296041 : switch (TREE_CODE (t))
5259 : {
5260 : case PTRMEM_CST:
5261 : case REFLECT_EXPR:
5262 : /* Even if we can't lower this yet, it's constant. */
5263 : return true;
5264 :
5265 : case OMP_DECLARE_MAPPER:
5266 : return true;
5267 :
5268 64272749 : case CONSTRUCTOR:
5269 : /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
5270 64272749 : tree field;
5271 64272749 : if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
5272 : /* A constant vector would be folded to VECTOR_CST.
5273 : A CONSTRUCTOR of scalar type means uninitialized. */
5274 : return false;
5275 64256170 : if (CONSTRUCTOR_NO_CLEARING (t))
5276 : {
5277 3516137 : if (union_elemental_subobject
5278 5261 : && cxx_dialect >= cxx26
5279 1954 : && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
5280 3517339 : && CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (t))
5281 : field = NULL_TREE;
5282 3515769 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
5283 : {
5284 : /* There must be a valid constant initializer at every array
5285 : index. */
5286 6089 : tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
5287 6089 : tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
5288 6089 : tree cursor = min;
5289 96687 : for (auto &e: CONSTRUCTOR_ELTS (t))
5290 : {
5291 78639 : if (!reduced_constant_expression_p
5292 78639 : (e.value, NULL_TREE, union_elemental_subobject))
5293 : return false;
5294 78480 : if (array_index_cmp (cursor, e.index) != 0)
5295 : return false;
5296 78420 : if (TREE_CODE (e.index) == RANGE_EXPR)
5297 0 : cursor = TREE_OPERAND (e.index, 1);
5298 78420 : if (TREE_CODE (e.value) == RAW_DATA_CST)
5299 0 : cursor
5300 0 : = int_const_binop (PLUS_EXPR, cursor,
5301 0 : size_int (RAW_DATA_LENGTH (e.value)));
5302 : else
5303 78420 : cursor = int_const_binop (PLUS_EXPR, cursor,
5304 78420 : size_one_node);
5305 : }
5306 5870 : if (find_array_ctor_elt (t, max) == -1)
5307 : return false;
5308 5599 : goto ok;
5309 : }
5310 3509680 : else if (cxx_dialect >= cxx20
5311 3509680 : && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
5312 : {
5313 : /* A union can have at most one active member. A union with no
5314 : active member has no constituent values, so all constituent
5315 : values are constant. */
5316 : field = NULL_TREE;
5317 : union_elemental_subobject = true;
5318 : }
5319 : else
5320 : {
5321 3506104 : field = next_subobject_field (TYPE_FIELDS (TREE_TYPE (t)));
5322 3506104 : union_elemental_subobject = false;
5323 : }
5324 : }
5325 : else
5326 : {
5327 60740033 : field = NULL_TREE;
5328 60740033 : if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
5329 : union_elemental_subobject = true;
5330 59780139 : else if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE)
5331 56910357 : union_elemental_subobject = false;
5332 : }
5333 605170010 : for (auto &e: CONSTRUCTOR_ELTS (t))
5334 : {
5335 : /* If VAL is null, we're in the middle of initializing this
5336 : element. */
5337 472701708 : if (!reduced_constant_expression_p (e.value,
5338 472701708 : (e.index
5339 472701672 : && (TREE_CODE (e.index)
5340 : == FIELD_DECL))
5341 59626543 : ? DECL_SIZE (e.index)
5342 : : NULL_TREE,
5343 : union_elemental_subobject))
5344 : return false;
5345 : /* We want to remove initializers for empty fields in a struct to
5346 : avoid confusing output_constructor. */
5347 472123994 : if (is_empty_field (e.index)
5348 472123994 : && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
5349 : return false;
5350 : /* Check for non-empty fields between initialized fields when
5351 : CONSTRUCTOR_NO_CLEARING. */
5352 470996107 : for (; field && e.index != field;
5353 384764 : field = next_subobject_field (DECL_CHAIN (field)))
5354 389520 : if (!is_really_empty_class (TREE_TYPE (field),
5355 : /*ignore_vptr*/false))
5356 : return false;
5357 470606587 : if (field)
5358 3994980 : field = next_subobject_field (DECL_CHAIN (field));
5359 : }
5360 : /* There could be a non-empty field at the end. */
5361 62444145 : for (; field; field = next_subobject_field (DECL_CHAIN (field)))
5362 296003 : if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false))
5363 : {
5364 : /* Ignore FIELD_DECLs with bit positions beyond DECL_SIZE of
5365 : the parent FIELD_DECL (if any) for classes with virtual
5366 : bases. */
5367 6818 : if (cxx_dialect >= cxx26
5368 4337 : && sz
5369 7340 : && tree_int_cst_le (sz, bit_position (field)))
5370 : break;
5371 : return false;
5372 : }
5373 62148142 : ok:
5374 62154133 : if (CONSTRUCTOR_NO_CLEARING (t))
5375 : /* All the fields are initialized. */
5376 3382670 : CONSTRUCTOR_NO_CLEARING (t) = false;
5377 : return true;
5378 :
5379 1182754334 : default:
5380 : /* FIXME are we calling this too much? */
5381 1182754334 : return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
5382 : }
5383 : }
5384 :
5385 : /* *TP was not deemed constant by reduced_constant_expression_p. Explain
5386 : why and suggest what could be done about it. */
5387 :
5388 : static tree
5389 1608 : verify_constant_explain_r (tree *tp, int *walk_subtrees, void *)
5390 : {
5391 1608 : bool ref_p = false;
5392 :
5393 : /* No need to look into types or unevaluated operands. */
5394 1608 : if (TYPE_P (*tp) || unevaluated_p (TREE_CODE (*tp)))
5395 : {
5396 0 : *walk_subtrees = false;
5397 0 : return NULL_TREE;
5398 : }
5399 :
5400 1608 : switch (TREE_CODE (*tp))
5401 : {
5402 106 : CASE_CONVERT:
5403 106 : if (TREE_CODE (TREE_OPERAND (*tp, 0)) != ADDR_EXPR)
5404 : break;
5405 87 : ref_p = TYPE_REF_P (TREE_TYPE (*tp));
5406 87 : *tp = TREE_OPERAND (*tp, 0);
5407 219 : gcc_fallthrough ();
5408 219 : case ADDR_EXPR:
5409 219 : {
5410 219 : tree op = TREE_OPERAND (*tp, 0);
5411 219 : if (VAR_P (op)
5412 118 : && DECL_DECLARED_CONSTEXPR_P (op)
5413 41 : && !TREE_STATIC (op)
5414 : /* ??? We should also say something about temporaries. */
5415 257 : && !DECL_ARTIFICIAL (op))
5416 : {
5417 33 : if (ref_p)
5418 12 : inform (location_of (*tp), "reference to %qD is not a constant "
5419 : "expression", op);
5420 : else
5421 21 : inform (location_of (*tp), "pointer to %qD is not a constant "
5422 : "expression", op);
5423 33 : const location_t op_loc = DECL_SOURCE_LOCATION (op);
5424 33 : rich_location richloc (line_table, op_loc);
5425 33 : richloc.add_fixit_insert_before (op_loc, "static ");
5426 33 : inform (&richloc,
5427 : "address of non-static constexpr variable %qD may differ on "
5428 : "each invocation of the enclosing function; add %<static%> "
5429 : "to give it a constant address", op);
5430 33 : }
5431 : break;
5432 : }
5433 : default:
5434 : break;
5435 : }
5436 :
5437 : return NULL_TREE;
5438 : }
5439 :
5440 : /* Some expressions may have constant operands but are not constant
5441 : themselves, such as 1/0. Call this function to check for that
5442 : condition.
5443 :
5444 : We only call this in places that require an arithmetic constant, not in
5445 : places where we might have a non-constant expression that can be a
5446 : component of a constant expression, such as the address of a constexpr
5447 : variable that might be dereferenced later. */
5448 :
5449 : static bool
5450 677635200 : verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
5451 : bool *overflow_p)
5452 : {
5453 664599954 : if (!*non_constant_p && !reduced_constant_expression_p (t)
5454 680577592 : && t != void_node)
5455 : {
5456 2941949 : if (!allow_non_constant)
5457 : {
5458 424 : auto_diagnostic_group d;
5459 581 : error_at (cp_expr_loc_or_input_loc (t),
5460 : "%q+E is not a constant expression", t);
5461 424 : cp_walk_tree_without_duplicates (&t, verify_constant_explain_r,
5462 : nullptr);
5463 424 : }
5464 2941949 : *non_constant_p = true;
5465 : }
5466 677635200 : if (TREE_OVERFLOW_P (t))
5467 : {
5468 678 : if (!allow_non_constant)
5469 : {
5470 155 : permerror (input_location, "overflow in constant expression");
5471 : /* If we're being permissive (and are in an enforcing
5472 : context), ignore the overflow. */
5473 155 : if (flag_permissive)
5474 75 : return *non_constant_p;
5475 : }
5476 603 : *overflow_p = true;
5477 : }
5478 677635125 : return *non_constant_p;
5479 : }
5480 :
5481 : /* Check whether the shift operation with code CODE and type TYPE on LHS
5482 : and RHS is undefined. If it is, give an error with an explanation,
5483 : and return true; return false otherwise. */
5484 :
5485 : static bool
5486 80623823 : cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
5487 : enum tree_code code, tree type, tree lhs, tree rhs)
5488 : {
5489 80623823 : if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
5490 5563171 : || TREE_CODE (lhs) != INTEGER_CST
5491 5562895 : || TREE_CODE (rhs) != INTEGER_CST)
5492 : return false;
5493 :
5494 5562895 : tree lhstype = TREE_TYPE (lhs);
5495 5562895 : unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
5496 :
5497 : /* [expr.shift] The behavior is undefined if the right operand
5498 : is negative, or greater than or equal to the length in bits
5499 : of the promoted left operand. */
5500 5562895 : if (tree_int_cst_sgn (rhs) == -1)
5501 : {
5502 126 : if (!ctx->quiet)
5503 35 : permerror (loc, "right operand of shift expression %q+E is negative",
5504 : build2_loc (loc, code, type, lhs, rhs));
5505 126 : return (!flag_permissive || ctx->quiet);
5506 : }
5507 5562769 : if (compare_tree_int (rhs, uprec) >= 0)
5508 : {
5509 200 : if (!ctx->quiet)
5510 34 : permerror (loc, "right operand of shift expression %q+E is greater "
5511 : "than or equal to the precision %wu of the left operand",
5512 : build2_loc (loc, code, type, lhs, rhs), uprec);
5513 200 : return (!flag_permissive || ctx->quiet);
5514 : }
5515 :
5516 : /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
5517 : if E1 has a signed type and non-negative value, and E1x2^E2 is
5518 : representable in the corresponding unsigned type of the result type,
5519 : then that value, converted to the result type, is the resulting value;
5520 : otherwise, the behavior is undefined.
5521 : For C++20:
5522 : The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
5523 : 2^N, where N is the range exponent of the type of the result. */
5524 5562569 : if (code == LSHIFT_EXPR
5525 4648814 : && !TYPE_OVERFLOW_WRAPS (lhstype)
5526 2201793 : && cxx_dialect >= cxx11
5527 7744311 : && cxx_dialect < cxx20)
5528 : {
5529 54036 : if (tree_int_cst_sgn (lhs) == -1)
5530 : {
5531 74 : if (!ctx->quiet)
5532 18 : permerror (loc,
5533 : "left operand of shift expression %q+E is negative",
5534 : build2_loc (loc, code, type, lhs, rhs));
5535 74 : return (!flag_permissive || ctx->quiet);
5536 : }
5537 : /* For signed x << y the following:
5538 : (unsigned) x >> ((prec (lhs) - 1) - y)
5539 : if > 1, is undefined. The right-hand side of this formula
5540 : is the highest bit of the LHS that can be set (starting from 0),
5541 : so that the shift doesn't overflow. We then right-shift the LHS
5542 : to see whether any other bit is set making the original shift
5543 : undefined -- the result is not representable in the corresponding
5544 : unsigned type. */
5545 53962 : tree t = build_int_cst (unsigned_type_node, uprec - 1);
5546 53962 : t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
5547 53962 : tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
5548 53962 : t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
5549 53962 : if (tree_int_cst_lt (integer_one_node, t))
5550 : {
5551 41 : if (!ctx->quiet)
5552 7 : permerror (loc, "shift expression %q+E overflows",
5553 : build2_loc (loc, code, type, lhs, rhs));
5554 41 : return (!flag_permissive || ctx->quiet);
5555 : }
5556 : }
5557 : return false;
5558 : }
5559 :
5560 : /* Subroutine of cxx_eval_constant_expression.
5561 : Attempt to reduce the unary expression tree T to a compile time value.
5562 : If successful, return the value. Otherwise issue a diagnostic
5563 : and return error_mark_node. */
5564 :
5565 : static tree
5566 26018126 : cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
5567 : bool /*lval*/,
5568 : bool *non_constant_p, bool *overflow_p,
5569 : tree *jump_target)
5570 : {
5571 26018126 : tree r;
5572 26018126 : tree orig_arg = TREE_OPERAND (t, 0);
5573 26018126 : tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue,
5574 : non_constant_p, overflow_p,
5575 : jump_target);
5576 26018124 : if (*jump_target)
5577 : return NULL_TREE;
5578 26018122 : VERIFY_CONSTANT (arg);
5579 20753019 : location_t loc = EXPR_LOCATION (t);
5580 20753019 : enum tree_code code = TREE_CODE (t);
5581 20753019 : tree type = TREE_TYPE (t);
5582 20753019 : r = fold_unary_loc (loc, code, type, arg);
5583 20753019 : if (r == NULL_TREE)
5584 : {
5585 17 : if (arg == orig_arg)
5586 : r = t;
5587 : else
5588 13 : r = build1_loc (loc, code, type, arg);
5589 : }
5590 20753019 : VERIFY_CONSTANT (r);
5591 : return r;
5592 : }
5593 :
5594 : /* Helper function for cxx_eval_binary_expression. Try to optimize
5595 : original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
5596 : generic folding should be used. */
5597 :
5598 : static tree
5599 10973329 : cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
5600 : tree lhs, tree rhs, bool *non_constant_p,
5601 : bool *overflow_p, tree *jump_target)
5602 : {
5603 10973329 : STRIP_NOPS (lhs);
5604 10973329 : if (TREE_CODE (lhs) != ADDR_EXPR)
5605 : return NULL_TREE;
5606 :
5607 10104152 : lhs = TREE_OPERAND (lhs, 0);
5608 :
5609 : /* &A[i] p+ j => &A[i + j] */
5610 10104152 : if (TREE_CODE (lhs) == ARRAY_REF
5611 208619 : && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
5612 208619 : && TREE_CODE (rhs) == INTEGER_CST
5613 208619 : && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
5614 10312771 : && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
5615 : {
5616 208619 : tree orig_type = TREE_TYPE (t);
5617 208619 : location_t loc = EXPR_LOCATION (t);
5618 208619 : tree type = TREE_TYPE (lhs);
5619 :
5620 208619 : t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
5621 208619 : tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
5622 208619 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
5623 : non_constant_p, overflow_p,
5624 : jump_target);
5625 208619 : if (*non_constant_p)
5626 : return NULL_TREE;
5627 208607 : if (*jump_target)
5628 : return NULL_TREE;
5629 : /* Don't fold an out-of-bound access. */
5630 208607 : if (!tree_int_cst_le (t, nelts))
5631 : return NULL_TREE;
5632 208607 : rhs = cp_fold_convert (ssizetype, rhs);
5633 : /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
5634 : constexpr int A[1]; ... (char *)&A[0] + 1 */
5635 208607 : if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
5636 208607 : rhs, TYPE_SIZE_UNIT (type))))
5637 : return NULL_TREE;
5638 : /* Make sure to treat the second operand of POINTER_PLUS_EXPR
5639 : as signed. */
5640 208575 : rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
5641 208575 : TYPE_SIZE_UNIT (type));
5642 208575 : t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
5643 208575 : t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
5644 : t, NULL_TREE, NULL_TREE);
5645 208575 : t = cp_build_addr_expr (t, tf_warning_or_error);
5646 208575 : t = cp_fold_convert (orig_type, t);
5647 208575 : return cxx_eval_constant_expression (ctx, t, vc_prvalue,
5648 : non_constant_p, overflow_p,
5649 208575 : jump_target);
5650 : }
5651 :
5652 : return NULL_TREE;
5653 : }
5654 :
5655 : /* Try to fold expressions like
5656 : (struct S *) (&a[0].D.2378 + 12)
5657 : into
5658 : &MEM <struct T> [(void *)&a + 12B]
5659 : This is something normally done by gimple_fold_stmt_to_constant_1
5660 : on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
5661 : dereference the address because some details are lost.
5662 : For pointer comparisons we want such folding though so that
5663 : match.pd address_compare optimization works. */
5664 :
5665 : static tree
5666 12312308 : cxx_maybe_fold_addr_pointer_plus (tree t)
5667 : {
5668 24624622 : while (CONVERT_EXPR_P (t)
5669 13022935 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
5670 710621 : t = TREE_OPERAND (t, 0);
5671 12312308 : if (TREE_CODE (t) != POINTER_PLUS_EXPR)
5672 : return NULL_TREE;
5673 10607642 : tree op0 = TREE_OPERAND (t, 0);
5674 10607642 : tree op1 = TREE_OPERAND (t, 1);
5675 10607642 : if (TREE_CODE (op1) != INTEGER_CST)
5676 : return NULL_TREE;
5677 10607642 : while (CONVERT_EXPR_P (op0)
5678 21211736 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
5679 10604094 : op0 = TREE_OPERAND (op0, 0);
5680 10607642 : if (TREE_CODE (op0) != ADDR_EXPR)
5681 : return NULL_TREE;
5682 10607642 : op1 = fold_convert (ptr_type_node, op1);
5683 10607642 : tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
5684 10607642 : return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
5685 : }
5686 :
5687 : /* Subroutine of cxx_eval_constant_expression.
5688 : Like cxx_eval_unary_expression, except for binary expressions. */
5689 :
5690 : static tree
5691 112842931 : cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
5692 : value_cat lval,
5693 : bool *non_constant_p, bool *overflow_p,
5694 : tree *jump_target)
5695 : {
5696 112842931 : tree r = NULL_TREE;
5697 112842931 : tree orig_lhs = TREE_OPERAND (t, 0);
5698 112842931 : tree orig_rhs = TREE_OPERAND (t, 1);
5699 112842931 : tree lhs, rhs;
5700 :
5701 112842931 : if (TREE_CODE (t) == POINTER_PLUS_EXPR
5702 12753627 : && CONVERT_EXPR_P (orig_lhs)
5703 6749754 : && (lhs = TREE_OPERAND (orig_lhs, 0))
5704 6749754 : && INDIRECT_TYPE_P (TREE_TYPE (lhs))
5705 6749754 : && (TREE_CODE (orig_lhs) != NOP_EXPR || !REINTERPRET_CAST_P (orig_lhs))
5706 119592656 : && is_properly_derived_from (TREE_TYPE (TREE_TYPE (orig_lhs)),
5707 6749725 : TREE_TYPE (TREE_TYPE (lhs))))
5708 : /* fold_unary_loc and match.pd can optimize
5709 : (type *) (ptr p+ off) into ((type *) ptr) p+ off, which can break
5710 : static_cast constexpr diagnostics, because ptr before the p+
5711 : cast to type * can be invalid while the original valid.
5712 : Evaluate it as (type *) (ptr p+ off) instead. */
5713 : {
5714 42 : tree cast = copy_node (orig_lhs);
5715 42 : tree pplus = copy_node (t);
5716 42 : TREE_OPERAND (cast, 0) = pplus;
5717 42 : TREE_OPERAND (pplus, 0) = lhs;
5718 42 : TREE_TYPE (pplus) = TREE_TYPE (lhs);
5719 42 : lhs = cxx_eval_constant_expression (ctx, cast, vc_prvalue,
5720 : non_constant_p, overflow_p,
5721 : jump_target);
5722 42 : if (lhs != cast)
5723 : {
5724 24 : ggc_free (cast);
5725 24 : ggc_free (pplus);
5726 : }
5727 42 : if (*non_constant_p)
5728 : return t;
5729 42 : return lhs;
5730 : }
5731 :
5732 112842889 : lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue,
5733 : non_constant_p, overflow_p,
5734 : jump_target);
5735 : /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
5736 : subtraction. */
5737 112842887 : if (*non_constant_p)
5738 : return t;
5739 90915127 : if (*jump_target)
5740 : return NULL_TREE;
5741 90915032 : rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue,
5742 : non_constant_p, overflow_p,
5743 : jump_target);
5744 90915032 : if (*non_constant_p)
5745 : return t;
5746 89746205 : if (*jump_target)
5747 : return NULL_TREE;
5748 :
5749 89746199 : location_t loc = EXPR_LOCATION (t);
5750 89746199 : enum tree_code code = TREE_CODE (t);
5751 89746199 : tree type = TREE_TYPE (t);
5752 :
5753 89746199 : if (code == EQ_EXPR || code == NE_EXPR)
5754 : {
5755 18560431 : bool is_code_eq = (code == EQ_EXPR);
5756 :
5757 18560431 : if (TREE_CODE (lhs) == PTRMEM_CST
5758 217 : && TREE_CODE (rhs) == PTRMEM_CST)
5759 : {
5760 76 : tree lmem = PTRMEM_CST_MEMBER (lhs);
5761 76 : tree rmem = PTRMEM_CST_MEMBER (rhs);
5762 76 : bool eq;
5763 76 : if (TREE_CODE (lmem) == TREE_CODE (rmem)
5764 76 : && TREE_CODE (lmem) == FIELD_DECL
5765 76 : && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
5766 103 : && same_type_p (DECL_CONTEXT (lmem),
5767 : DECL_CONTEXT (rmem)))
5768 : /* If both refer to (possibly different) members of the same union
5769 : (12.3), they compare equal. */
5770 : eq = true;
5771 : else
5772 49 : eq = cp_tree_equal (lhs, rhs);
5773 76 : r = constant_boolean_node (eq == is_code_eq, type);
5774 76 : }
5775 18560355 : else if ((TREE_CODE (lhs) == PTRMEM_CST
5776 18560214 : || TREE_CODE (rhs) == PTRMEM_CST)
5777 18560355 : && (null_member_pointer_value_p (lhs)
5778 141 : || null_member_pointer_value_p (rhs)))
5779 141 : r = constant_boolean_node (!is_code_eq, type);
5780 18560214 : else if (TREE_CODE (lhs) == PTRMEM_CST)
5781 0 : lhs = cplus_expand_constant (lhs);
5782 18560214 : else if (TREE_CODE (rhs) == PTRMEM_CST)
5783 0 : rhs = cplus_expand_constant (rhs);
5784 37120428 : else if (REFLECTION_TYPE_P (TREE_TYPE (lhs))
5785 18564160 : && REFLECTION_TYPE_P (TREE_TYPE (rhs)))
5786 : {
5787 3946 : const bool eq = compare_reflections (lhs, rhs);
5788 3946 : r = constant_boolean_node (eq == is_code_eq, type);
5789 : }
5790 : }
5791 0 : if (r == NULL_TREE
5792 89742036 : && TREE_CODE_CLASS (code) == tcc_comparison
5793 39457145 : && POINTER_TYPE_P (TREE_TYPE (lhs)))
5794 : {
5795 6156154 : if (tree lhso = cxx_maybe_fold_addr_pointer_plus (lhs))
5796 5157575 : lhs = fold_convert (TREE_TYPE (lhs), lhso);
5797 6156154 : if (tree rhso = cxx_maybe_fold_addr_pointer_plus (rhs))
5798 5450067 : rhs = fold_convert (TREE_TYPE (rhs), rhso);
5799 : }
5800 10973484 : if (code == POINTER_PLUS_EXPR && !*non_constant_p
5801 100719683 : && integer_zerop (lhs) && !integer_zerop (rhs))
5802 : {
5803 155 : if (!ctx->quiet)
5804 45 : error ("arithmetic involving a null pointer in %qE", lhs);
5805 155 : *non_constant_p = true;
5806 155 : return t;
5807 : }
5808 89746044 : else if (code == POINTER_PLUS_EXPR)
5809 : {
5810 10973329 : r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
5811 : overflow_p, jump_target);
5812 10973329 : if (*jump_target)
5813 : return NULL_TREE;
5814 : }
5815 78772715 : else if (code == SPACESHIP_EXPR)
5816 : {
5817 27406 : r = genericize_spaceship (loc, type, lhs, rhs);
5818 27406 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
5819 27406 : overflow_p, jump_target);
5820 : }
5821 :
5822 89718638 : if (r == NULL_TREE)
5823 : {
5824 89505900 : if (ctx->manifestly_const_eval == mce_true
5825 68490749 : && (flag_constexpr_fp_except
5826 68490746 : || TREE_CODE (type) != REAL_TYPE))
5827 : {
5828 68436933 : auto ofcc = make_temp_override (folding_cxx_constexpr, true);
5829 68436933 : r = fold_binary_initializer_loc (loc, code, type, lhs, rhs);
5830 68436933 : }
5831 : else
5832 21068967 : r = fold_binary_loc (loc, code, type, lhs, rhs);
5833 : }
5834 :
5835 89505900 : if (r == NULL_TREE
5836 9094913 : && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
5837 100 : && TREE_CODE (lhs) == INTEGER_CST
5838 98 : && TREE_CODE (rhs) == INTEGER_CST
5839 98813551 : && wi::neg_p (wi::to_wide (rhs)))
5840 : {
5841 : /* For diagnostics and -fpermissive emulate previous behavior of
5842 : handling shifts by negative amount. */
5843 98 : tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
5844 98 : if (nrhs)
5845 119 : r = fold_binary_loc (loc,
5846 : code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
5847 : type, lhs, nrhs);
5848 : }
5849 :
5850 89718638 : if (r == NULL_TREE)
5851 : {
5852 9094815 : if (lhs == orig_lhs && rhs == orig_rhs)
5853 : r = t;
5854 : else
5855 3151775 : r = build2_loc (loc, code, type, lhs, rhs);
5856 : }
5857 80623823 : else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
5858 433 : *non_constant_p = true;
5859 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
5860 : a local array in a constexpr function. */
5861 89718638 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
5862 71900783 : if (!ptr)
5863 71900783 : VERIFY_CONSTANT (r);
5864 : return r;
5865 : }
5866 :
5867 : /* Subroutine of cxx_eval_constant_expression.
5868 : Attempt to evaluate condition expressions. */
5869 :
5870 : static tree
5871 39508619 : cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
5872 : value_cat lval,
5873 : bool *non_constant_p, bool *overflow_p,
5874 : tree *jump_target)
5875 : {
5876 39508619 : tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5877 : vc_prvalue,
5878 : non_constant_p, overflow_p,
5879 : jump_target);
5880 39508619 : if (*jump_target)
5881 : return NULL_TREE;
5882 39508595 : VERIFY_CONSTANT (val);
5883 37196103 : if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
5884 : {
5885 : /* Evaluate the condition as if it was
5886 : if (__builtin_is_constant_evaluated ()), i.e. defer it if not
5887 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
5888 : without manifestly_const_eval even expressions or parts thereof which
5889 : will later be manifestly const_eval evaluated), otherwise fold it to
5890 : true. */
5891 1069950 : if (ctx->manifestly_const_eval == mce_unknown)
5892 : {
5893 967641 : *non_constant_p = true;
5894 967641 : return t;
5895 : }
5896 102309 : val = constant_boolean_node (ctx->manifestly_const_eval == mce_true,
5897 : boolean_type_node);
5898 : }
5899 : /* Don't VERIFY_CONSTANT the other operands. */
5900 36228462 : const bool zero_p = integer_zerop (val);
5901 36228462 : if (zero_p)
5902 22830974 : val = TREE_OPERAND (t, 2);
5903 : else
5904 13397488 : val = TREE_OPERAND (t, 1);
5905 36228462 : if (TREE_CODE (t) == IF_STMT && !val)
5906 9950469 : val = void_node;
5907 :
5908 : /* P2564: If we aren't in immediate function context (including a manifestly
5909 : constant-evaluated expression), check any uses of immediate functions in
5910 : the arm we're discarding. But don't do this inside a call; we already
5911 : checked when parsing the function. */
5912 36228462 : if (ctx->manifestly_const_eval != mce_true
5913 5122208 : && !in_immediate_context ()
5914 5024328 : && !ctx->call
5915 37038259 : && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2),
5916 809797 : ctx->manifestly_const_eval))
5917 : {
5918 7 : *non_constant_p = true;
5919 7 : return t;
5920 : }
5921 :
5922 : /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still
5923 : serve as the initializer for the same object as the outer TARGET_EXPR,
5924 : as in
5925 : A a = true ? A{} : A{};
5926 : so strip the inner TARGET_EXPR so we don't materialize a temporary. */
5927 36228455 : if (TREE_CODE (val) == TARGET_EXPR)
5928 5341 : val = TARGET_EXPR_INITIAL (val);
5929 36228455 : return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
5930 36228455 : overflow_p, jump_target);
5931 : }
5932 :
5933 : /* Subroutine of cxx_eval_constant_expression.
5934 : Attempt to evaluate vector condition expressions. Unlike
5935 : cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
5936 : ternary arithmetics operation, where all 3 arguments have to be
5937 : evaluated as constants and then folding computes the result from
5938 : them. */
5939 :
5940 : static tree
5941 11755 : cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
5942 : bool *non_constant_p, bool *overflow_p,
5943 : tree *jump_target)
5944 : {
5945 11755 : tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5946 : vc_prvalue,
5947 : non_constant_p, overflow_p,
5948 : jump_target);
5949 11755 : if (*jump_target)
5950 : return NULL_TREE;
5951 11755 : VERIFY_CONSTANT (arg1);
5952 8227 : tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
5953 : vc_prvalue,
5954 : non_constant_p, overflow_p,
5955 : jump_target);
5956 8227 : if (*jump_target)
5957 : return NULL_TREE;
5958 8227 : VERIFY_CONSTANT (arg2);
5959 7097 : tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
5960 : vc_prvalue,
5961 : non_constant_p, overflow_p,
5962 : jump_target);
5963 7097 : if (*jump_target)
5964 : return NULL_TREE;
5965 7097 : VERIFY_CONSTANT (arg3);
5966 7097 : location_t loc = EXPR_LOCATION (t);
5967 7097 : tree type = TREE_TYPE (t);
5968 7097 : tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5969 7097 : if (r == NULL_TREE)
5970 : {
5971 0 : if (arg1 == TREE_OPERAND (t, 0)
5972 0 : && arg2 == TREE_OPERAND (t, 1)
5973 0 : && arg3 == TREE_OPERAND (t, 2))
5974 : r = t;
5975 : else
5976 0 : r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5977 : }
5978 7097 : VERIFY_CONSTANT (r);
5979 : return r;
5980 : }
5981 :
5982 : /* Returns less than, equal to, or greater than zero if KEY is found to be
5983 : less than, to match, or to be greater than the constructor_elt's INDEX. */
5984 :
5985 : static int
5986 440195 : array_index_cmp (tree key, tree index)
5987 : {
5988 440195 : gcc_assert (TREE_CODE (key) == INTEGER_CST);
5989 :
5990 440195 : switch (TREE_CODE (index))
5991 : {
5992 437251 : case INTEGER_CST:
5993 437251 : return tree_int_cst_compare (key, index);
5994 2944 : case RANGE_EXPR:
5995 2944 : {
5996 2944 : tree lo = TREE_OPERAND (index, 0);
5997 2944 : tree hi = TREE_OPERAND (index, 1);
5998 2944 : if (tree_int_cst_lt (key, lo))
5999 : return -1;
6000 2648 : else if (tree_int_cst_lt (hi, key))
6001 : return 1;
6002 : else
6003 2648 : return 0;
6004 : }
6005 0 : default:
6006 0 : gcc_unreachable ();
6007 : }
6008 : }
6009 :
6010 : /* Extract a single INTEGER_CST from RAW_DATA_CST RAW_DATA at
6011 : relative index OFF. */
6012 :
6013 : static tree
6014 29559 : raw_data_cst_elt (tree raw_data, unsigned int off)
6015 : {
6016 29559 : return build_int_cst (TREE_TYPE (raw_data),
6017 29559 : TYPE_UNSIGNED (TREE_TYPE (raw_data))
6018 59118 : ? (HOST_WIDE_INT)
6019 29073 : RAW_DATA_UCHAR_ELT (raw_data, off)
6020 : : (HOST_WIDE_INT)
6021 486 : RAW_DATA_SCHAR_ELT (raw_data, off));
6022 : }
6023 :
6024 : /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
6025 : if none. If INSERT is true, insert a matching element rather than fail. */
6026 :
6027 : static HOST_WIDE_INT
6028 12546346 : find_array_ctor_elt (tree ary, tree dindex, bool insert)
6029 : {
6030 12546346 : if (tree_int_cst_sgn (dindex) < 0)
6031 : return -1;
6032 :
6033 12546346 : unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex);
6034 12546346 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary);
6035 12546346 : unsigned HOST_WIDE_INT len = vec_safe_length (elts);
6036 :
6037 16808002 : unsigned HOST_WIDE_INT end = len;
6038 16808002 : unsigned HOST_WIDE_INT begin = 0;
6039 :
6040 : /* If the last element of the CONSTRUCTOR has its own index, we can assume
6041 : that the same is true of the other elements and index directly. */
6042 11989433 : if (end > 0)
6043 : {
6044 11760477 : tree cindex = (*elts)[end - 1].index;
6045 11760477 : if (cindex == NULL_TREE)
6046 : {
6047 : /* Verify that if the last index is missing, all indexes
6048 : are missing and there is no RAW_DATA_CST. */
6049 21871 : if (flag_checking)
6050 220441 : for (unsigned int j = 0; j < len - 1; ++j)
6051 198570 : gcc_assert ((*elts)[j].index == NULL_TREE
6052 : && TREE_CODE ((*elts)[j].value) != RAW_DATA_CST);
6053 21871 : if (i < end)
6054 21871 : return i;
6055 : else
6056 : {
6057 0 : begin = end;
6058 0 : if (i == end)
6059 : /* If the element is to be added right at the end,
6060 : make sure it is added with cleared index too. */
6061 4818569 : dindex = NULL_TREE;
6062 0 : else if (insert)
6063 : /* Otherwise, in order not to break the assumption
6064 : that CONSTRUCTOR either has all indexes or none,
6065 : we need to add indexes to all elements. */
6066 0 : for (unsigned int j = 0; j < len; ++j)
6067 0 : (*elts)[j].index = build_int_cst (TREE_TYPE (dindex), j);
6068 : }
6069 : }
6070 11738606 : else if (TREE_CODE (cindex) == INTEGER_CST
6071 11738606 : && compare_tree_int (cindex, end - 1) == 0)
6072 : {
6073 11527518 : tree value = (*elts)[end - 1].value;
6074 11527518 : if (i < end)
6075 : {
6076 7705996 : if (i == end - 1 && TREE_CODE (value) == RAW_DATA_CST)
6077 : begin = end - 1;
6078 : else
6079 7705906 : return i;
6080 : }
6081 3821522 : else if (TREE_CODE (value) == RAW_DATA_CST
6082 3853678 : && wi::to_offset (dindex) < (wi::to_offset (cindex)
6083 32156 : + RAW_DATA_LENGTH (value)))
6084 16078 : begin = end - 1;
6085 : else
6086 3805444 : begin = end;
6087 : }
6088 : }
6089 :
6090 : /* Otherwise, find a matching index by means of a binary search. */
6091 5023348 : while (begin != end)
6092 : {
6093 361712 : unsigned HOST_WIDE_INT middle = (begin + end) / 2;
6094 361712 : constructor_elt &elt = (*elts)[middle];
6095 361712 : tree idx = elt.index;
6096 :
6097 361712 : int cmp = array_index_cmp (dindex, idx);
6098 361712 : if (cmp > 0
6099 66757 : && TREE_CODE (elt.value) == RAW_DATA_CST
6100 445520 : && wi::to_offset (dindex) < (wi::to_offset (idx)
6101 83808 : + RAW_DATA_LENGTH (elt.value)))
6102 29417 : cmp = 0;
6103 361712 : if (cmp < 0)
6104 : end = middle;
6105 194273 : else if (cmp > 0)
6106 37340 : begin = middle + 1;
6107 : else
6108 : {
6109 156933 : if (insert && TREE_CODE (elt.value) == RAW_DATA_CST)
6110 : {
6111 : /* We need to split the RAW_DATA_CST elt. */
6112 122 : constructor_elt e;
6113 122 : gcc_checking_assert (TREE_CODE (idx) != RANGE_EXPR);
6114 244 : unsigned int off = (wi::to_offset (dindex)
6115 244 : - wi::to_offset (idx)).to_uhwi ();
6116 122 : tree value = elt.value;
6117 122 : unsigned int len = RAW_DATA_LENGTH (value);
6118 122 : if (off > 1 && len >= off + 3)
6119 22 : value = copy_node (elt.value);
6120 122 : if (off)
6121 : {
6122 33 : if (off > 1)
6123 33 : RAW_DATA_LENGTH (elt.value) = off;
6124 : else
6125 0 : elt.value = raw_data_cst_elt (elt.value, 0);
6126 33 : e.index = size_binop (PLUS_EXPR, elt.index,
6127 : build_int_cst (TREE_TYPE (elt.index),
6128 : off));
6129 33 : e.value = NULL_TREE;
6130 33 : ++middle;
6131 33 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
6132 : }
6133 122 : (*elts)[middle].value = raw_data_cst_elt (value, off);
6134 122 : if (len >= off + 2)
6135 : {
6136 111 : e.index = (*elts)[middle].index;
6137 111 : e.index = size_binop (PLUS_EXPR, e.index,
6138 : build_one_cst (TREE_TYPE (e.index)));
6139 111 : if (len >= off + 3)
6140 : {
6141 111 : RAW_DATA_LENGTH (value) -= off + 1;
6142 111 : RAW_DATA_POINTER (value) += off + 1;
6143 111 : e.value = value;
6144 : }
6145 : else
6146 0 : e.value = raw_data_cst_elt (value, off + 1);
6147 111 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
6148 : }
6149 122 : return middle;
6150 : }
6151 35919 : if (insert && TREE_CODE (idx) == RANGE_EXPR)
6152 : {
6153 : /* We need to split the range. */
6154 361 : constructor_elt e;
6155 361 : tree lo = TREE_OPERAND (idx, 0);
6156 361 : tree hi = TREE_OPERAND (idx, 1);
6157 361 : tree value = elt.value;
6158 361 : dindex = fold_convert (sizetype, dindex);
6159 361 : if (tree_int_cst_lt (lo, dindex))
6160 : {
6161 : /* There are still some lower elts; shorten the range. */
6162 194 : tree new_hi = int_const_binop (MINUS_EXPR, dindex,
6163 97 : size_one_node);
6164 97 : if (tree_int_cst_equal (lo, new_hi))
6165 : /* Only one element left, no longer a range. */
6166 42 : elt.index = lo;
6167 : else
6168 55 : TREE_OPERAND (idx, 1) = new_hi;
6169 : /* Append the element we want to insert. */
6170 97 : ++middle;
6171 97 : e.index = dindex;
6172 97 : e.value = unshare_constructor (value);
6173 97 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
6174 : }
6175 : else
6176 : /* No lower elts, the range elt is now ours. */
6177 264 : elt.index = dindex;
6178 :
6179 361 : if (tree_int_cst_lt (dindex, hi))
6180 : {
6181 : /* There are still some higher elts; append a range. */
6182 506 : tree new_lo = int_const_binop (PLUS_EXPR, dindex,
6183 253 : size_one_node);
6184 253 : if (tree_int_cst_equal (new_lo, hi))
6185 : e.index = hi;
6186 : else
6187 153 : e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
6188 253 : e.value = unshare_constructor (value);
6189 253 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
6190 : }
6191 : }
6192 156811 : return middle;
6193 : }
6194 : }
6195 :
6196 4661636 : if (insert)
6197 : {
6198 4530970 : constructor_elt e = { dindex, NULL_TREE };
6199 4530970 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e);
6200 4530970 : return end;
6201 : }
6202 :
6203 : return -1;
6204 : }
6205 :
6206 : /* Return a pointer to the constructor_elt of CTOR which matches INDEX. If no
6207 : matching constructor_elt exists, then add one to CTOR.
6208 :
6209 : As an optimization, if POS_HINT is non-negative then it is used as a guess
6210 : for the (integer) index of the matching constructor_elt within CTOR.
6211 :
6212 : If POS_HINT is -2, it means do not insert. */
6213 :
6214 : static constructor_elt *
6215 42602890 : get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
6216 : {
6217 : /* Check the hint first. */
6218 4629451 : if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)
6219 47232341 : && CONSTRUCTOR_ELT (ctor, pos_hint)->index == index)
6220 : return CONSTRUCTOR_ELT (ctor, pos_hint);
6221 :
6222 37973451 : bool insertp = (pos_hint != -2);
6223 37973451 : tree type = TREE_TYPE (ctor);
6224 37973451 : if (TREE_CODE (type) == VECTOR_TYPE && index == NULL_TREE)
6225 : {
6226 27296 : gcc_assert (insertp);
6227 27296 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE);
6228 27296 : return &CONSTRUCTOR_ELTS (ctor)->last();
6229 : }
6230 37946155 : else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
6231 : {
6232 6213616 : if (TREE_CODE (index) == RANGE_EXPR)
6233 : {
6234 : /* Support for RANGE_EXPR index lookups is currently limited to
6235 : accessing an existing element via POS_HINT, or appending a new
6236 : element to the end of CTOR. ??? Support for other access
6237 : patterns may also be needed. */
6238 3 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
6239 3 : if (vec_safe_length (elts))
6240 : {
6241 3 : tree lo = TREE_OPERAND (index, 0);
6242 3 : gcc_assert (array_index_cmp (elts->last().index, lo) < 0);
6243 : }
6244 3 : gcc_assert (insertp);
6245 3 : CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE);
6246 3 : return &elts->last();
6247 : }
6248 :
6249 6213613 : HOST_WIDE_INT i = find_array_ctor_elt (ctor, index, insertp);
6250 6213613 : if (i < 0)
6251 : {
6252 2711 : gcc_assert (!insertp);
6253 : return nullptr;
6254 : }
6255 6210902 : constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i);
6256 6210902 : if (!insertp && cep->index && TREE_CODE (cep->index) == RANGE_EXPR)
6257 : {
6258 : /* Split a range even if we aren't inserting new entries. */
6259 0 : gcc_assert (!insertp);
6260 0 : i = find_array_ctor_elt (ctor, index, /*insert*/true);
6261 0 : gcc_assert (i >= 0);
6262 0 : cep = CONSTRUCTOR_ELT (ctor, i);
6263 : }
6264 6210902 : gcc_assert (cep->index == NULL_TREE
6265 : || TREE_CODE (cep->index) != RANGE_EXPR);
6266 : return cep;
6267 : }
6268 : else
6269 : {
6270 31732539 : gcc_assert (TREE_CODE (index) == FIELD_DECL
6271 : && (same_type_ignoring_top_level_qualifiers_p
6272 : (DECL_CONTEXT (index), TREE_TYPE (ctor))));
6273 :
6274 : /* We must keep the CONSTRUCTOR's ELTS in FIELD order.
6275 : Usually we meet initializers in that order, but it is
6276 : possible for base types to be placed not in program
6277 : order. */
6278 31732539 : tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
6279 31732539 : unsigned HOST_WIDE_INT idx = 0;
6280 31732539 : constructor_elt *cep = NULL;
6281 :
6282 : /* Check if we're changing the active member of a union. */
6283 584786 : if (TREE_CODE (type) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)
6284 32111630 : && CONSTRUCTOR_ELT (ctor, 0)->index != index)
6285 12486 : vec_safe_truncate (CONSTRUCTOR_ELTS (ctor), 0);
6286 : /* If the bit offset of INDEX is larger than that of the last
6287 : constructor_elt, then we can just immediately append a new
6288 : constructor_elt to the end of CTOR. */
6289 48310143 : else if (CONSTRUCTOR_NELTS (ctor)
6290 44461398 : && tree_int_cst_compare (bit_position (index),
6291 43498300 : bit_position (CONSTRUCTOR_ELTS (ctor)
6292 21749150 : ->last().index)) > 0)
6293 : {
6294 6134644 : idx = CONSTRUCTOR_NELTS (ctor);
6295 6134644 : goto insert;
6296 : }
6297 :
6298 : /* Otherwise, we need to iterate over CTOR to find or insert INDEX
6299 : appropriately. */
6300 :
6301 30383586 : for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor), idx, &cep);
6302 4785691 : idx++, fields = DECL_CHAIN (fields))
6303 : {
6304 20400197 : if (index == cep->index)
6305 15572568 : goto found;
6306 :
6307 : /* The field we're initializing must be on the field
6308 : list. Look to see if it is present before the
6309 : field the current ELT initializes. */
6310 51182443 : for (; fields != cep->index; fields = DECL_CHAIN (fields))
6311 46396752 : if (index == fields)
6312 41938 : goto insert;
6313 : }
6314 : /* We fell off the end of the CONSTRUCTOR, so insert a new
6315 : entry at the end. */
6316 :
6317 16159971 : insert:
6318 16159971 : if (!insertp)
6319 : return nullptr;
6320 :
6321 16159968 : {
6322 16159968 : constructor_elt ce = { index, NULL_TREE };
6323 :
6324 16159968 : vec_safe_insert (CONSTRUCTOR_ELTS (ctor), idx, ce);
6325 16159968 : cep = CONSTRUCTOR_ELT (ctor, idx);
6326 : }
6327 42602890 : found:;
6328 :
6329 : return cep;
6330 : }
6331 : }
6332 :
6333 : /* Under the control of CTX, issue a detailed diagnostic for
6334 : an out-of-bounds subscript INDEX into the expression ARRAY. */
6335 :
6336 : static void
6337 601 : diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index)
6338 : {
6339 601 : if (!ctx->quiet)
6340 : {
6341 120 : tree arraytype = TREE_TYPE (array);
6342 :
6343 : /* Convert the unsigned array subscript to a signed integer to avoid
6344 : printing huge numbers for small negative values. */
6345 120 : tree sidx = fold_convert (ssizetype, index);
6346 120 : STRIP_ANY_LOCATION_WRAPPER (array);
6347 120 : if (DECL_P (array))
6348 : {
6349 79 : auto_diagnostic_group d;
6350 79 : if (TYPE_DOMAIN (arraytype))
6351 73 : error_at (loc, "array subscript value %qE is outside the bounds "
6352 : "of array %qD of type %qT", sidx, array, arraytype);
6353 : else
6354 6 : error_at (loc, "nonzero array subscript %qE is used with array %qD of "
6355 : "type %qT with unknown bounds", sidx, array, arraytype);
6356 79 : inform (DECL_SOURCE_LOCATION (array), "declared here");
6357 79 : }
6358 41 : else if (TYPE_DOMAIN (arraytype))
6359 38 : error_at (loc, "array subscript value %qE is outside the bounds "
6360 : "of array type %qT", sidx, arraytype);
6361 : else
6362 3 : error_at (loc, "nonzero array subscript %qE is used with array of type %qT "
6363 : "with unknown bounds", sidx, arraytype);
6364 : }
6365 601 : }
6366 :
6367 : /* Return the number of elements for TYPE (which is an ARRAY_TYPE or
6368 : a VECTOR_TYPE). */
6369 :
6370 : static tree
6371 21104987 : get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
6372 : bool *non_constant_p, bool *overflow_p,
6373 : tree *jump_target)
6374 : {
6375 21104987 : tree nelts;
6376 21104987 : if (TREE_CODE (type) == ARRAY_TYPE)
6377 : {
6378 21104987 : if (TYPE_DOMAIN (type))
6379 21104727 : nelts = array_type_nelts_top (type);
6380 : else
6381 260 : nelts = size_zero_node;
6382 : }
6383 0 : else if (VECTOR_TYPE_P (type))
6384 0 : nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
6385 : else
6386 0 : gcc_unreachable ();
6387 :
6388 : /* For VLAs, the number of elements won't be an integer constant. */
6389 21104987 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
6390 : non_constant_p, overflow_p,
6391 : jump_target);
6392 21104987 : return nelts;
6393 : }
6394 :
6395 : /* Extract element INDEX consisting of CHARS_PER_ELT chars from
6396 : STRING_CST STRING. */
6397 :
6398 : static tree
6399 1996691 : extract_string_elt (tree string, unsigned chars_per_elt, unsigned index)
6400 : {
6401 1996691 : tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string)));
6402 1996691 : tree r;
6403 :
6404 1996691 : if (chars_per_elt == 1)
6405 1781828 : r = build_int_cst (type, TREE_STRING_POINTER (string)[index]);
6406 : else
6407 : {
6408 214863 : const unsigned char *ptr
6409 214863 : = ((const unsigned char *)TREE_STRING_POINTER (string)
6410 214863 : + index * chars_per_elt);
6411 214863 : r = native_interpret_expr (type, ptr, chars_per_elt);
6412 : }
6413 1996691 : return r;
6414 : }
6415 :
6416 : /* Subroutine of cxx_eval_array_reference. T is an ARRAY_REF; evaluate the
6417 : subscript, diagnose any problems with it, and return the result. */
6418 :
6419 : static tree
6420 21306019 : eval_and_check_array_index (const constexpr_ctx *ctx,
6421 : tree t, bool allow_one_past,
6422 : bool *non_constant_p, bool *overflow_p,
6423 : tree *jump_target)
6424 : {
6425 21306019 : location_t loc = cp_expr_loc_or_input_loc (t);
6426 21306019 : tree ary = TREE_OPERAND (t, 0);
6427 21306019 : t = TREE_OPERAND (t, 1);
6428 21306019 : tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue,
6429 : non_constant_p, overflow_p,
6430 : jump_target);
6431 21306019 : if (*jump_target)
6432 : return NULL_TREE;
6433 21306019 : VERIFY_CONSTANT (index);
6434 :
6435 21104193 : if (!tree_fits_shwi_p (index)
6436 21104193 : || tree_int_cst_sgn (index) < 0)
6437 : {
6438 112 : diag_array_subscript (loc, ctx, ary, index);
6439 112 : *non_constant_p = true;
6440 112 : return t;
6441 : }
6442 :
6443 21104081 : tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
6444 : overflow_p, jump_target);
6445 21104081 : if (*jump_target)
6446 : return NULL_TREE;
6447 21104081 : VERIFY_CONSTANT (nelts);
6448 21103997 : if (allow_one_past
6449 21103997 : ? !tree_int_cst_le (index, nelts)
6450 14321377 : : !tree_int_cst_lt (index, nelts))
6451 : {
6452 489 : diag_array_subscript (loc, ctx, ary, index);
6453 489 : *non_constant_p = true;
6454 489 : return t;
6455 : }
6456 :
6457 : return index;
6458 : }
6459 :
6460 : /* Subroutine of cxx_eval_constant_expression.
6461 : Attempt to reduce a reference to an array slot. */
6462 :
6463 : static tree
6464 15683020 : cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
6465 : value_cat lval,
6466 : bool *non_constant_p, bool *overflow_p,
6467 : tree *jump_target)
6468 : {
6469 15683020 : tree oldary = TREE_OPERAND (t, 0);
6470 15683020 : tree ary = cxx_eval_constant_expression (ctx, oldary,
6471 : lval,
6472 : non_constant_p, overflow_p,
6473 : jump_target);
6474 15683020 : if (*non_constant_p)
6475 : return t;
6476 15440411 : if (*jump_target)
6477 : return NULL_TREE;
6478 15440411 : if (!lval
6479 8656344 : && TREE_CODE (ary) == VIEW_CONVERT_EXPR
6480 144212 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
6481 15584623 : && (TYPE_MAIN_VARIANT (TREE_TYPE (t))
6482 144212 : == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))))
6483 144212 : ary = TREE_OPERAND (ary, 0);
6484 :
6485 15440411 : tree oldidx = TREE_OPERAND (t, 1);
6486 15440411 : tree index = eval_and_check_array_index (ctx, t, lval,
6487 : non_constant_p, overflow_p,
6488 : jump_target);
6489 15440411 : if (*non_constant_p)
6490 : return t;
6491 15237981 : if (*jump_target)
6492 : return NULL_TREE;
6493 :
6494 15237981 : if (lval && ary == oldary && index == oldidx)
6495 : return t;
6496 10227154 : else if (lval == vc_discard)
6497 : return t;
6498 10227154 : else if (lval)
6499 1771539 : return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
6500 :
6501 8455615 : unsigned len = 0, elem_nchars = 1;
6502 8455615 : tree elem_type = TREE_TYPE (TREE_TYPE (ary));
6503 8455615 : if (TREE_CODE (ary) == CONSTRUCTOR)
6504 6325884 : len = CONSTRUCTOR_NELTS (ary);
6505 2129731 : else if (TREE_CODE (ary) == STRING_CST)
6506 : {
6507 1985533 : elem_nchars = (TYPE_PRECISION (elem_type)
6508 1985533 : / TYPE_PRECISION (char_type_node));
6509 1985533 : len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
6510 : }
6511 144198 : else if (TREE_CODE (ary) == VECTOR_CST)
6512 : /* We don't create variable-length VECTOR_CSTs. */
6513 144198 : len = VECTOR_CST_NELTS (ary).to_constant ();
6514 : else
6515 : {
6516 : /* We can't do anything with other tree codes, so use
6517 : VERIFY_CONSTANT to complain and fail. */
6518 0 : VERIFY_CONSTANT (ary);
6519 0 : gcc_unreachable ();
6520 : }
6521 :
6522 8455615 : bool found;
6523 8455615 : HOST_WIDE_INT i = 0;
6524 8455615 : if (TREE_CODE (ary) == CONSTRUCTOR)
6525 : {
6526 6325884 : HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
6527 6325884 : found = (ix >= 0);
6528 6325884 : if (found)
6529 6198584 : i = ix;
6530 : }
6531 : else
6532 : {
6533 2129731 : i = tree_to_shwi (index);
6534 2129731 : found = (i < len);
6535 : }
6536 :
6537 8455615 : if (found)
6538 : {
6539 8327850 : tree r;
6540 8327850 : if (TREE_CODE (ary) == CONSTRUCTOR)
6541 : {
6542 6198584 : r = (*CONSTRUCTOR_ELTS (ary))[i].value;
6543 6198584 : if (TREE_CODE (r) == RAW_DATA_CST)
6544 : {
6545 29437 : tree ridx = (*CONSTRUCTOR_ELTS (ary))[i].index;
6546 29437 : gcc_checking_assert (ridx);
6547 29437 : unsigned int off
6548 29437 : = (wi::to_offset (index) - wi::to_offset (ridx)).to_uhwi ();
6549 29437 : r = raw_data_cst_elt (r, off);
6550 : }
6551 : }
6552 2129266 : else if (TREE_CODE (ary) == VECTOR_CST)
6553 144198 : r = VECTOR_CST_ELT (ary, i);
6554 : else
6555 1985068 : r = extract_string_elt (ary, elem_nchars, i);
6556 :
6557 2158703 : if (r)
6558 : /* Don't VERIFY_CONSTANT here. */
6559 : return r;
6560 :
6561 : /* Otherwise the element doesn't have a value yet. */
6562 : }
6563 :
6564 : /* Not found. */
6565 :
6566 127765 : if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
6567 90 : return build_constructor (elem_type, NULL);
6568 :
6569 127675 : if (TREE_CODE (ary) == CONSTRUCTOR
6570 127675 : && CONSTRUCTOR_NO_CLEARING (ary))
6571 : {
6572 : /* 'ary' is part of the aggregate initializer we're currently
6573 : building; if there's no initializer for this element yet,
6574 : that's an error. */
6575 51 : if (!ctx->quiet)
6576 16 : error ("accessing uninitialized array element");
6577 51 : *non_constant_p = true;
6578 51 : return t;
6579 : }
6580 :
6581 : /* If it's within the array bounds but doesn't have an explicit
6582 : initializer, it's initialized from {}. But use build_value_init
6583 : directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */
6584 127624 : tree val;
6585 127624 : constexpr_ctx new_ctx;
6586 127624 : if (CP_AGGREGATE_TYPE_P (elem_type))
6587 : {
6588 504 : tree empty_ctor = build_constructor (init_list_type_node, NULL);
6589 504 : val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
6590 : }
6591 : else
6592 127120 : val = build_value_init (elem_type, tf_warning_or_error);
6593 :
6594 : /* Create a new constructor only if we don't already have a suitable one. */
6595 127624 : const bool new_ctor = (!SCALAR_TYPE_P (elem_type)
6596 128154 : && (!ctx->ctor
6597 45 : || !same_type_ignoring_top_level_qualifiers_p
6598 45 : (elem_type, TREE_TYPE (ctx->ctor))));
6599 : if (new_ctor)
6600 : {
6601 521 : new_ctx = *ctx;
6602 : /* We clear the object here. We used to replace it with T, but that
6603 : caused problems (101371, 108158); and anyway, T is the initializer,
6604 : not the target object. */
6605 521 : new_ctx.object = NULL_TREE;
6606 521 : new_ctx.ctor = build_constructor (elem_type, NULL);
6607 521 : ctx = &new_ctx;
6608 : }
6609 127624 : t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
6610 : overflow_p, jump_target);
6611 127624 : if (new_ctor && t != ctx->ctor)
6612 500 : free_constructor (ctx->ctor);
6613 : return t;
6614 : }
6615 :
6616 : /* Subroutine of cxx_eval_constant_expression.
6617 : Attempt to reduce a field access of a value of class type. */
6618 :
6619 : static tree
6620 116311108 : cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
6621 : value_cat lval,
6622 : bool *non_constant_p, bool *overflow_p,
6623 : tree *jump_target)
6624 : {
6625 116311108 : unsigned HOST_WIDE_INT i;
6626 116311108 : tree field;
6627 116311108 : tree value;
6628 116311108 : tree part = TREE_OPERAND (t, 1);
6629 116311108 : tree orig_whole = TREE_OPERAND (t, 0);
6630 116311108 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6631 : lval,
6632 : non_constant_p, overflow_p,
6633 : jump_target);
6634 116311108 : if (*non_constant_p)
6635 : return t;
6636 90208824 : if (*jump_target)
6637 : return NULL_TREE;
6638 90208818 : if (INDIRECT_REF_P (whole)
6639 90208818 : && integer_zerop (TREE_OPERAND (whole, 0)))
6640 : {
6641 177 : if (!ctx->quiet)
6642 39 : error ("dereferencing a null pointer in %qE", orig_whole);
6643 177 : *non_constant_p = true;
6644 177 : return t;
6645 : }
6646 :
6647 90208641 : if (TREE_CODE (whole) == PTRMEM_CST)
6648 1651 : whole = cplus_expand_constant (whole);
6649 90208641 : if (whole == orig_whole)
6650 : return t;
6651 61198482 : if (lval == vc_discard)
6652 : return t;
6653 61198434 : if (lval)
6654 21776595 : return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
6655 : whole, part, NULL_TREE);
6656 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6657 : CONSTRUCTOR. */
6658 39421839 : if (TREE_CODE (whole) != CONSTRUCTOR)
6659 : {
6660 0 : if (!ctx->quiet)
6661 0 : error ("%qE is not a constant expression", orig_whole);
6662 0 : *non_constant_p = true;
6663 0 : return t;
6664 : }
6665 39420344 : if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole))
6666 39423516 : && DECL_MUTABLE_P (part))
6667 : {
6668 144 : if (!ctx->quiet)
6669 16 : error ("mutable %qD is not usable in a constant expression", part);
6670 144 : *non_constant_p = true;
6671 144 : return t;
6672 : }
6673 :
6674 39421695 : bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole));
6675 59236996 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6676 : {
6677 : /* Use name match for PMF fields, as a variant will have a
6678 : different FIELD_DECL with a different type. */
6679 59011143 : if (pmf ? DECL_NAME (field) == DECL_NAME (part)
6680 : : field == part)
6681 : {
6682 39195842 : if (value == void_node)
6683 6 : goto uninit;
6684 39195836 : if (value)
6685 : {
6686 39195818 : STRIP_ANY_LOCATION_WRAPPER (value);
6687 39195818 : return value;
6688 : }
6689 : else
6690 : /* We're in the middle of initializing it. */
6691 : break;
6692 : }
6693 : }
6694 225871 : if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE)
6695 : {
6696 112 : if (CONSTRUCTOR_NELTS (whole) > 0)
6697 : {
6698 : /* DR 1188 says we don't have to deal with this. */
6699 97 : if (!ctx->quiet)
6700 : {
6701 20 : constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0);
6702 20 : if (cep->value == NULL_TREE)
6703 9 : error ("accessing uninitialized member %qD", part);
6704 : else
6705 11 : error ("accessing %qD member instead of active %qD member "
6706 : "in constant expression", part, cep->index);
6707 : }
6708 97 : *non_constant_p = true;
6709 97 : return t;
6710 : }
6711 15 : else if (!CONSTRUCTOR_NO_CLEARING (whole))
6712 : {
6713 : /* Value-initialized union, check if looking at the first member. */
6714 12 : tree first = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (whole)));
6715 12 : if (first != part)
6716 : {
6717 9 : if (!ctx->quiet)
6718 3 : error ("accessing %qD member instead of initialized %qD "
6719 : "member in constant expression", part, first);
6720 9 : *non_constant_p = true;
6721 9 : return t;
6722 : }
6723 : }
6724 : }
6725 :
6726 : /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
6727 : classes never get represented; throw together a value now. */
6728 225765 : if (is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
6729 209177 : return build_constructor (TREE_TYPE (t), NULL);
6730 :
6731 16588 : gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
6732 :
6733 16588 : if (CONSTRUCTOR_NO_CLEARING (whole))
6734 : {
6735 112 : uninit:
6736 : /* 'whole' is part of the aggregate initializer we're currently
6737 : building; if there's no initializer for this member yet, that's an
6738 : error. */
6739 118 : if (!ctx->quiet)
6740 23 : error ("accessing uninitialized member %qD", part);
6741 118 : *non_constant_p = true;
6742 118 : return t;
6743 : }
6744 :
6745 : /* If there's no explicit init for this field, it's value-initialized. */
6746 :
6747 16476 : if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
6748 : {
6749 : /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR
6750 : and copy the flags. */
6751 15869 : constructor_elt *e = get_or_insert_ctor_field (whole, part);
6752 15869 : e->value = value = build_constructor (TREE_TYPE (part), NULL);
6753 15869 : CONSTRUCTOR_ZERO_PADDING_BITS (value)
6754 15869 : = CONSTRUCTOR_ZERO_PADDING_BITS (whole);
6755 15869 : return value;
6756 : }
6757 :
6758 607 : value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
6759 607 : return cxx_eval_constant_expression (ctx, value,
6760 : lval,
6761 : non_constant_p, overflow_p,
6762 607 : jump_target);
6763 : }
6764 :
6765 : /* Subroutine of cxx_eval_constant_expression.
6766 : Attempt to reduce a field access of a value of class type that is
6767 : expressed as a BIT_FIELD_REF. */
6768 :
6769 : static tree
6770 40745 : cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
6771 : value_cat lval,
6772 : bool *non_constant_p, bool *overflow_p,
6773 : tree *jump_target)
6774 : {
6775 40745 : tree orig_whole = TREE_OPERAND (t, 0);
6776 40745 : tree retval, fldval, utype, mask;
6777 40745 : bool fld_seen = false;
6778 40745 : HOST_WIDE_INT istart, isize;
6779 40745 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6780 : lval,
6781 : non_constant_p, overflow_p,
6782 : jump_target);
6783 40745 : tree start, field, value;
6784 40745 : unsigned HOST_WIDE_INT i;
6785 :
6786 40745 : if (*jump_target)
6787 : return NULL_TREE;
6788 40745 : if (whole == orig_whole)
6789 : return t;
6790 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6791 : CONSTRUCTOR. */
6792 40596 : if (!*non_constant_p
6793 40596 : && TREE_CODE (whole) != VECTOR_CST
6794 0 : && TREE_CODE (whole) != CONSTRUCTOR)
6795 : {
6796 0 : if (!ctx->quiet)
6797 0 : error ("%qE is not a constant expression", orig_whole);
6798 0 : *non_constant_p = true;
6799 : }
6800 40596 : if (*non_constant_p)
6801 : return t;
6802 :
6803 40596 : if (TREE_CODE (whole) == VECTOR_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)))
6804 : {
6805 40596 : if (tree r = fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
6806 : TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)))
6807 : return r;
6808 0 : if (!ctx->quiet)
6809 0 : error ("%qE is not a constant expression", orig_whole);
6810 0 : *non_constant_p = true;
6811 0 : return t;
6812 : }
6813 :
6814 0 : start = TREE_OPERAND (t, 2);
6815 0 : istart = tree_to_shwi (start);
6816 0 : isize = tree_to_shwi (TREE_OPERAND (t, 1));
6817 0 : utype = TREE_TYPE (t);
6818 0 : if (!TYPE_UNSIGNED (utype))
6819 0 : utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
6820 0 : retval = build_int_cst (utype, 0);
6821 0 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6822 : {
6823 0 : tree bitpos = bit_position (field);
6824 0 : STRIP_ANY_LOCATION_WRAPPER (value);
6825 0 : if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
6826 : return value;
6827 0 : if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
6828 0 : && TREE_CODE (value) == INTEGER_CST
6829 0 : && tree_fits_shwi_p (bitpos)
6830 0 : && tree_fits_shwi_p (DECL_SIZE (field)))
6831 : {
6832 0 : HOST_WIDE_INT bit = tree_to_shwi (bitpos);
6833 0 : HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
6834 0 : HOST_WIDE_INT shift;
6835 0 : if (bit >= istart && bit + sz <= istart + isize)
6836 : {
6837 0 : fldval = fold_convert (utype, value);
6838 0 : mask = build_int_cst_type (utype, -1);
6839 0 : mask = fold_build2 (LSHIFT_EXPR, utype, mask,
6840 : size_int (TYPE_PRECISION (utype) - sz));
6841 0 : mask = fold_build2 (RSHIFT_EXPR, utype, mask,
6842 : size_int (TYPE_PRECISION (utype) - sz));
6843 0 : fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
6844 0 : shift = bit - istart;
6845 0 : if (BYTES_BIG_ENDIAN)
6846 : shift = TYPE_PRECISION (utype) - shift - sz;
6847 0 : fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
6848 : size_int (shift));
6849 0 : retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
6850 0 : fld_seen = true;
6851 : }
6852 : }
6853 : }
6854 0 : if (fld_seen)
6855 0 : return fold_convert (TREE_TYPE (t), retval);
6856 0 : gcc_unreachable ();
6857 : return error_mark_node;
6858 : }
6859 :
6860 : /* Helper for cxx_eval_bit_cast.
6861 : Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From
6862 : types and types of all subobjects have is_union_v<T>, is_pointer_v<T>,
6863 : is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static
6864 : data members of reference or std::meta::info type. */
6865 :
6866 : static bool
6867 56312 : check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
6868 : tree orig_type)
6869 : {
6870 57312 : if (TREE_CODE (type) == UNION_TYPE)
6871 : {
6872 63 : if (!ctx->quiet)
6873 : {
6874 21 : if (type == orig_type)
6875 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6876 : "a union type", "__builtin_bit_cast", type);
6877 : else
6878 15 : error_at (loc, "%qs is not a constant expression because %qT "
6879 : "contains a union type", "__builtin_bit_cast",
6880 : orig_type);
6881 : }
6882 : return true;
6883 : }
6884 : if (TREE_CODE (type) == POINTER_TYPE)
6885 : {
6886 57 : if (!ctx->quiet)
6887 : {
6888 18 : if (type == orig_type)
6889 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6890 : "a pointer type", "__builtin_bit_cast", type);
6891 : else
6892 12 : error_at (loc, "%qs is not a constant expression because %qT "
6893 : "contains a pointer type", "__builtin_bit_cast",
6894 : orig_type);
6895 : }
6896 : return true;
6897 : }
6898 : if (TREE_CODE (type) == REFERENCE_TYPE)
6899 : {
6900 0 : if (!ctx->quiet)
6901 : {
6902 0 : if (type == orig_type)
6903 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6904 : "a reference type", "__builtin_bit_cast", type);
6905 : else
6906 0 : error_at (loc, "%qs is not a constant expression because %qT "
6907 : "contains a reference type", "__builtin_bit_cast",
6908 : orig_type);
6909 : }
6910 : return true;
6911 : }
6912 39316 : if (TYPE_PTRMEM_P (type))
6913 : {
6914 36 : if (!ctx->quiet)
6915 : {
6916 12 : if (type == orig_type)
6917 12 : error_at (loc, "%qs is not a constant expression because %qT is "
6918 : "a pointer to member type", "__builtin_bit_cast",
6919 : type);
6920 : else
6921 0 : error_at (loc, "%qs is not a constant expression because %qT "
6922 : "contains a pointer to member type",
6923 : "__builtin_bit_cast", orig_type);
6924 : }
6925 : return true;
6926 : }
6927 57156 : if (TYPE_VOLATILE (type))
6928 : {
6929 0 : if (!ctx->quiet)
6930 : {
6931 0 : if (type == orig_type)
6932 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6933 : "volatile", "__builtin_bit_cast", type);
6934 : else
6935 0 : error_at (loc, "%qs is not a constant expression because %qT "
6936 : "contains a volatile subobject",
6937 : "__builtin_bit_cast", orig_type);
6938 : }
6939 : return true;
6940 : }
6941 57156 : if (REFLECTION_TYPE_P (type))
6942 : {
6943 22 : if (!ctx->quiet)
6944 : {
6945 6 : if (type == orig_type)
6946 4 : error_at (loc, "%qs is not a constant expression because its "
6947 : "type is %qs", "__builtin_bit_cast", "std::meta::info");
6948 : else
6949 2 : error_at (loc, "%qs is not a constant expression because %qT "
6950 : "contains %qs type",
6951 : "__builtin_bit_cast", orig_type, "std::meta::info");
6952 : }
6953 : return true;
6954 : }
6955 57134 : if (TREE_CODE (type) == RECORD_TYPE)
6956 2294092 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6957 2254890 : if (TREE_CODE (field) == FIELD_DECL
6958 2254890 : && check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
6959 : return true;
6960 57038 : if (TREE_CODE (type) == ARRAY_TYPE)
6961 1000 : return check_bit_cast_type (ctx, loc, TREE_TYPE (type), orig_type);
6962 : return false;
6963 : }
6964 :
6965 : /* Helper function for cxx_eval_bit_cast. For unsigned char or
6966 : std::byte members of CONSTRUCTOR (recursively) if they contain
6967 : some indeterminate bits (as set in MASK), remove the ctor elts,
6968 : mark the CONSTRUCTOR as CONSTRUCTOR_NO_CLEARING and clear the
6969 : bits in MASK. */
6970 :
6971 : static void
6972 9631 : clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask)
6973 : {
6974 9631 : if (TREE_CODE (t) != CONSTRUCTOR)
6975 : return;
6976 :
6977 : unsigned i, j = 0;
6978 : tree index, value;
6979 23564 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)
6980 : {
6981 13933 : tree type = TREE_TYPE (value);
6982 13933 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
6983 27427 : && DECL_BIT_FIELD_TYPE (index) != NULL_TREE)
6984 : {
6985 270 : if (is_byte_access_type_not_plain_char (DECL_BIT_FIELD_TYPE (index)))
6986 : {
6987 135 : HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (index));
6988 135 : gcc_assert (fldsz != 0);
6989 135 : HOST_WIDE_INT pos = int_byte_position (index);
6990 135 : HOST_WIDE_INT bpos
6991 135 : = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (index));
6992 135 : bpos %= BITS_PER_UNIT;
6993 135 : HOST_WIDE_INT end
6994 135 : = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
6995 135 : gcc_assert (end == 1 || end == 2);
6996 135 : unsigned char *p = mask + pos;
6997 135 : unsigned char mask_save[2];
6998 135 : mask_save[0] = mask[pos];
6999 135 : mask_save[1] = end == 2 ? mask[pos + 1] : 0;
7000 135 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
7001 : sorry_at (loc, "PDP11 bit-field handling unsupported"
7002 : " in %qs", "__builtin_bit_cast");
7003 135 : else if (BYTES_BIG_ENDIAN)
7004 : {
7005 : /* Big endian. */
7006 : if (bpos + fldsz <= BITS_PER_UNIT)
7007 : *p &= ~(((1 << fldsz) - 1)
7008 : << (BITS_PER_UNIT - bpos - fldsz));
7009 : else
7010 : {
7011 : gcc_assert (bpos);
7012 : *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
7013 : p++;
7014 : fldsz -= BITS_PER_UNIT - bpos;
7015 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
7016 : *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
7017 : }
7018 : }
7019 : else
7020 : {
7021 : /* Little endian. */
7022 135 : if (bpos + fldsz <= BITS_PER_UNIT)
7023 135 : *p &= ~(((1 << fldsz) - 1) << bpos);
7024 : else
7025 : {
7026 0 : gcc_assert (bpos);
7027 0 : *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
7028 0 : p++;
7029 0 : fldsz -= BITS_PER_UNIT - bpos;
7030 0 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
7031 0 : *p &= ~((1 << fldsz) - 1);
7032 : }
7033 : }
7034 135 : if (mask_save[0] != mask[pos]
7035 99 : || (end == 2 && mask_save[1] != mask[pos + 1]))
7036 : {
7037 36 : CONSTRUCTOR_NO_CLEARING (t) = 1;
7038 36 : continue;
7039 : }
7040 : }
7041 : }
7042 13663 : else if (is_byte_access_type_not_plain_char (type))
7043 : {
7044 228 : HOST_WIDE_INT pos;
7045 228 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7046 132 : pos = tree_to_shwi (index);
7047 : else
7048 96 : pos = int_byte_position (index);
7049 228 : if (mask[pos])
7050 : {
7051 48 : CONSTRUCTOR_NO_CLEARING (t) = 1;
7052 48 : mask[pos] = 0;
7053 48 : continue;
7054 : }
7055 : }
7056 13849 : if (TREE_CODE (value) == CONSTRUCTOR)
7057 : {
7058 7292 : HOST_WIDE_INT pos;
7059 7292 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7060 144 : pos = tree_to_shwi (index)
7061 72 : * tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))));
7062 : else
7063 7220 : pos = int_byte_position (index);
7064 7292 : clear_uchar_or_std_byte_in_mask (loc, value, mask + pos);
7065 : }
7066 13849 : if (i != j)
7067 : {
7068 180 : CONSTRUCTOR_ELT (t, j)->index = index;
7069 180 : CONSTRUCTOR_ELT (t, j)->value = value;
7070 : }
7071 13849 : ++j;
7072 : }
7073 19262 : if (CONSTRUCTOR_NELTS (t) != j)
7074 84 : vec_safe_truncate (CONSTRUCTOR_ELTS (t), j);
7075 : }
7076 :
7077 : /* Subroutine of cxx_eval_constant_expression.
7078 : Attempt to evaluate a BIT_CAST_EXPR. */
7079 :
7080 : static tree
7081 4047 : cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
7082 : bool *overflow_p, tree *jump_target)
7083 : {
7084 4047 : if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
7085 4047 : TREE_TYPE (t))
7086 12767 : || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0),
7087 3950 : EXPR_LOCATION (t)),
7088 3950 : TREE_TYPE (TREE_OPERAND (t, 0)),
7089 3950 : TREE_TYPE (TREE_OPERAND (t, 0))))
7090 : {
7091 178 : *non_constant_p = true;
7092 178 : return t;
7093 : }
7094 :
7095 3869 : tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue,
7096 : non_constant_p, overflow_p,
7097 : jump_target);
7098 3869 : if (*non_constant_p)
7099 : return t;
7100 2820 : if (*jump_target)
7101 : return NULL_TREE;
7102 :
7103 2820 : location_t loc = EXPR_LOCATION (t);
7104 2820 : if (BITS_PER_UNIT != 8 || CHAR_BIT != 8)
7105 : {
7106 : if (!ctx->quiet)
7107 : sorry_at (loc, "%qs cannot be constant evaluated on the target",
7108 : "__builtin_bit_cast");
7109 : *non_constant_p = true;
7110 : return t;
7111 : }
7112 :
7113 2820 : if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))))
7114 : {
7115 0 : if (!ctx->quiet)
7116 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7117 : "type is too large", "__builtin_bit_cast");
7118 0 : *non_constant_p = true;
7119 0 : return t;
7120 : }
7121 :
7122 2820 : HOST_WIDE_INT len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t)));
7123 2820 : if (len < 0 || (int) len != len)
7124 : {
7125 0 : if (!ctx->quiet)
7126 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7127 : "type is too large", "__builtin_bit_cast");
7128 0 : *non_constant_p = true;
7129 0 : return t;
7130 : }
7131 :
7132 2820 : unsigned char buf[64];
7133 2820 : unsigned char *ptr, *mask;
7134 2820 : size_t alen = (size_t) len * 2;
7135 2820 : if (alen <= sizeof (buf))
7136 : ptr = buf;
7137 : else
7138 329 : ptr = XNEWVEC (unsigned char, alen);
7139 2820 : mask = ptr + (size_t) len;
7140 : /* At the beginning consider everything indeterminate. */
7141 2820 : memset (mask, ~0, (size_t) len);
7142 :
7143 2820 : if (native_encode_initializer (op, ptr, len, 0, mask) != len)
7144 : {
7145 0 : if (!ctx->quiet)
7146 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7147 : "argument cannot be encoded", "__builtin_bit_cast");
7148 0 : *non_constant_p = true;
7149 0 : if (ptr != buf)
7150 0 : XDELETE (ptr);
7151 : return t;
7152 : }
7153 :
7154 2820 : tree r = NULL_TREE;
7155 2820 : if (can_native_interpret_type_p (TREE_TYPE (t)))
7156 : {
7157 481 : r = native_interpret_expr (TREE_TYPE (t), ptr, len);
7158 481 : if (is_byte_access_type_not_plain_char (TREE_TYPE (t)))
7159 : {
7160 52 : gcc_assert (len == 1);
7161 52 : if (mask[0])
7162 : {
7163 27 : memset (mask, 0, len);
7164 27 : r = build_constructor (TREE_TYPE (r), NULL);
7165 27 : CONSTRUCTOR_NO_CLEARING (r) = 1;
7166 : }
7167 : }
7168 : }
7169 2339 : else if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
7170 : {
7171 2339 : r = native_interpret_aggregate (TREE_TYPE (t), ptr, 0, len);
7172 2339 : if (r != NULL_TREE)
7173 : {
7174 2339 : clear_type_padding_in_mask (TREE_TYPE (t), mask);
7175 2339 : clear_uchar_or_std_byte_in_mask (loc, r, mask);
7176 2339 : if (CHECKING_P)
7177 : {
7178 2339 : tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue,
7179 : non_constant_p, overflow_p,
7180 : jump_target);
7181 2339 : gcc_checking_assert (e == r && !*jump_target);
7182 : r = e;
7183 : }
7184 : }
7185 : }
7186 :
7187 2820 : if (r != NULL_TREE)
7188 : {
7189 92041 : for (int i = 0; i < len; i++)
7190 89311 : if (mask[i])
7191 : {
7192 90 : if (!ctx->quiet)
7193 30 : error_at (loc, "%qs accessing uninitialized byte at offset %d",
7194 : "__builtin_bit_cast", i);
7195 90 : *non_constant_p = true;
7196 90 : r = t;
7197 90 : break;
7198 : }
7199 2820 : if (ptr != buf)
7200 329 : XDELETE (ptr);
7201 : return r;
7202 : }
7203 :
7204 0 : if (!ctx->quiet)
7205 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7206 : "argument cannot be interpreted", "__builtin_bit_cast");
7207 0 : *non_constant_p = true;
7208 0 : if (ptr != buf)
7209 0 : XDELETE (ptr);
7210 : return t;
7211 : }
7212 :
7213 : /* Subroutine of cxx_eval_constant_expression.
7214 : Evaluate a short-circuited logical expression T in the context
7215 : of a given constexpr CALL. BAILOUT_VALUE is the value for
7216 : early return. CONTINUE_VALUE is used here purely for
7217 : sanity check purposes. */
7218 :
7219 : static tree
7220 18669489 : cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
7221 : tree bailout_value, tree continue_value,
7222 : bool *non_constant_p, bool *overflow_p,
7223 : tree *jump_target)
7224 : {
7225 18669489 : tree r;
7226 18669489 : tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
7227 : vc_prvalue, non_constant_p,
7228 : overflow_p, jump_target);
7229 18669487 : if (*jump_target)
7230 : return NULL_TREE;
7231 18669478 : VERIFY_CONSTANT (lhs);
7232 13875099 : if (tree_int_cst_equal (lhs, bailout_value))
7233 : return lhs;
7234 11837389 : gcc_assert (tree_int_cst_equal (lhs, continue_value));
7235 11837389 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
7236 : vc_prvalue, non_constant_p,
7237 : overflow_p, jump_target);
7238 11837389 : if (*jump_target)
7239 : return NULL_TREE;
7240 11837389 : VERIFY_CONSTANT (r);
7241 : return r;
7242 : }
7243 :
7244 : /* REF is a COMPONENT_REF designating a particular field. V is a vector of
7245 : CONSTRUCTOR elements to initialize (part of) an object containing that
7246 : field. Return a pointer to the constructor_elt corresponding to the
7247 : initialization of the field. */
7248 :
7249 : static constructor_elt *
7250 0 : base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
7251 : {
7252 0 : tree aggr = TREE_OPERAND (ref, 0);
7253 0 : tree field = TREE_OPERAND (ref, 1);
7254 0 : HOST_WIDE_INT i;
7255 0 : constructor_elt *ce;
7256 :
7257 0 : gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
7258 :
7259 0 : if (TREE_CODE (aggr) == COMPONENT_REF)
7260 : {
7261 0 : constructor_elt *base_ce
7262 0 : = base_field_constructor_elt (v, aggr);
7263 0 : v = CONSTRUCTOR_ELTS (base_ce->value);
7264 : }
7265 :
7266 0 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
7267 0 : if (ce->index == field)
7268 0 : return ce;
7269 :
7270 0 : gcc_unreachable ();
7271 : return NULL;
7272 : }
7273 :
7274 : /* Some of the expressions fed to the constexpr mechanism are calls to
7275 : constructors, which have type void. In that case, return the type being
7276 : initialized by the constructor. */
7277 :
7278 : static tree
7279 612760456 : initialized_type (tree t)
7280 : {
7281 614423748 : if (TYPE_P (t))
7282 : return t;
7283 614423284 : tree type = TREE_TYPE (t);
7284 614423284 : if (TREE_CODE (t) == CALL_EXPR)
7285 : {
7286 : /* A constructor call has void type, so we need to look deeper. */
7287 74276698 : tree fn = get_function_named_in_call (t);
7288 74270219 : if (fn && TREE_CODE (fn) == FUNCTION_DECL
7289 148420257 : && DECL_CXX_CONSTRUCTOR_P (fn))
7290 4107107 : type = DECL_CONTEXT (fn);
7291 : }
7292 540146586 : else if (TREE_CODE (t) == COMPOUND_EXPR)
7293 1663292 : return initialized_type (TREE_OPERAND (t, 1));
7294 538483294 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
7295 884255 : type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
7296 612759992 : return cv_unqualified (type);
7297 : }
7298 :
7299 : /* We're about to initialize element INDEX of an array or class from VALUE.
7300 : Set up NEW_CTX appropriately by adjusting .object to refer to the
7301 : subobject and creating a new CONSTRUCTOR if the element is itself
7302 : a class or array. */
7303 :
7304 : static void
7305 4197380 : init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
7306 : tree index, tree &value)
7307 : {
7308 4197380 : new_ctx = *ctx;
7309 :
7310 4197380 : if (index && TREE_CODE (index) != INTEGER_CST
7311 3760161 : && TREE_CODE (index) != FIELD_DECL
7312 3 : && TREE_CODE (index) != RANGE_EXPR)
7313 : /* This won't have an element in the new CONSTRUCTOR. */
7314 : return;
7315 :
7316 4197380 : tree type = initialized_type (value);
7317 4197380 : if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
7318 : /* A non-aggregate member doesn't get its own CONSTRUCTOR. */
7319 : return;
7320 :
7321 1700425 : tree ctxtype = NULL_TREE;
7322 1700425 : if (ctx->ctor)
7323 1700408 : ctxtype = TREE_TYPE (ctx->ctor);
7324 17 : else if (ctx->object)
7325 14 : ctxtype = TREE_TYPE (ctx->object);
7326 : else
7327 : {
7328 : /* This can happen if the enclosing object is also an empty subobject
7329 : (c++/125315). */
7330 3 : gcc_checking_assert (is_empty_field (index));
7331 : return;
7332 : }
7333 :
7334 1700422 : if (VECTOR_TYPE_P (type)
7335 7417 : && VECTOR_TYPE_P (ctxtype)
7336 2596 : && index == NULL_TREE)
7337 : /* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
7338 : vector is constructed from smaller vectors, doesn't get its own
7339 : CONSTRUCTOR either. */
7340 : return;
7341 :
7342 : /* The sub-aggregate initializer might contain a placeholder;
7343 : update object to refer to the subobject and ctor to refer to
7344 : the (newly created) sub-initializer. */
7345 1697826 : if (ctx->object)
7346 : {
7347 1534703 : if (index == NULL_TREE || TREE_CODE (index) == RANGE_EXPR)
7348 : /* There's no well-defined subobject for this index. */
7349 3 : new_ctx.object = NULL_TREE;
7350 : else
7351 1534700 : new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
7352 : }
7353 :
7354 1697826 : if (is_empty_field (index)
7355 1697826 : && TREE_CODE (ctxtype) != UNION_TYPE)
7356 : /* Leave ctor null for an empty subobject of a non-union class, they aren't
7357 : represented in the result of evaluation. */
7358 1522461 : new_ctx.ctor = NULL_TREE;
7359 : else
7360 : {
7361 175365 : tree elt = build_constructor (type, NULL);
7362 175365 : CONSTRUCTOR_NO_CLEARING (elt) = true;
7363 175365 : new_ctx.ctor = elt;
7364 : }
7365 :
7366 1697826 : if (TREE_CODE (value) == TARGET_EXPR)
7367 : /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */
7368 120252 : value = TARGET_EXPR_INITIAL (value);
7369 : }
7370 :
7371 : /* We're about to process an initializer for a class or array TYPE. Make
7372 : sure that CTX is set up appropriately. */
7373 :
7374 : static void
7375 3391762 : verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
7376 : {
7377 : /* We don't bother building a ctor for an empty base subobject. */
7378 3391762 : if (is_empty_class (type))
7379 : return;
7380 :
7381 : /* We're in the middle of an initializer that might involve placeholders;
7382 : our caller should have created a CONSTRUCTOR for us to put the
7383 : initializer into. We will either return that constructor or T. */
7384 1887532 : gcc_assert (ctx->ctor);
7385 1887532 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
7386 : (type, TREE_TYPE (ctx->ctor)));
7387 : /* We used to check that ctx->ctor was empty, but that isn't the case when
7388 : the object is zero-initialized before calling the constructor. */
7389 1887532 : if (ctx->object)
7390 : {
7391 1672144 : tree otype = TREE_TYPE (ctx->object);
7392 1672144 : gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)
7393 : /* Handle flexible array members. */
7394 : || (TREE_CODE (otype) == ARRAY_TYPE
7395 : && TYPE_DOMAIN (otype) == NULL_TREE
7396 : && TREE_CODE (type) == ARRAY_TYPE
7397 : && (same_type_ignoring_top_level_qualifiers_p
7398 : (TREE_TYPE (type), TREE_TYPE (otype)))));
7399 : }
7400 1887532 : gcc_assert (!ctx->object || !DECL_P (ctx->object)
7401 : || ctx->global->get_value (ctx->object) == ctx->ctor);
7402 : }
7403 :
7404 : /* Subroutine of cxx_eval_constant_expression.
7405 : The expression tree T denotes a C-style array or a C-style
7406 : aggregate. Reduce it to a constant expression. */
7407 :
7408 : static tree
7409 3390856 : cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
7410 : value_cat lval,
7411 : bool *non_constant_p, bool *overflow_p,
7412 : tree *jump_target)
7413 : {
7414 3390856 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
7415 3390856 : bool changed = false;
7416 3390856 : gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
7417 3390856 : tree type = TREE_TYPE (t);
7418 :
7419 3390856 : constexpr_ctx new_ctx;
7420 3390856 : if (TYPE_PTRMEMFUNC_P (type) || VECTOR_TYPE_P (type))
7421 : {
7422 : /* We don't really need the ctx->ctor business for a PMF or
7423 : vector, but it's simpler to use the same code. */
7424 56001 : new_ctx = *ctx;
7425 56001 : new_ctx.ctor = build_constructor (type, NULL);
7426 56001 : new_ctx.object = NULL_TREE;
7427 56001 : ctx = &new_ctx;
7428 3390856 : };
7429 3390856 : verify_ctor_sanity (ctx, type);
7430 3390856 : vec<constructor_elt, va_gc> **p = nullptr;
7431 3390856 : if (ctx->ctor)
7432 : {
7433 3390839 : p = &CONSTRUCTOR_ELTS (ctx->ctor);
7434 6778229 : vec_alloc (*p, vec_safe_length (v));
7435 3390839 : if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t))
7436 16085 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1;
7437 : }
7438 :
7439 3390856 : unsigned i;
7440 3390856 : tree index, value;
7441 3390856 : bool constant_p = true;
7442 3390856 : bool side_effects_p = false;
7443 6856200 : FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
7444 : {
7445 4190941 : tree orig_value = value;
7446 4190941 : init_subob_ctx (ctx, new_ctx, index, value);
7447 : /* Like in cxx_eval_store_expression, omit entries for empty fields. */
7448 4190941 : bool no_slot = new_ctx.ctor == NULL_TREE;
7449 4190941 : int pos_hint = -1;
7450 4190941 : if (!ctx->ctor)
7451 : /* The enclosing object could be an empty subobject so we have no
7452 : CONSTRUCTOR (c++/125336). */
7453 17 : gcc_checking_assert (is_empty_class (type));
7454 4190924 : else if (new_ctx.ctor != ctx->ctor && !no_slot)
7455 : {
7456 : /* If we built a new CONSTRUCTOR, attach it now so that other
7457 : initializers can refer to it. */
7458 169227 : constructor_elt *cep = get_or_insert_ctor_field (ctx->ctor, index);
7459 169227 : cep->value = new_ctx.ctor;
7460 169227 : pos_hint = cep - (*p)->begin();
7461 169227 : }
7462 4021697 : else if (TREE_CODE (type) == UNION_TYPE)
7463 : /* Otherwise if we're constructing a non-aggregate union member, set
7464 : the active union member now so that we can later detect and diagnose
7465 : if its initializer attempts to activate another member. */
7466 1089 : get_or_insert_ctor_field (ctx->ctor, index);
7467 4190941 : tree elt = cxx_eval_constant_expression (&new_ctx, value,
7468 : lval,
7469 : non_constant_p, overflow_p,
7470 : jump_target);
7471 4190941 : if (*jump_target)
7472 : return NULL_TREE;
7473 : /* Don't VERIFY_CONSTANT here. */
7474 4190935 : if (ctx->quiet && *non_constant_p)
7475 : break;
7476 3465344 : if (elt != orig_value)
7477 1237781 : changed = true;
7478 :
7479 3465344 : if (!TREE_CONSTANT (elt))
7480 951799 : constant_p = false;
7481 3465344 : if (TREE_SIDE_EFFECTS (elt))
7482 281 : side_effects_p = true;
7483 3465344 : if (index && TREE_CODE (index) == COMPONENT_REF)
7484 : {
7485 : /* This is an initialization of a vfield inside a base
7486 : subaggregate that we already initialized; push this
7487 : initialization into the previous initialization. */
7488 0 : constructor_elt *inner = base_field_constructor_elt (*p, index);
7489 0 : inner->value = elt;
7490 0 : changed = true;
7491 0 : }
7492 3465344 : else if (no_slot)
7493 : /* This is an initializer for an empty field; now that we've
7494 : checked that it's constant, we can ignore it. */
7495 : changed = true;
7496 1944047 : else if (ctx->ctor)
7497 : {
7498 1944047 : if (TREE_CODE (type) == UNION_TYPE
7499 1944047 : && (*p)->last().index != index)
7500 : /* The initializer erroneously changed the active union member that
7501 : we're initializing. */
7502 7 : gcc_assert (*non_constant_p);
7503 : else
7504 : {
7505 : /* The initializer might have mutated the underlying CONSTRUCTOR,
7506 : so recompute the location of the target constructer_elt. */
7507 1944040 : constructor_elt *cep
7508 1944040 : = get_or_insert_ctor_field (ctx->ctor, index, pos_hint);
7509 1944040 : cep->value = elt;
7510 : }
7511 :
7512 : /* Adding or replacing an element might change the ctor's flags. */
7513 1944047 : TREE_CONSTANT (ctx->ctor) = constant_p;
7514 1944047 : TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
7515 : }
7516 : }
7517 3390850 : if (*non_constant_p)
7518 : return t;
7519 2665192 : if (!changed)
7520 : {
7521 267862 : if (VECTOR_TYPE_P (type))
7522 14408 : t = fold (t);
7523 : return t;
7524 : }
7525 2397330 : t = ctx->ctor;
7526 2397330 : if (!t)
7527 8 : t = build_constructor (type, NULL);
7528 : /* We're done building this CONSTRUCTOR, so now we can interpret an
7529 : element without an explicit initializer as value-initialized. */
7530 2397330 : CONSTRUCTOR_NO_CLEARING (t) = false;
7531 2397330 : TREE_CONSTANT (t) = constant_p;
7532 2397330 : TREE_SIDE_EFFECTS (t) = side_effects_p;
7533 2397330 : if (VECTOR_TYPE_P (type))
7534 11444 : t = fold (t);
7535 : return t;
7536 : }
7537 :
7538 : /* Subroutine of cxx_eval_constant_expression.
7539 : The expression tree T is a VEC_INIT_EXPR which denotes the desired
7540 : initialization of a non-static data member of array type. Reduce it to a
7541 : CONSTRUCTOR.
7542 :
7543 : Note that apart from value-initialization (when VALUE_INIT is true),
7544 : this is only intended to support value-initialization and the
7545 : initializations done by defaulted constructors for classes with
7546 : non-static data members of array type. In this case, VEC_INIT_EXPR_INIT
7547 : will either be NULL_TREE for the default constructor, or a COMPONENT_REF
7548 : for the copy/move constructor. */
7549 :
7550 : static tree
7551 906 : cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
7552 : bool value_init, value_cat lval,
7553 : bool *non_constant_p, bool *overflow_p,
7554 : tree *jump_target)
7555 : {
7556 906 : tree elttype = TREE_TYPE (atype);
7557 906 : verify_ctor_sanity (ctx, atype);
7558 906 : vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
7559 906 : bool pre_init = false;
7560 906 : unsigned HOST_WIDE_INT i;
7561 906 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7562 :
7563 906 : if (init && TREE_CODE (init) == CONSTRUCTOR)
7564 0 : return cxx_eval_bare_aggregate (ctx, init, lval,
7565 0 : non_constant_p, overflow_p, jump_target);
7566 :
7567 : /* We already checked access when building the VEC_INIT_EXPR. */
7568 906 : deferring_access_check_sentinel acs (dk_deferred);
7569 :
7570 : /* For the default constructor, build up a call to the default
7571 : constructor of the element type. We only need to handle class types
7572 : here, as for a constructor to be constexpr, all members must be
7573 : initialized, which for a defaulted default constructor means they must
7574 : be of a class type with a constexpr default constructor. */
7575 906 : if (TREE_CODE (elttype) == ARRAY_TYPE)
7576 : /* We only do this at the lowest level. */;
7577 852 : else if (value_init)
7578 : {
7579 338 : init = build_value_init (elttype, complain);
7580 338 : pre_init = true;
7581 : }
7582 514 : else if (!init)
7583 : {
7584 402 : releasing_vec argvec;
7585 402 : init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
7586 : &argvec, elttype, LOOKUP_NORMAL,
7587 : complain);
7588 402 : init = build_aggr_init_expr (elttype, init);
7589 402 : pre_init = true;
7590 402 : }
7591 :
7592 906 : bool zeroed_out = false;
7593 906 : if (!CONSTRUCTOR_NO_CLEARING (ctx->ctor))
7594 : {
7595 : /* We're initializing an array object that had been zero-initialized
7596 : earlier. Truncate ctx->ctor, and propagate its zeroed state by
7597 : clearing CONSTRUCTOR_NO_CLEARING on each of the aggregate element
7598 : initializers we append to it. */
7599 156 : gcc_checking_assert (initializer_zerop (ctx->ctor));
7600 156 : zeroed_out = true;
7601 156 : vec_safe_truncate (*p, 0);
7602 : }
7603 :
7604 906 : tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
7605 : overflow_p, jump_target);
7606 906 : if (*jump_target)
7607 : return NULL_TREE;
7608 906 : unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
7609 6676 : for (i = 0; i < max; ++i)
7610 : {
7611 6439 : tree idx = build_int_cst (size_type_node, i);
7612 6439 : tree eltinit;
7613 6439 : bool reuse = false;
7614 6439 : constexpr_ctx new_ctx;
7615 6903 : init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
7616 6439 : bool no_slot = new_ctx.ctor == NULL_TREE;
7617 6439 : if (new_ctx.ctor != ctx->ctor && !no_slot)
7618 : {
7619 6138 : if (zeroed_out)
7620 5445 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = false;
7621 6138 : CONSTRUCTOR_APPEND_ELT (*p, idx, new_ctx.ctor);
7622 : }
7623 6439 : if (TREE_CODE (elttype) == ARRAY_TYPE)
7624 : {
7625 : /* A multidimensional array; recurse. */
7626 186 : if (value_init || init == NULL_TREE)
7627 : {
7628 176 : eltinit = NULL_TREE;
7629 176 : reuse = i == 0;
7630 : }
7631 : else
7632 10 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7633 186 : eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit,
7634 : value_init, lval, non_constant_p,
7635 : overflow_p, jump_target);
7636 : }
7637 6253 : else if (pre_init)
7638 : {
7639 : /* Initializing an element using value or default initialization
7640 : we just pre-built above. */
7641 5975 : if (init == void_node)
7642 : /* Trivial default-init, don't do anything to the CONSTRUCTOR. */
7643 10 : return ctx->ctor;
7644 5965 : eltinit = init;
7645 5965 : if (CLASS_TYPE_P (elttype) && new_ctx.object)
7646 : /* Clarify what object is being initialized (118285). */
7647 5665 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7648 5965 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7649 : non_constant_p, overflow_p,
7650 : jump_target);
7651 5965 : reuse = i == 0;
7652 : }
7653 : else
7654 : {
7655 : /* Copying an element. */
7656 278 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7657 278 : if (!lvalue_p (init))
7658 232 : eltinit = move (eltinit);
7659 278 : eltinit = (perform_implicit_conversion_flags
7660 278 : (elttype, eltinit, complain,
7661 : LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
7662 271 : if (CLASS_TYPE_P (elttype)
7663 271 : && new_ctx.object
7664 526 : && !error_operand_p (eltinit))
7665 : /* Clarify what object is being initialized (118285). */
7666 244 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7667 278 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7668 : non_constant_p, overflow_p,
7669 : jump_target);
7670 : }
7671 6429 : if (*jump_target)
7672 : return NULL_TREE;
7673 6429 : if (*non_constant_p)
7674 : break;
7675 6251 : if (no_slot)
7676 : {
7677 : /* This is an initializer for an empty subobject; now that we've
7678 : checked that it's constant, we can ignore it. */
7679 0 : gcc_checking_assert (i == 0);
7680 : break;
7681 : }
7682 6251 : else if (new_ctx.ctor != ctx->ctor)
7683 : {
7684 : /* We appended this element above; update the value. */
7685 5957 : gcc_assert ((*p)->last().index == idx);
7686 5957 : (*p)->last().value = eltinit;
7687 : }
7688 : else
7689 294 : CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
7690 : /* Reuse the result of cxx_eval_constant_expression call
7691 : from the first iteration to all others if it is a constant
7692 : initializer that doesn't require relocations. */
7693 6251 : if (reuse
7694 6251 : && max > 1
7695 6251 : && (eltinit == NULL_TREE
7696 634 : || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
7697 634 : == null_pointer_node)))
7698 : {
7699 481 : if (new_ctx.ctor != ctx->ctor)
7700 201 : eltinit = new_ctx.ctor;
7701 481 : tree range = build2 (RANGE_EXPR, size_type_node,
7702 : build_int_cst (size_type_node, 1),
7703 481 : build_int_cst (size_type_node, max - 1));
7704 481 : CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
7705 481 : break;
7706 : }
7707 5770 : else if (i == 0)
7708 234 : vec_safe_reserve (*p, max);
7709 : }
7710 :
7711 896 : if (!*non_constant_p)
7712 : {
7713 718 : init = ctx->ctor;
7714 718 : CONSTRUCTOR_NO_CLEARING (init) = false;
7715 : }
7716 896 : return init;
7717 : }
7718 :
7719 : static tree
7720 792 : cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
7721 : value_cat lval,
7722 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
7723 : {
7724 792 : tree atype = TREE_TYPE (t);
7725 792 : tree init = VEC_INIT_EXPR_INIT (t);
7726 792 : bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
7727 792 : if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
7728 : ;
7729 83 : else if (CONSTRUCTOR_NELTS (init) == 0
7730 83 : && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
7731 : {
7732 : /* Handle {} as value-init. */
7733 : init = NULL_TREE;
7734 : value_init = true;
7735 : }
7736 : else
7737 : {
7738 : /* This is a more complicated case, like needing to loop over trailing
7739 : elements; call build_vec_init and evaluate the result. */
7740 72 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7741 72 : constexpr_ctx new_ctx = *ctx;
7742 72 : if (!ctx->object)
7743 : {
7744 : /* We want to have an initialization target for an VEC_INIT_EXPR.
7745 : If we don't already have one in CTX, use the VEC_INIT_EXPR_SLOT. */
7746 57 : new_ctx.object = VEC_INIT_EXPR_SLOT (t);
7747 57 : tree ctor = new_ctx.ctor = build_constructor (atype, NULL);
7748 57 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
7749 57 : ctx->global->put_value (new_ctx.object, ctor);
7750 57 : ctx = &new_ctx;
7751 : }
7752 72 : init = expand_vec_init_expr (ctx->object, t, complain);
7753 72 : return cxx_eval_constant_expression (ctx, init, lval, non_constant_p,
7754 : overflow_p, jump_target);
7755 : }
7756 720 : tree r = cxx_eval_vec_init_1 (ctx, atype, init, value_init,
7757 : lval, non_constant_p, overflow_p, jump_target);
7758 720 : if (*non_constant_p)
7759 : return t;
7760 : else
7761 568 : return r;
7762 : }
7763 :
7764 : /* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
7765 : where the desired type is an array of unknown bounds because the variable
7766 : has had its bounds deduced since the wrapping expression was created. */
7767 :
7768 : static bool
7769 451151610 : same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
7770 : {
7771 451151610 : while (TREE_CODE (type1) == ARRAY_TYPE
7772 144752 : && TREE_CODE (type2) == ARRAY_TYPE
7773 451151614 : && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
7774 : {
7775 2 : type1 = TREE_TYPE (type1);
7776 2 : type2 = TREE_TYPE (type2);
7777 : }
7778 451151610 : return same_type_ignoring_top_level_qualifiers_p (type1, type2);
7779 : }
7780 :
7781 : /* Try to determine the currently active union member for an expression
7782 : with UNION_TYPE. If it can be determined, return the FIELD_DECL,
7783 : otherwise return NULL_TREE. */
7784 :
7785 : static tree
7786 86 : cxx_union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target)
7787 : {
7788 86 : constexpr_ctx new_ctx = *ctx;
7789 86 : new_ctx.quiet = true;
7790 86 : bool non_constant_p = false, overflow_p = false;
7791 86 : tree ctor = cxx_eval_constant_expression (&new_ctx, t, vc_prvalue,
7792 : &non_constant_p,
7793 : &overflow_p, jump_target);
7794 86 : if (*jump_target)
7795 : return NULL_TREE;
7796 86 : if (TREE_CODE (ctor) == CONSTRUCTOR
7797 32 : && CONSTRUCTOR_NELTS (ctor) == 1
7798 20 : && CONSTRUCTOR_ELT (ctor, 0)->index
7799 106 : && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL)
7800 : return CONSTRUCTOR_ELT (ctor, 0)->index;
7801 : return NULL_TREE;
7802 : }
7803 :
7804 : /* Helper function for cxx_fold_indirect_ref_1, called recursively. */
7805 :
7806 : static tree
7807 15373785 : cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
7808 : tree op, unsigned HOST_WIDE_INT off, bool *empty_base,
7809 : tree *jump_target)
7810 : {
7811 24973204 : tree optype = TREE_TYPE (op);
7812 24973204 : unsigned HOST_WIDE_INT const_nunits;
7813 24973204 : if (off == 0 && similar_type_p (optype, type))
7814 : return op;
7815 15369016 : else if (cxx_dialect >= cxx26
7816 9435641 : && VAR_P (op)
7817 5434605 : && DECL_VTABLE_OR_VTT_P (op)
7818 15655 : && same_type_ignoring_top_level_qualifiers_p (type,
7819 : ptrdiff_type_node)
7820 15370361 : && POINTER_TYPE_P (strip_array_types (optype)))
7821 : {
7822 : /* We often read some virtual table elements using ptrdiff_t rather
7823 : than pointer type. */
7824 1345 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc,
7825 : strip_array_types (optype),
7826 : op, off, empty_base,
7827 : jump_target))
7828 1345 : return fold_convert (type, ret);
7829 : }
7830 15367671 : else if (TREE_CODE (optype) == COMPLEX_TYPE
7831 15367671 : && similar_type_p (type, TREE_TYPE (optype)))
7832 : {
7833 : /* *(foo *)&complexfoo => __real__ complexfoo */
7834 0 : if (off == 0)
7835 0 : return build1_loc (loc, REALPART_EXPR, type, op);
7836 : /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
7837 0 : else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
7838 0 : return build1_loc (loc, IMAGPART_EXPR, type, op);
7839 : }
7840 : /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF<vectorfoo,...> */
7841 15367671 : else if (VECTOR_TYPE_P (optype)
7842 0 : && similar_type_p (type, TREE_TYPE (optype))
7843 15367671 : && TYPE_VECTOR_SUBPARTS (optype).is_constant (&const_nunits))
7844 : {
7845 0 : unsigned HOST_WIDE_INT part_width = tree_to_uhwi (TYPE_SIZE_UNIT (type));
7846 0 : unsigned HOST_WIDE_INT max_offset = part_width * const_nunits;
7847 0 : if (off < max_offset && off % part_width == 0)
7848 : {
7849 0 : tree index = bitsize_int (off * BITS_PER_UNIT);
7850 0 : return build3_loc (loc, BIT_FIELD_REF, type, op,
7851 0 : TYPE_SIZE (type), index);
7852 : }
7853 : }
7854 : /* ((foo *)&fooarray)[x] => fooarray[x] */
7855 15367671 : else if (TREE_CODE (optype) == ARRAY_TYPE
7856 9599419 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
7857 24967090 : && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
7858 : {
7859 9599419 : tree type_domain = TYPE_DOMAIN (optype);
7860 9599419 : tree min_val = size_zero_node;
7861 9599419 : if (type_domain && TYPE_MIN_VALUE (type_domain))
7862 9599190 : min_val = TYPE_MIN_VALUE (type_domain);
7863 9599419 : unsigned HOST_WIDE_INT el_sz
7864 9599419 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
7865 9599419 : unsigned HOST_WIDE_INT idx = off / el_sz;
7866 9599419 : unsigned HOST_WIDE_INT rem = off % el_sz;
7867 9599419 : if (tree_fits_uhwi_p (min_val))
7868 : {
7869 9599419 : tree index = size_int (idx + tree_to_uhwi (min_val));
7870 9599419 : op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
7871 : NULL_TREE, NULL_TREE);
7872 9599419 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
7873 9599419 : empty_base, jump_target);
7874 : }
7875 : }
7876 : /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
7877 5768252 : else if (TREE_CODE (optype) == RECORD_TYPE
7878 5768252 : || TREE_CODE (optype) == UNION_TYPE)
7879 : {
7880 5759678 : if (TREE_CODE (optype) == UNION_TYPE)
7881 : /* For unions prefer the currently active member. */
7882 86 : if (tree field = cxx_union_active_member (ctx, op, jump_target))
7883 : {
7884 20 : unsigned HOST_WIDE_INT el_sz
7885 20 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7886 20 : if (off < el_sz)
7887 : {
7888 20 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7889 : op, field, NULL_TREE);
7890 20 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7891 : off, empty_base,
7892 : jump_target))
7893 : return ret;
7894 : }
7895 : }
7896 :
7897 : /* Handle conversion to "as base" type. */
7898 5759664 : if (CLASS_TYPE_P (optype)
7899 11519164 : && CLASSTYPE_AS_BASE (optype) == type)
7900 : return op;
7901 :
7902 : /* Handle conversion to an empty base class, which is represented with a
7903 : NOP_EXPR. Do this before spelunking into the non-empty subobjects,
7904 : which is likely to be a waste of time (109678). */
7905 5754190 : if (is_empty_class (type)
7906 5415294 : && CLASS_TYPE_P (optype)
7907 11169478 : && lookup_base (optype, type, ba_any, NULL, tf_none, off))
7908 : {
7909 2637494 : if (empty_base)
7910 2637489 : *empty_base = true;
7911 : return op;
7912 : }
7913 :
7914 3116696 : for (tree field = TYPE_FIELDS (optype);
7915 44499402 : field; field = DECL_CHAIN (field))
7916 44453178 : if (TREE_CODE (field) == FIELD_DECL
7917 3129228 : && TREE_TYPE (field) != error_mark_node
7918 47582406 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (field))))
7919 : {
7920 3129224 : tree pos = byte_position (field);
7921 3129224 : if (!tree_fits_uhwi_p (pos))
7922 0 : continue;
7923 3129224 : unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos);
7924 3129224 : unsigned HOST_WIDE_INT el_sz;
7925 3129224 : if (DECL_FIELD_IS_BASE (field)
7926 779447 : && CLASS_TYPE_P (optype)
7927 3908671 : && CLASSTYPE_VBASECLASSES (optype))
7928 7765 : el_sz = tree_to_uhwi (DECL_SIZE_UNIT (field));
7929 : else
7930 3121459 : el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7931 3129224 : if (upos <= off && off < upos + el_sz)
7932 : {
7933 3116497 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7934 : op, field, NULL_TREE);
7935 3116497 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7936 : off - upos,
7937 : empty_base,
7938 : jump_target))
7939 : return ret;
7940 : }
7941 : }
7942 : }
7943 :
7944 : return NULL_TREE;
7945 : }
7946 :
7947 : /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
7948 : match. We want to be less strict for simple *& folding; if we have a
7949 : non-const temporary that we access through a const pointer, that should
7950 : work. We handle this here rather than change fold_indirect_ref_1
7951 : because we're dealing with things like ADDR_EXPR of INTEGER_CST which
7952 : don't really make sense outside of constant expression evaluation. Also
7953 : we want to allow folding to COMPONENT_REF, which could cause trouble
7954 : with TBAA in fold_indirect_ref_1. */
7955 :
7956 : static tree
7957 197748195 : cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
7958 : tree op0, bool *empty_base, tree *jump_target)
7959 : {
7960 197748195 : tree sub = op0;
7961 197748195 : tree subtype;
7962 :
7963 : /* STRIP_NOPS, but stop if REINTERPRET_CAST_P. */
7964 407441587 : while (CONVERT_EXPR_P (sub) || TREE_CODE (sub) == NON_LVALUE_EXPR
7965 531893428 : || TREE_CODE (sub) == VIEW_CONVERT_EXPR)
7966 : {
7967 133922477 : if (TREE_CODE (sub) == NOP_EXPR
7968 133922477 : && REINTERPRET_CAST_P (sub))
7969 : return NULL_TREE;
7970 133922477 : sub = TREE_OPERAND (sub, 0);
7971 : }
7972 :
7973 197748195 : subtype = TREE_TYPE (sub);
7974 197748195 : if (!INDIRECT_TYPE_P (subtype))
7975 : return NULL_TREE;
7976 :
7977 : /* Canonicalizes the given OBJ/OFF pair by iteratively absorbing
7978 : the innermost component into the offset until it would make the
7979 : offset positive, so that cxx_fold_indirect_ref_1 can identify
7980 : more folding opportunities. */
7981 210004069 : auto canonicalize_obj_off = [] (tree& obj, tree& off) {
7982 12255923 : if (cxx_dialect >= cxx26)
7983 : {
7984 : /* For C++26, we need to fold *(B *)(&x.D.1234 + 32) used
7985 : to access virtual base members. */
7986 7369157 : tree nobj = obj;
7987 7369157 : while (TREE_CODE (nobj) == COMPONENT_REF
7988 7405105 : && DECL_FIELD_IS_BASE (TREE_OPERAND (nobj, 1)))
7989 35948 : nobj = TREE_OPERAND (nobj, 0);
7990 7369157 : if (nobj != obj
7991 28244 : && CLASS_TYPE_P (TREE_TYPE (nobj))
7992 7397401 : && CLASSTYPE_VBASECLASSES (TREE_TYPE (nobj)))
7993 2537 : while (obj != nobj)
7994 : {
7995 1424 : tree field = TREE_OPERAND (obj, 1);
7996 1424 : tree pos = byte_position (field);
7997 1424 : off = int_const_binop (PLUS_EXPR, off, pos);
7998 1424 : obj = TREE_OPERAND (obj, 0);
7999 : }
8000 : }
8001 15362172 : while (TREE_CODE (obj) == COMPONENT_REF
8002 : /* We need to preserve union member accesses so that we can
8003 : later properly diagnose accessing the wrong member. */
8004 6438521 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (obj, 0))) == RECORD_TYPE
8005 21575283 : && (tree_int_cst_sign_bit (off) || integer_zerop (off)))
8006 : {
8007 3294727 : tree field = TREE_OPERAND (obj, 1);
8008 3294727 : tree pos = byte_position (field);
8009 3294727 : if (integer_zerop (off) && integer_nonzerop (pos))
8010 : /* If the offset is already 0, keep going as long as the
8011 : component is at position 0. */
8012 : break;
8013 3106249 : off = int_const_binop (PLUS_EXPR, off, pos);
8014 3106249 : obj = TREE_OPERAND (obj, 0);
8015 : }
8016 12255923 : };
8017 :
8018 197748146 : if (TREE_CODE (sub) == ADDR_EXPR)
8019 : {
8020 88273486 : tree op = TREE_OPERAND (sub, 0);
8021 88273486 : tree optype = TREE_TYPE (op);
8022 :
8023 : /* *&CONST_DECL -> to the value of the const decl. */
8024 88273486 : if (TREE_CODE (op) == CONST_DECL)
8025 0 : return DECL_INITIAL (op);
8026 : /* *&p => p; make sure to handle *&"str"[cst] here. */
8027 88273486 : if (similar_type_p (optype, type))
8028 : {
8029 84356892 : tree fop = fold_read_from_constant_string (op);
8030 84356892 : if (fop)
8031 : return fop;
8032 : else
8033 84148945 : return op;
8034 : }
8035 : else
8036 : {
8037 3916594 : tree off = integer_zero_node;
8038 3916594 : canonicalize_obj_off (op, off);
8039 3916594 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op,
8040 : tree_to_uhwi (off), empty_base,
8041 : jump_target);
8042 : }
8043 : }
8044 109474660 : else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
8045 109474660 : && tree_fits_uhwi_p (TREE_OPERAND (sub, 1)))
8046 : {
8047 8937889 : tree op00 = TREE_OPERAND (sub, 0);
8048 8937889 : tree off = TREE_OPERAND (sub, 1);
8049 :
8050 8937889 : STRIP_NOPS (op00);
8051 8937889 : if (TREE_CODE (op00) == ADDR_EXPR)
8052 : {
8053 8339329 : tree obj = TREE_OPERAND (op00, 0);
8054 8339329 : canonicalize_obj_off (obj, off);
8055 8339329 : return cxx_fold_indirect_ref_1 (ctx, loc, type, obj,
8056 : tree_to_uhwi (off), empty_base,
8057 : jump_target);
8058 : }
8059 : }
8060 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
8061 100536771 : else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
8062 100536771 : && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
8063 : {
8064 0 : tree type_domain;
8065 0 : tree min_val = size_zero_node;
8066 0 : tree newsub
8067 0 : = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL,
8068 : jump_target);
8069 0 : if (*jump_target)
8070 : return NULL_TREE;
8071 0 : if (newsub)
8072 : sub = newsub;
8073 : else
8074 0 : sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
8075 0 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
8076 0 : if (type_domain && TYPE_MIN_VALUE (type_domain))
8077 0 : min_val = TYPE_MIN_VALUE (type_domain);
8078 0 : return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
8079 0 : NULL_TREE);
8080 : }
8081 :
8082 : return NULL_TREE;
8083 : }
8084 :
8085 : static tree
8086 104458535 : cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
8087 : value_cat lval,
8088 : bool *non_constant_p, bool *overflow_p,
8089 : tree *jump_target)
8090 : {
8091 104458535 : tree orig_op0 = TREE_OPERAND (t, 0);
8092 104458535 : bool empty_base = false;
8093 :
8094 : /* We can handle a MEM_REF like an INDIRECT_REF, if MEM_REF's second
8095 : operand is an integer-zero. Otherwise reject the MEM_REF for now. */
8096 :
8097 104458535 : if (TREE_CODE (t) == MEM_REF
8098 104458535 : && (!TREE_OPERAND (t, 1) || !integer_zerop (TREE_OPERAND (t, 1))))
8099 : {
8100 9 : gcc_assert (ctx->quiet);
8101 9 : *non_constant_p = true;
8102 9 : return t;
8103 : }
8104 :
8105 : /* First try to simplify it directly. */
8106 104458526 : tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
8107 : orig_op0, &empty_base, jump_target);
8108 104458526 : if (*jump_target)
8109 : return NULL_TREE;
8110 104458526 : if (!r)
8111 : {
8112 : /* If that didn't work, evaluate the operand first. */
8113 100446807 : tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
8114 : vc_prvalue, non_constant_p,
8115 : overflow_p, jump_target);
8116 100446807 : if (*jump_target)
8117 : return NULL_TREE;
8118 : /* Don't VERIFY_CONSTANT here. */
8119 100446795 : if (*non_constant_p)
8120 : return t;
8121 :
8122 79435603 : if (!lval && integer_zerop (op0))
8123 : {
8124 73 : if (!ctx->quiet)
8125 12 : error ("dereferencing a null pointer");
8126 73 : *non_constant_p = true;
8127 73 : return t;
8128 : }
8129 :
8130 79435530 : r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0,
8131 : &empty_base, jump_target);
8132 79435530 : if (*jump_target)
8133 : return NULL_TREE;
8134 79435530 : if (r == NULL_TREE)
8135 : {
8136 : /* We couldn't fold to a constant value. Make sure it's not
8137 : something we should have been able to fold. */
8138 697009 : tree sub = op0;
8139 697009 : STRIP_NOPS (sub);
8140 697009 : if (TREE_CODE (sub) == ADDR_EXPR)
8141 : {
8142 4135 : gcc_assert (!similar_type_p
8143 : (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
8144 : /* DR 1188 says we don't have to deal with this. */
8145 4135 : if (!ctx->quiet)
8146 : {
8147 9 : auto_diagnostic_group d;
8148 15 : error_at (cp_expr_loc_or_input_loc (t),
8149 : "accessing value of %qT object through a %qT "
8150 : "glvalue in a constant expression",
8151 9 : TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t));
8152 9 : tree ob = build_fold_indirect_ref (sub);
8153 9 : if (DECL_P (ob))
8154 : {
8155 9 : if (DECL_ARTIFICIAL (ob))
8156 2 : inform (DECL_SOURCE_LOCATION (ob),
8157 2 : "%qT object created here", TREE_TYPE (ob));
8158 : else
8159 7 : inform (DECL_SOURCE_LOCATION (ob),
8160 : "%q#D declared here", ob);
8161 : }
8162 9 : }
8163 4135 : *non_constant_p = true;
8164 4135 : return t;
8165 : }
8166 :
8167 692874 : if (lval == vc_glvalue && op0 != orig_op0)
8168 83366 : return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
8169 609508 : if (!lval)
8170 498875 : VERIFY_CONSTANT (t);
8171 : return t;
8172 : }
8173 : }
8174 :
8175 82750240 : r = cxx_eval_constant_expression (ctx, r,
8176 : lval, non_constant_p, overflow_p,
8177 : jump_target);
8178 82750238 : if (*jump_target)
8179 : return NULL_TREE;
8180 82750238 : if (*non_constant_p)
8181 : return t;
8182 :
8183 : /* If we're pulling out the value of an empty base, just return an empty
8184 : CONSTRUCTOR. */
8185 73681742 : if (empty_base && !lval)
8186 : {
8187 19439 : r = build_constructor (TREE_TYPE (t), NULL);
8188 19439 : TREE_CONSTANT (r) = true;
8189 : }
8190 :
8191 : return r;
8192 : }
8193 :
8194 : /* Complain about R, a DECL that is accessed outside its lifetime. */
8195 :
8196 : static void
8197 45 : outside_lifetime_error (location_t loc, tree r)
8198 : {
8199 45 : auto_diagnostic_group d;
8200 45 : if (DECL_NAME (r) == heap_deleted_identifier)
8201 : {
8202 : /* Provide a more accurate message for deleted variables. */
8203 14 : error_at (loc, "use of allocated storage after deallocation "
8204 : "in a constant expression");
8205 14 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8206 : }
8207 : else
8208 : {
8209 31 : error_at (loc, "accessing %qE outside its lifetime", r);
8210 31 : inform (DECL_SOURCE_LOCATION (r), "declared here");
8211 : }
8212 45 : }
8213 :
8214 : /* Complain about R, a VAR_DECL, not being usable in a constant expression.
8215 : FUNDEF_P is true if we're checking a constexpr function body.
8216 : Shared between potential_constant_expression and
8217 : cxx_eval_constant_expression. */
8218 :
8219 : static void
8220 354 : non_const_var_error (location_t loc, tree r, bool fundef_p)
8221 : {
8222 354 : auto_diagnostic_group d;
8223 354 : tree type = TREE_TYPE (r);
8224 354 : if (DECL_NAME (r) == heap_uninit_identifier
8225 354 : || DECL_NAME (r) == heap_identifier
8226 351 : || DECL_NAME (r) == heap_vec_uninit_identifier
8227 705 : || DECL_NAME (r) == heap_vec_identifier)
8228 : {
8229 3 : if (constexpr_error (loc, fundef_p, "the content of uninitialized "
8230 : "storage is not usable in a constant expression"))
8231 3 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8232 : return;
8233 : }
8234 351 : if (DECL_NAME (r) == heap_deleted_identifier)
8235 : {
8236 0 : if (constexpr_error (loc, fundef_p, "use of allocated storage after "
8237 : "deallocation in a constant expression"))
8238 0 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8239 : return;
8240 : }
8241 351 : if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
8242 : "a constant expression", r))
8243 : return;
8244 : /* Avoid error cascade. */
8245 344 : if (DECL_INITIAL (r) == error_mark_node)
8246 : return;
8247 328 : if (DECL_DECLARED_CONSTEXPR_P (r))
8248 3 : inform (DECL_SOURCE_LOCATION (r),
8249 : "%qD used in its own initializer", r);
8250 325 : else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
8251 : {
8252 225 : if (!CP_TYPE_CONST_P (type))
8253 196 : inform (DECL_SOURCE_LOCATION (r),
8254 : "%q#D is not const", r);
8255 29 : else if (CP_TYPE_VOLATILE_P (type))
8256 0 : inform (DECL_SOURCE_LOCATION (r),
8257 : "%q#D is volatile", r);
8258 29 : else if (!DECL_INITIAL (r)
8259 9 : || !TREE_CONSTANT (DECL_INITIAL (r))
8260 37 : || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
8261 29 : inform (DECL_SOURCE_LOCATION (r),
8262 : "%qD was not initialized with a constant "
8263 : "expression", r);
8264 : else
8265 0 : gcc_unreachable ();
8266 : }
8267 100 : else if (TYPE_REF_P (type))
8268 9 : inform (DECL_SOURCE_LOCATION (r),
8269 : "%qD was not initialized with a constant "
8270 : "expression", r);
8271 : else
8272 : {
8273 91 : if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
8274 91 : inform (DECL_SOURCE_LOCATION (r),
8275 : "%qD was not declared %<constexpr%>", r);
8276 : else
8277 0 : inform (DECL_SOURCE_LOCATION (r),
8278 : "%qD does not have integral or enumeration type",
8279 : r);
8280 : }
8281 354 : }
8282 :
8283 : /* Subroutine of cxx_eval_constant_expression.
8284 : Like cxx_eval_unary_expression, except for trinary expressions. */
8285 :
8286 : static tree
8287 43640 : cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
8288 : value_cat lval,
8289 : bool *non_constant_p, bool *overflow_p,
8290 : tree *jump_target)
8291 : {
8292 43640 : int i;
8293 43640 : tree args[3];
8294 43640 : tree val;
8295 :
8296 168053 : for (i = 0; i < 3; i++)
8297 : {
8298 126582 : args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
8299 : lval,
8300 : non_constant_p, overflow_p,
8301 : jump_target);
8302 126582 : if (*jump_target)
8303 : return NULL_TREE;
8304 126582 : VERIFY_CONSTANT (args[i]);
8305 : }
8306 :
8307 41471 : val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
8308 : args[0], args[1], args[2]);
8309 41471 : if (val == NULL_TREE)
8310 : return t;
8311 41471 : VERIFY_CONSTANT (val);
8312 : return val;
8313 : }
8314 :
8315 : /* True if T was declared in a function declared to be constexpr, and
8316 : therefore potentially constant in C++14. */
8317 :
8318 : bool
8319 89997604 : var_in_constexpr_fn (tree t)
8320 : {
8321 89997604 : tree ctx = DECL_CONTEXT (t);
8322 89997604 : return (ctx && TREE_CODE (ctx) == FUNCTION_DECL
8323 171440180 : && DECL_DECLARED_CONSTEXPR_P (ctx));
8324 : }
8325 :
8326 : /* True if a function might be constexpr: either a function that was
8327 : declared constexpr, or a C++17 lambda op(). */
8328 :
8329 : bool
8330 738812979 : maybe_constexpr_fn (tree t)
8331 : {
8332 738812979 : return (DECL_DECLARED_CONSTEXPR_P (t)
8333 226549591 : || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t))
8334 956722136 : || (flag_implicit_constexpr
8335 96 : && DECL_DECLARED_INLINE_P (STRIP_TEMPLATE (t))));
8336 : }
8337 :
8338 : /* True if T was declared in a function that might be constexpr: either a
8339 : function that was declared constexpr, or a C++17 lambda op(). */
8340 :
8341 : bool
8342 66983501 : var_in_maybe_constexpr_fn (tree t)
8343 : {
8344 133966355 : return (DECL_FUNCTION_SCOPE_P (t)
8345 122422920 : && maybe_constexpr_fn (DECL_CONTEXT (t)));
8346 : }
8347 :
8348 : /* We're assigning INIT to TARGET. In do_build_copy_constructor and
8349 : build_over_call we implement trivial copy of a class with tail padding using
8350 : assignment of character arrays, which is valid in normal code, but not in
8351 : constexpr evaluation. We don't need to worry about clobbering tail padding
8352 : in constexpr evaluation, so strip the type punning. */
8353 :
8354 : static void
8355 104160819 : maybe_simplify_trivial_copy (tree &target, tree &init)
8356 : {
8357 104160819 : if (TREE_CODE (target) == MEM_REF
8358 36160 : && TREE_CODE (init) == MEM_REF
8359 35992 : && TREE_TYPE (target) == TREE_TYPE (init)
8360 35992 : && TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
8361 104196811 : && TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
8362 : {
8363 35992 : target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
8364 35992 : init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
8365 : }
8366 104160819 : }
8367 :
8368 : /* Returns true if REF, which is a COMPONENT_REF, has any fields
8369 : of constant type. This does not check for 'mutable', so the
8370 : caller is expected to be mindful of that. */
8371 :
8372 : static bool
8373 419 : cref_has_const_field (tree ref)
8374 : {
8375 488 : while (TREE_CODE (ref) == COMPONENT_REF)
8376 : {
8377 479 : if (CP_TYPE_CONST_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
8378 : return true;
8379 69 : ref = TREE_OPERAND (ref, 0);
8380 : }
8381 : return false;
8382 : }
8383 :
8384 : /* Return true if we are modifying something that is const during constant
8385 : expression evaluation. CODE is the code of the statement, OBJ is the
8386 : object in question, MUTABLE_P is true if one of the subobjects were
8387 : declared mutable. */
8388 :
8389 : static bool
8390 107860976 : modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
8391 : {
8392 : /* If this is initialization, there's no problem. */
8393 107860976 : if (code == INIT_EXPR)
8394 : return false;
8395 :
8396 : /* [basic.type.qualifier] "A const object is an object of type
8397 : const T or a non-mutable subobject of a const object." */
8398 30066871 : if (mutable_p)
8399 : return false;
8400 :
8401 30066129 : if (TREE_READONLY (obj))
8402 : return true;
8403 :
8404 30011426 : if (CP_TYPE_CONST_P (TREE_TYPE (obj)))
8405 : {
8406 : /* Although a COMPONENT_REF may have a const type, we should
8407 : only consider it modifying a const object when any of the
8408 : field components is const. This can happen when using
8409 : constructs such as const_cast<const T &>(m), making something
8410 : const even though it wasn't declared const. */
8411 34329 : if (TREE_CODE (obj) == COMPONENT_REF)
8412 419 : return cref_has_const_field (obj);
8413 : else
8414 : return true;
8415 : }
8416 :
8417 : return false;
8418 : }
8419 :
8420 : /* Evaluate an INIT_EXPR or MODIFY_EXPR or MODOP_EXPR. MODOP_EXPR means
8421 : we are evaluating __builtin_start_lifetime (init is in the second
8422 : operand rather than third, like for INIT_EXPR and MODIFY_EXPR). */
8423 :
8424 : static tree
8425 104160819 : cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
8426 : value_cat lval,
8427 : bool *non_constant_p, bool *overflow_p,
8428 : tree *jump_target)
8429 : {
8430 104160819 : constexpr_ctx new_ctx = *ctx;
8431 :
8432 104160819 : tree init = TREE_OPERAND (t, 1);
8433 :
8434 : /* First we figure out where we're storing to. */
8435 104160819 : tree target = TREE_OPERAND (t, 0);
8436 :
8437 104160819 : maybe_simplify_trivial_copy (target, init);
8438 :
8439 104160819 : tree type = TREE_TYPE (target);
8440 104160819 : bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) != INIT_EXPR;
8441 73040373 : if (preeval && !TREE_CLOBBER_P (init) && TREE_CODE (t) != MODOP_EXPR)
8442 : {
8443 : /* Ignore var = .DEFERRED_INIT (); for now, until PR121965 is fixed. */
8444 72001487 : if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
8445 42052521 : && TREE_CODE (init) == CALL_EXPR
8446 6967426 : && CALL_EXPR_FN (init) == NULL_TREE
8447 72001495 : && CALL_EXPR_IFN (init) == IFN_DEFERRED_INIT)
8448 8 : return void_node;
8449 :
8450 : /* Evaluate the value to be stored without knowing what object it will be
8451 : stored in, so that any side-effects happen first. */
8452 72001479 : if (!SCALAR_TYPE_P (type))
8453 203798 : new_ctx.ctor = new_ctx.object = NULL_TREE;
8454 72001479 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8455 : non_constant_p, overflow_p,
8456 : jump_target);
8457 72001475 : if (*jump_target)
8458 : return NULL_TREE;
8459 72001207 : if (*non_constant_p)
8460 : return t;
8461 : }
8462 :
8463 94971002 : bool evaluated = false;
8464 94971002 : if (lval == vc_glvalue)
8465 : {
8466 : /* If we want to return a reference to the target, we need to evaluate it
8467 : as a whole; otherwise, only evaluate the innermost piece to avoid
8468 : building up unnecessary *_REFs. */
8469 0 : target = cxx_eval_constant_expression (ctx, target, lval,
8470 : non_constant_p, overflow_p,
8471 : jump_target);
8472 0 : evaluated = true;
8473 0 : if (*jump_target)
8474 : return NULL_TREE;
8475 0 : if (*non_constant_p)
8476 : return t;
8477 : }
8478 :
8479 : /* Find the underlying variable. */
8480 94971002 : releasing_vec refs;
8481 94971002 : tree object = NULL_TREE;
8482 : /* If we're modifying a const object, save it. */
8483 94971002 : tree const_object_being_modified = NULL_TREE;
8484 94971002 : bool mutable_p = false;
8485 : /* If we see a union, we can't ignore clobbers. */
8486 94971002 : int seen_union = 0;
8487 321226330 : for (tree probe = target; object == NULL_TREE; )
8488 : {
8489 226255783 : switch (TREE_CODE (probe))
8490 : {
8491 36314105 : case BIT_FIELD_REF:
8492 36314105 : case COMPONENT_REF:
8493 36314105 : case ARRAY_REF:
8494 36314105 : {
8495 36314105 : tree ob = TREE_OPERAND (probe, 0);
8496 36314105 : tree elt = TREE_OPERAND (probe, 1);
8497 36314105 : if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt))
8498 : mutable_p = true;
8499 36314105 : if (TREE_CODE (probe) == ARRAY_REF)
8500 : {
8501 5864584 : elt = eval_and_check_array_index (ctx, probe, false,
8502 : non_constant_p, overflow_p,
8503 : jump_target);
8504 5864584 : if (*jump_target)
8505 69 : return NULL_TREE;
8506 5864584 : if (*non_constant_p)
8507 : return t;
8508 : }
8509 : /* We don't check modifying_const_object_p for ARRAY_REFs. Given
8510 : "int a[10]", an ARRAY_REF "a[2]" can be "const int", even though
8511 : the array isn't const. Instead, check "a" in the next iteration;
8512 : that will detect modifying "const int a[10]". */
8513 30449521 : else if (evaluated
8514 12890429 : && modifying_const_object_p (TREE_CODE (t), probe,
8515 : mutable_p)
8516 30450135 : && const_object_being_modified == NULL_TREE)
8517 : const_object_being_modified = probe;
8518 :
8519 : /* Track named member accesses for unions to validate modifications
8520 : that change active member. */
8521 36314036 : if (!evaluated && TREE_CODE (probe) == COMPONENT_REF)
8522 17559092 : vec_safe_push (refs, probe);
8523 : else
8524 18754944 : vec_safe_push (refs, NULL_TREE);
8525 :
8526 36314036 : vec_safe_push (refs, elt);
8527 36314036 : vec_safe_push (refs, TREE_TYPE (probe));
8528 36314036 : probe = ob;
8529 36314036 : if (TREE_CODE (TREE_TYPE (ob)) == UNION_TYPE)
8530 586433 : ++seen_union;
8531 : }
8532 36314036 : break;
8533 :
8534 30 : case REALPART_EXPR:
8535 30 : gcc_assert (refs->is_empty ());
8536 30 : vec_safe_push (refs, NULL_TREE);
8537 30 : vec_safe_push (refs, probe);
8538 30 : vec_safe_push (refs, TREE_TYPE (probe));
8539 30 : probe = TREE_OPERAND (probe, 0);
8540 30 : break;
8541 :
8542 31 : case IMAGPART_EXPR:
8543 31 : gcc_assert (refs->is_empty ());
8544 31 : vec_safe_push (refs, NULL_TREE);
8545 31 : vec_safe_push (refs, probe);
8546 31 : vec_safe_push (refs, TREE_TYPE (probe));
8547 31 : probe = TREE_OPERAND (probe, 0);
8548 31 : break;
8549 :
8550 189941617 : default:
8551 189941617 : if (evaluated)
8552 : object = probe;
8553 : else
8554 : {
8555 94971070 : tree pvar = tree_strip_any_location_wrapper (probe);
8556 94971070 : if (VAR_P (pvar) && DECL_ANON_UNION_VAR_P (pvar))
8557 : {
8558 : /* Stores to DECL_ANON_UNION_VAR_P var are allowed to change
8559 : active union member. */
8560 101 : probe = DECL_VALUE_EXPR (pvar);
8561 101 : break;
8562 : }
8563 94970969 : probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue,
8564 : non_constant_p, overflow_p,
8565 : jump_target);
8566 94970969 : evaluated = true;
8567 94970969 : if (*jump_target)
8568 : return NULL_TREE;
8569 94970969 : if (*non_constant_p)
8570 : return t;
8571 : }
8572 : break;
8573 : }
8574 : }
8575 :
8576 94970547 : if (modifying_const_object_p (TREE_CODE (t), object, mutable_p)
8577 94970547 : && const_object_being_modified == NULL_TREE)
8578 94970547 : const_object_being_modified = object;
8579 :
8580 94970547 : if (DECL_P (object)
8581 94968537 : && TREE_CLOBBER_P (init)
8582 96032127 : && DECL_NAME (object) == heap_deleted_identifier)
8583 : /* Ignore clobbers of deleted allocations for now; we'll get a better error
8584 : message later when operator delete is called. */
8585 15 : return void_node;
8586 :
8587 : /* And then find/build up our initializer for the path to the subobject
8588 : we're initializing. */
8589 94970532 : tree *valp;
8590 94970532 : if (DECL_P (object))
8591 94968522 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8592 : else
8593 : valp = NULL;
8594 94970532 : if (!valp)
8595 : {
8596 : /* A constant-expression cannot modify objects from outside the
8597 : constant-expression. */
8598 11621 : if (!ctx->quiet)
8599 : {
8600 31 : auto_diagnostic_group d;
8601 31 : if (DECL_P (object) && DECL_NAME (object) == heap_deleted_identifier)
8602 : {
8603 0 : error ("modification of allocated storage after deallocation "
8604 : "is not a constant expression");
8605 0 : inform (DECL_SOURCE_LOCATION (object), "allocated here");
8606 : }
8607 31 : else if (DECL_P (object) && ctx->global->is_outside_lifetime (object))
8608 : {
8609 14 : if (TREE_CLOBBER_P (init))
8610 6 : error ("destroying %qE outside its lifetime", object);
8611 : else
8612 8 : error ("modification of %qE outside its lifetime "
8613 : "is not a constant expression", object);
8614 14 : inform (DECL_SOURCE_LOCATION (object), "declared here");
8615 : }
8616 : else
8617 : {
8618 17 : if (TREE_CLOBBER_P (init))
8619 6 : error ("destroying %qE from outside current evaluation "
8620 : "is not a constant expression", object);
8621 : else
8622 11 : error ("modification of %qE from outside current evaluation "
8623 : "is not a constant expression", object);
8624 : }
8625 31 : }
8626 11621 : *non_constant_p = true;
8627 11621 : return t;
8628 : }
8629 :
8630 : /* Handle explicit end-of-lifetime. */
8631 94958911 : if (TREE_CLOBBER_P (init))
8632 : {
8633 1061514 : if (CLOBBER_KIND (init) >= CLOBBER_OBJECT_END
8634 1061514 : && refs->is_empty ())
8635 : {
8636 300411 : ctx->global->destroy_value (object, (CLOBBER_KIND (init)
8637 : > CLOBBER_OBJECT_END));
8638 300411 : return void_node;
8639 : }
8640 :
8641 747867 : if (!seen_union && !*valp
8642 771501 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
8643 10363 : return void_node;
8644 :
8645 : /* Ending the lifetime of a const object is OK. */
8646 : const_object_being_modified = NULL_TREE;
8647 : }
8648 :
8649 94648137 : type = TREE_TYPE (object);
8650 94648137 : bool no_zero_init = true;
8651 94648137 : bool zero_padding_bits = false;
8652 :
8653 189296274 : auto_vec<tree *> ctors;
8654 189296274 : releasing_vec indexes;
8655 189296274 : auto_vec<int> index_pos_hints;
8656 94648137 : bool activated_union_member_p = false;
8657 94648137 : bool empty_base = false;
8658 130640263 : while (!refs->is_empty ())
8659 : {
8660 36283651 : if (*valp == NULL_TREE || *valp == void_node)
8661 : {
8662 2944806 : *valp = build_constructor (type, NULL);
8663 2944806 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8664 2944806 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8665 : }
8666 33338845 : else if (STRIP_ANY_LOCATION_WRAPPER (*valp),
8667 33338845 : TREE_CODE (*valp) == STRING_CST)
8668 : {
8669 : /* An array was initialized with a string constant, and now
8670 : we're writing into one of its elements. Explode the
8671 : single initialization into a set of element
8672 : initializations. */
8673 11455 : gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
8674 :
8675 11455 : tree string = *valp;
8676 11455 : tree elt_type = TREE_TYPE (type);
8677 11455 : unsigned chars_per_elt = (TYPE_PRECISION (elt_type)
8678 11455 : / TYPE_PRECISION (char_type_node));
8679 11455 : unsigned num_elts = TREE_STRING_LENGTH (string) / chars_per_elt;
8680 11455 : tree ary_ctor = build_constructor (type, NULL);
8681 :
8682 11455 : vec_safe_reserve (CONSTRUCTOR_ELTS (ary_ctor), num_elts);
8683 34533 : for (unsigned ix = 0; ix != num_elts; ix++)
8684 : {
8685 11623 : constructor_elt elt =
8686 : {
8687 11623 : build_int_cst (size_type_node, ix),
8688 11623 : extract_string_elt (string, chars_per_elt, ix)
8689 11623 : };
8690 11623 : CONSTRUCTOR_ELTS (ary_ctor)->quick_push (elt);
8691 : }
8692 :
8693 11455 : *valp = ary_ctor;
8694 : }
8695 :
8696 36283651 : enum tree_code code = TREE_CODE (type);
8697 36283651 : tree reftype = refs->pop();
8698 36283651 : tree index = refs->pop();
8699 36283651 : bool is_access_expr = refs->pop() != NULL_TREE;
8700 :
8701 36283651 : if (code == COMPLEX_TYPE)
8702 : {
8703 61 : if (TREE_CODE (*valp) == COMPLEX_CST)
8704 51 : *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp),
8705 51 : TREE_IMAGPART (*valp));
8706 10 : else if (TREE_CODE (*valp) == CONSTRUCTOR
8707 2 : && CONSTRUCTOR_NELTS (*valp) == 0
8708 12 : && CONSTRUCTOR_NO_CLEARING (*valp))
8709 : {
8710 2 : tree r = build_constructor (reftype, NULL);
8711 2 : CONSTRUCTOR_NO_CLEARING (r) = 1;
8712 2 : *valp = build2 (COMPLEX_EXPR, type, r, r);
8713 : }
8714 61 : gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR);
8715 61 : ctors.safe_push (valp);
8716 61 : vec_safe_push (indexes, index);
8717 61 : valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR);
8718 61 : gcc_checking_assert (refs->is_empty ());
8719 : type = reftype;
8720 287013 : break;
8721 : }
8722 :
8723 : /* If the value of object is already zero-initialized, any new ctors for
8724 : subobjects will also be zero-initialized. Similarly with zeroing of
8725 : padding bits. */
8726 36283590 : no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
8727 36283590 : zero_padding_bits = CONSTRUCTOR_ZERO_PADDING_BITS (*valp);
8728 :
8729 36283590 : if (code == RECORD_TYPE && is_empty_field (index))
8730 : /* Don't build a sub-CONSTRUCTOR for an empty base or field, as they
8731 : have no data and might have an offset lower than previously declared
8732 : fields, which confuses the middle-end. The code below will notice
8733 : that we don't have a CONSTRUCTOR for our inner target and just
8734 : return init. */
8735 : {
8736 : empty_base = true;
8737 : break;
8738 : }
8739 :
8740 : /* If a union is zero-initialized, its first non-static named data member
8741 : is zero-initialized (and therefore active). */
8742 35996638 : if (code == UNION_TYPE
8743 35996638 : && !no_zero_init
8744 35996638 : && CONSTRUCTOR_NELTS (*valp) == 0)
8745 4079 : if (tree first = next_aggregate_field (TYPE_FIELDS (type)))
8746 4079 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (*valp), first, NULL_TREE);
8747 :
8748 : /* Check for implicit change of active member for a union. */
8749 :
8750 : /* LWG3436, CWG2675, c++/121068: The array object model is confused. For
8751 : now allow initializing an array element to activate the array. */
8752 36048971 : auto only_array_refs = [](const releasing_vec &refs)
8753 : {
8754 52338 : for (unsigned i = 1; i < refs->length(); i += 3)
8755 35 : if (TREE_CODE ((*refs)[i]) != INTEGER_CST)
8756 : return false;
8757 : return true;
8758 : };
8759 :
8760 35996638 : if (code == UNION_TYPE
8761 584445 : && (CONSTRUCTOR_NELTS (*valp) == 0
8762 380860 : || CONSTRUCTOR_ELT (*valp, 0)->index != index)
8763 : /* An INIT_EXPR of the last member in an access chain is always OK,
8764 : but still check implicit change of members earlier on; see
8765 : cpp2a/constexpr-union6.C. */
8766 36212703 : && !(TREE_CODE (t) == INIT_EXPR && only_array_refs (refs)))
8767 : {
8768 163762 : bool has_active_member = CONSTRUCTOR_NELTS (*valp) != 0;
8769 163762 : tree inner = strip_array_types (reftype);
8770 :
8771 163762 : if (has_active_member && cxx_dialect < cxx20)
8772 : {
8773 58 : if (!ctx->quiet)
8774 19 : error_at (cp_expr_loc_or_input_loc (t),
8775 : "change of the active member of a union "
8776 : "from %qD to %qD is not a constant expression "
8777 : "before C++20",
8778 19 : CONSTRUCTOR_ELT (*valp, 0)->index,
8779 : index);
8780 58 : *non_constant_p = true;
8781 : }
8782 163704 : else if ((!is_access_expr
8783 47495 : || (TREE_CLOBBER_P (init)
8784 0 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8785 47495 : || (TREE_CODE (t) != INIT_EXPR
8786 47483 : && CLASS_TYPE_P (inner)
8787 482 : && !type_has_non_deleted_trivial_default_ctor (inner)))
8788 163789 : && TREE_CODE (t) != MODOP_EXPR)
8789 : {
8790 : /* Diagnose changing active union member after initialization
8791 : without a valid member access expression, as described in
8792 : [class.union.general] p5. */
8793 116218 : if (!ctx->quiet)
8794 : {
8795 33 : auto_diagnostic_group d;
8796 33 : if (has_active_member)
8797 24 : error_at (cp_expr_loc_or_input_loc (t),
8798 : "accessing %qD member instead of initialized "
8799 : "%qD member in constant expression",
8800 24 : index, CONSTRUCTOR_ELT (*valp, 0)->index);
8801 : else
8802 9 : error_at (cp_expr_loc_or_input_loc (t),
8803 : "accessing uninitialized member %qD",
8804 : index);
8805 33 : if (is_access_expr)
8806 3 : inform (DECL_SOURCE_LOCATION (index),
8807 : "%qD does not implicitly begin its lifetime "
8808 : "because %qT does not have a non-deleted "
8809 : "trivial default constructor, use "
8810 : "%<std::construct_at%> instead",
8811 : index, inner);
8812 : else
8813 30 : inform (DECL_SOURCE_LOCATION (index),
8814 : "initializing %qD requires a member access "
8815 : "expression as the left operand of the assignment",
8816 : index);
8817 33 : }
8818 116218 : *non_constant_p = true;
8819 : }
8820 47486 : else if (has_active_member && CONSTRUCTOR_NO_CLEARING (*valp))
8821 : {
8822 : /* Diagnose changing the active union member while the union
8823 : is in the process of being initialized. */
8824 18 : if (!ctx->quiet)
8825 6 : error_at (cp_expr_loc_or_input_loc (t),
8826 : "change of the active member of a union "
8827 : "from %qD to %qD during initialization",
8828 6 : CONSTRUCTOR_ELT (*valp, 0)->index,
8829 : index);
8830 18 : *non_constant_p = true;
8831 : }
8832 : no_zero_init = true;
8833 : }
8834 :
8835 : /* Ending the lifetime of the active union member means the union no
8836 : longer has an active member. */
8837 584445 : if (code == UNION_TYPE && refs->is_empty ()
8838 100660 : && TREE_CLOBBER_P (init)
8839 36004512 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8840 : {
8841 1798 : vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0);
8842 4512 : return void_node;
8843 : }
8844 :
8845 35994840 : ctors.safe_push (valp);
8846 35994840 : vec_safe_push (indexes, index);
8847 :
8848 : /* Avoid adding an _elt for a clobber when the whole CONSTRUCTOR is
8849 : uninitialized. */
8850 34086972 : int pos = (!seen_union && TREE_CLOBBER_P (init)
8851 1744269 : && CONSTRUCTOR_NO_CLEARING (*valp)
8852 37548565 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END) ? -2 : -1;
8853 35994840 : constructor_elt *cep
8854 35994840 : = get_or_insert_ctor_field (*valp, index, pos);
8855 35994840 : if (cep == nullptr)
8856 2714 : return void_node;
8857 35992126 : index_pos_hints.safe_push (cep - CONSTRUCTOR_ELTS (*valp)->begin());
8858 :
8859 35992126 : if (code == UNION_TYPE)
8860 : {
8861 582647 : activated_union_member_p = true;
8862 582647 : --seen_union;
8863 : }
8864 :
8865 35992126 : valp = &cep->value;
8866 35992126 : type = reftype;
8867 : }
8868 :
8869 : /* Change an "as-base" clobber to the real type;
8870 : we don't need to worry about padding in constexpr. */
8871 94643625 : tree itype = initialized_type (init);
8872 94643625 : if (IS_FAKE_BASE_TYPE (itype))
8873 4452 : itype = TYPE_CONTEXT (itype);
8874 :
8875 : /* For initialization of an empty base, the original target will be
8876 : *(base*)this, evaluation of which resolves to the object
8877 : argument, which has the derived type rather than the base type. */
8878 189000298 : if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p
8879 94356673 : (itype, type)))
8880 : {
8881 18800 : gcc_assert (is_empty_class (TREE_TYPE (target)));
8882 : empty_base = true;
8883 : }
8884 :
8885 : /* For __builtin_start_lifetime, if it is already within lifetime,
8886 : don't do anything. */
8887 94643625 : if (TREE_CODE (t) == MODOP_EXPR && *valp != NULL_TREE && *valp != void_node)
8888 : return void_node;
8889 :
8890 : /* Detect modifying a constant object in constexpr evaluation.
8891 : We have found a const object that is being modified. Figure out
8892 : if we need to issue an error. Consider
8893 :
8894 : struct A {
8895 : int n;
8896 : constexpr A() : n(1) { n = 2; } // #1
8897 : };
8898 : struct B {
8899 : const A a;
8900 : constexpr B() { a.n = 3; } // #2
8901 : };
8902 : constexpr B b{};
8903 :
8904 : #1 is OK, since we're modifying an object under construction, but
8905 : #2 is wrong, since "a" is const and has been fully constructed.
8906 : To track it, we use the TREE_READONLY bit in the object's CONSTRUCTOR
8907 : which means that the object is read-only. For the example above, the
8908 : *ctors stack at the point of #2 will look like:
8909 :
8910 : ctors[0] = {.a={.n=2}} TREE_READONLY = 0
8911 : ctors[1] = {.n=2} TREE_READONLY = 1
8912 :
8913 : and we're modifying "b.a", so we search the stack and see if the
8914 : constructor for "b.a" has already run. */
8915 94643587 : if (const_object_being_modified)
8916 : {
8917 87488 : bool fail = false;
8918 87488 : tree const_objtype
8919 87488 : = strip_array_types (TREE_TYPE (const_object_being_modified));
8920 87488 : if (!CLASS_TYPE_P (const_objtype))
8921 : fail = true;
8922 : else
8923 : {
8924 : /* [class.ctor]p5 "A constructor can be invoked for a const,
8925 : volatile, or const volatile object. const and volatile
8926 : semantics are not applied on an object under construction.
8927 : They come into effect when the constructor for the most
8928 : derived object ends." */
8929 262663 : for (tree *elt : ctors)
8930 87897 : if (same_type_ignoring_top_level_qualifiers_p
8931 87897 : (TREE_TYPE (const_object_being_modified), TREE_TYPE (*elt)))
8932 : {
8933 87383 : fail = TREE_READONLY (*elt);
8934 87383 : break;
8935 : }
8936 : }
8937 87383 : if (fail)
8938 : {
8939 200 : if (!ctx->quiet)
8940 65 : modifying_const_object_error (t, const_object_being_modified);
8941 200 : *non_constant_p = true;
8942 200 : return t;
8943 : }
8944 : }
8945 :
8946 94643387 : if (!preeval)
8947 : {
8948 : /* We're handling an INIT_EXPR of class type, so the value of the
8949 : initializer can depend on the object it's initializing. */
8950 :
8951 : /* Create a new CONSTRUCTOR in case evaluation of the initializer
8952 : wants to modify it. */
8953 31098309 : if (*valp == NULL_TREE)
8954 : {
8955 29999910 : *valp = build_constructor (type, NULL);
8956 29999910 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8957 29999910 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8958 : }
8959 31098309 : new_ctx.ctor = empty_base ? NULL_TREE : *valp;
8960 31098309 : new_ctx.object = target;
8961 : /* Avoid temporary materialization when initializing from a TARGET_EXPR.
8962 : We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because
8963 : expansion of those trees uses ctx instead. */
8964 31098309 : if (TREE_CODE (init) == TARGET_EXPR)
8965 3285322 : if (tree tinit = TARGET_EXPR_INITIAL (init))
8966 3285322 : init = tinit;
8967 31098309 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8968 : non_constant_p, overflow_p,
8969 : jump_target);
8970 31098309 : if (*jump_target)
8971 : return NULL_TREE;
8972 : /* The hash table might have moved since the get earlier, and the
8973 : initializer might have mutated the underlying CONSTRUCTORs, so we must
8974 : recompute VALP. */
8975 31098115 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8976 35575940 : for (unsigned i = 0; i < vec_safe_length (indexes); i++)
8977 : {
8978 4477825 : ctors[i] = valp;
8979 4477825 : constructor_elt *cep
8980 4477825 : = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]);
8981 4477825 : valp = &cep->value;
8982 : }
8983 : }
8984 :
8985 94643193 : if (*non_constant_p)
8986 : return t;
8987 :
8988 : /* Don't share a CONSTRUCTOR that might be changed later. */
8989 92780764 : init = unshare_constructor (init);
8990 :
8991 92780764 : gcc_checking_assert (!*valp
8992 : || *valp == void_node
8993 : || (same_type_ignoring_top_level_qualifiers_p
8994 : (TREE_TYPE (*valp), type)));
8995 92780764 : if (empty_base)
8996 : {
8997 : /* Just evaluate the initializer and return, since there's no actual data
8998 : to store, and we didn't build a CONSTRUCTOR. */
8999 294310 : if (!*valp)
9000 : {
9001 : /* But do make sure we have something in *valp. */
9002 0 : *valp = build_constructor (type, nullptr);
9003 0 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
9004 0 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
9005 : }
9006 : }
9007 92486454 : else if (TREE_CLOBBER_P (init))
9008 : {
9009 746228 : if (AGGREGATE_TYPE_P (type) && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
9010 : {
9011 11424 : if (*valp && TREE_CODE (*valp) == CONSTRUCTOR)
9012 6788 : CONSTRUCTOR_ELTS (*valp) = nullptr;
9013 : else
9014 4636 : *valp = build_constructor (type, nullptr);
9015 11424 : TREE_CONSTANT (*valp) = true;
9016 11424 : TREE_SIDE_EFFECTS (*valp) = false;
9017 11424 : CONSTRUCTOR_NO_CLEARING (*valp) = true;
9018 11424 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
9019 : }
9020 : else
9021 734804 : *valp = void_node;
9022 : }
9023 91740226 : else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
9024 29228743 : && TREE_CODE (init) == CONSTRUCTOR)
9025 : {
9026 : /* An outer ctx->ctor might be pointing to *valp, so replace
9027 : its contents. */
9028 4743684 : CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
9029 4743684 : TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
9030 4743684 : TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
9031 14231052 : CONSTRUCTOR_NO_CLEARING (*valp)
9032 4743684 : = CONSTRUCTOR_NO_CLEARING (init);
9033 14231052 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp)
9034 4743684 : = CONSTRUCTOR_ZERO_PADDING_BITS (init);
9035 : }
9036 : else
9037 86996542 : *valp = init;
9038 :
9039 : /* After initialization, 'const' semantics apply to the value of the
9040 : object. Make a note of this fact by marking the CONSTRUCTOR
9041 : TREE_READONLY. */
9042 92780764 : if (TREE_CODE (t) == INIT_EXPR
9043 70202758 : && !empty_base
9044 69908448 : && TREE_CODE (*valp) == CONSTRUCTOR
9045 97353428 : && TYPE_READONLY (type))
9046 : {
9047 35990 : tree target_type = TREE_TYPE (target);
9048 35990 : if (IS_FAKE_BASE_TYPE (target_type))
9049 0 : target_type = TYPE_CONTEXT (target_type);
9050 35990 : if (INDIRECT_REF_P (target)
9051 51144 : && (is_this_parameter
9052 15154 : (tree_strip_nop_conversions (TREE_OPERAND (target, 0)))))
9053 : /* We've just initialized '*this' (perhaps via the target
9054 : constructor of a delegating constructor). Leave it up to the
9055 : caller that set 'this' to set TREE_READONLY appropriately. */
9056 23 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
9057 : (target_type, type) || empty_base);
9058 : else
9059 35967 : TREE_READONLY (*valp) = true;
9060 : }
9061 :
9062 : /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing
9063 : CONSTRUCTORs, if any. */
9064 92780764 : bool c = TREE_CONSTANT (init);
9065 92780764 : bool s = TREE_SIDE_EFFECTS (init);
9066 92780764 : if (!indexes->is_empty ())
9067 : {
9068 20406162 : tree last = indexes->last ();
9069 20406162 : if (TREE_CODE (last) == REALPART_EXPR
9070 20406162 : || TREE_CODE (last) == IMAGPART_EXPR)
9071 : {
9072 : /* And canonicalize COMPLEX_EXPR into COMPLEX_CST if
9073 : possible. */
9074 61 : tree *cexpr = ctors.last ();
9075 61 : if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr),
9076 61 : TREE_OPERAND (*cexpr, 0),
9077 61 : TREE_OPERAND (*cexpr, 1)))
9078 53 : *cexpr = c;
9079 : else
9080 : {
9081 16 : TREE_CONSTANT (*cexpr)
9082 8 : = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0))
9083 8 : & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1)));
9084 16 : TREE_SIDE_EFFECTS (*cexpr)
9085 16 : = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0))
9086 8 : | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1)));
9087 : }
9088 61 : c = TREE_CONSTANT (*cexpr);
9089 61 : s = TREE_SIDE_EFFECTS (*cexpr);
9090 : }
9091 : }
9092 92780764 : if (!c || s || activated_union_member_p)
9093 63828603 : for (tree *elt : ctors)
9094 : {
9095 12518357 : if (TREE_CODE (*elt) != CONSTRUCTOR)
9096 0 : continue;
9097 12518357 : if (!c)
9098 10626248 : TREE_CONSTANT (*elt) = false;
9099 12518357 : if (s)
9100 0 : TREE_SIDE_EFFECTS (*elt) = true;
9101 : /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of
9102 : this union. */
9103 12518357 : if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE)
9104 465567 : CONSTRUCTOR_NO_CLEARING (*elt) = false;
9105 : }
9106 :
9107 92780764 : if (lval)
9108 : return target;
9109 : else
9110 587065 : return init;
9111 94971002 : }
9112 :
9113 : /* Evaluate a ++ or -- expression. */
9114 :
9115 : static tree
9116 8840345 : cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
9117 : value_cat lval,
9118 : bool *non_constant_p, bool *overflow_p,
9119 : tree *jump_target)
9120 : {
9121 8840345 : enum tree_code code = TREE_CODE (t);
9122 8840345 : tree type = TREE_TYPE (t);
9123 8840345 : tree op = TREE_OPERAND (t, 0);
9124 8840345 : tree offset = TREE_OPERAND (t, 1);
9125 8840345 : gcc_assert (TREE_CONSTANT (offset));
9126 :
9127 : /* OFFSET is constant, but perhaps not constant enough. We need to
9128 : e.g. bash FLOAT_EXPRs to REAL_CSTs. */
9129 8840345 : offset = fold_simple (offset);
9130 :
9131 : /* The operand as an lvalue. */
9132 8840345 : op = cxx_eval_constant_expression (ctx, op, vc_glvalue,
9133 : non_constant_p, overflow_p,
9134 : jump_target);
9135 8840345 : if (*jump_target)
9136 : return NULL_TREE;
9137 :
9138 : /* The operand as an rvalue. */
9139 8840345 : tree val
9140 8840345 : = cxx_eval_constant_expression (ctx, op, vc_prvalue,
9141 : non_constant_p, overflow_p,
9142 : jump_target);
9143 8840345 : if (*jump_target)
9144 : return NULL_TREE;
9145 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
9146 : a local array in a constexpr function. */
9147 8840345 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val));
9148 3526906 : if (!ptr)
9149 3526906 : VERIFY_CONSTANT (val);
9150 :
9151 : /* The modified value. */
9152 8780872 : bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
9153 8780872 : tree mod;
9154 8780872 : if (INDIRECT_TYPE_P (type))
9155 : {
9156 : /* The middle end requires pointers to use POINTER_PLUS_EXPR. */
9157 5313439 : offset = convert_to_ptrofftype (offset);
9158 5313439 : if (!inc)
9159 80918 : offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
9160 5313439 : mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
9161 : }
9162 3467433 : else if (c_promoting_integer_type_p (type)
9163 39611 : && !TYPE_UNSIGNED (type)
9164 3467643 : && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
9165 : {
9166 210 : offset = fold_convert (integer_type_node, offset);
9167 210 : mod = fold_convert (integer_type_node, val);
9168 241 : tree t = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, integer_type_node,
9169 : mod, offset);
9170 210 : mod = fold_convert (type, t);
9171 210 : if (TREE_OVERFLOW_P (mod) && !TREE_OVERFLOW_P (t))
9172 9 : TREE_OVERFLOW (mod) = false;
9173 : }
9174 : else
9175 3909470 : mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
9176 8780872 : if (!ptr)
9177 3467433 : VERIFY_CONSTANT (mod);
9178 :
9179 : /* Storing the modified value. */
9180 14744469 : tree store = build2_loc (cp_expr_loc_or_loc (t, input_location),
9181 : MODIFY_EXPR, type, op, mod);
9182 8780872 : mod = cxx_eval_constant_expression (ctx, store, lval,
9183 : non_constant_p, overflow_p,
9184 : jump_target);
9185 8780872 : ggc_free (store);
9186 8780872 : if (*jump_target)
9187 : return NULL_TREE;
9188 8780872 : if (*non_constant_p)
9189 : return t;
9190 :
9191 : /* And the value of the expression. */
9192 8706465 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
9193 : /* Prefix ops are lvalues, but the caller might want an rvalue;
9194 : lval has already been taken into account in the store above. */
9195 : return mod;
9196 : else
9197 : /* Postfix ops are rvalues. */
9198 421037 : return val;
9199 : }
9200 :
9201 : /* Subroutine of cxx_eval_statement_list. Determine whether the statement
9202 : STMT matches *jump_target. If we're looking for a case label and we see
9203 : the default label, note it in ctx->css_state. */
9204 :
9205 : static bool
9206 504244 : label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
9207 : {
9208 504244 : switch (TREE_CODE (*jump_target))
9209 : {
9210 145 : case LABEL_DECL:
9211 145 : if (TREE_CODE (stmt) == LABEL_EXPR
9212 145 : && LABEL_EXPR_LABEL (stmt) == *jump_target)
9213 52 : return true;
9214 : break;
9215 :
9216 502182 : case INTEGER_CST:
9217 502182 : if (TREE_CODE (stmt) == CASE_LABEL_EXPR)
9218 : {
9219 502155 : gcc_assert (ctx->css_state != NULL);
9220 502155 : if (!CASE_LOW (stmt))
9221 : {
9222 : /* default: should appear just once in a SWITCH_EXPR
9223 : body (excluding nested SWITCH_EXPR). */
9224 76286 : gcc_assert (*ctx->css_state != css_default_seen);
9225 : /* When evaluating SWITCH_EXPR body for the second time,
9226 : return true for the default: label. */
9227 76286 : if (*ctx->css_state == css_default_processing)
9228 : return true;
9229 39019 : *ctx->css_state = css_default_seen;
9230 : }
9231 425869 : else if (CASE_HIGH (stmt))
9232 : {
9233 20 : if (tree_int_cst_le (CASE_LOW (stmt), *jump_target)
9234 31 : && tree_int_cst_le (*jump_target, CASE_HIGH (stmt)))
9235 : return true;
9236 : }
9237 425849 : else if (tree_int_cst_equal (*jump_target, CASE_LOW (stmt)))
9238 : return true;
9239 : }
9240 : break;
9241 :
9242 : case BREAK_STMT:
9243 : case CONTINUE_STMT:
9244 : /* These two are handled directly in cxx_eval_loop_expr by testing
9245 : breaks (jump_target) or continues (jump_target). */
9246 : break;
9247 :
9248 : case VAR_DECL:
9249 : /* Uncaught exception. This is handled by TRY_BLOCK evaluation
9250 : and other places by testing throws (jump_target). */
9251 : break;
9252 :
9253 0 : default:
9254 0 : gcc_unreachable ();
9255 : }
9256 : return false;
9257 : }
9258 :
9259 : /* Evaluate a STATEMENT_LIST for side-effects. Handles various jump
9260 : semantics, for switch, break, continue, and return. */
9261 :
9262 : static tree
9263 48416820 : cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
9264 : bool *non_constant_p, bool *overflow_p,
9265 : tree *jump_target)
9266 : {
9267 : /* In a statement-expression we want to return the last value.
9268 : For empty statement expression return void_node. */
9269 48416820 : tree r = void_node;
9270 127197832 : for (tree_stmt_iterator i = tsi_start (t); !tsi_end_p (i); ++i)
9271 : {
9272 104594211 : tree stmt = *i;
9273 :
9274 : /* We've found a continue, so skip everything until we reach
9275 : the label its jumping to. */
9276 104594211 : if (continues (jump_target))
9277 : {
9278 2062 : if (label_matches (ctx, jump_target, stmt))
9279 : /* Found it. */
9280 52 : *jump_target = NULL_TREE;
9281 : else
9282 2010 : continue;
9283 : }
9284 104592201 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
9285 11313132 : continue;
9286 :
9287 93279069 : value_cat lval = vc_discard;
9288 : /* The result of a statement-expression is not wrapped in EXPR_STMT. */
9289 131277964 : if (tsi_one_before_end_p (i)
9290 38000157 : && !VOID_TYPE_P (TREE_TYPE (stmt)))
9291 : lval = vc_prvalue;
9292 :
9293 93279069 : r = cxx_eval_constant_expression (ctx, stmt, lval,
9294 : non_constant_p, overflow_p,
9295 : jump_target);
9296 93279065 : if (*non_constant_p)
9297 : break;
9298 83229417 : if (returns (jump_target)
9299 67555368 : || breaks (jump_target)
9300 78781012 : || throws (jump_target))
9301 : break;
9302 : }
9303 48416816 : return r;
9304 : }
9305 :
9306 : /* Evaluate a LOOP_EXPR for side-effects. Handles break and return
9307 : semantics; continue semantics are covered by cxx_eval_statement_list. */
9308 :
9309 : static tree
9310 6658406 : cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
9311 : bool *non_constant_p, bool *overflow_p,
9312 : tree *jump_target)
9313 : {
9314 6658406 : tree body, cond = NULL_TREE, expr = NULL_TREE;
9315 6658406 : tree cond_prep = NULL_TREE, cond_cleanup = NULL_TREE;
9316 6658406 : unsigned cond_cleanup_depth = 0;
9317 6658406 : int count = 0;
9318 6658406 : switch (TREE_CODE (t))
9319 : {
9320 3403 : case LOOP_EXPR:
9321 3403 : body = LOOP_EXPR_BODY (t);
9322 3403 : break;
9323 5361681 : case DO_STMT:
9324 5361681 : body = DO_BODY (t);
9325 5361681 : cond = DO_COND (t);
9326 5361681 : break;
9327 365577 : case WHILE_STMT:
9328 365577 : body = WHILE_BODY (t);
9329 365577 : cond = WHILE_COND (t);
9330 365577 : cond_prep = WHILE_COND_PREP (t);
9331 365577 : cond_cleanup = WHILE_COND_CLEANUP (t);
9332 365577 : count = -1;
9333 365577 : break;
9334 927745 : case FOR_STMT:
9335 927745 : if (FOR_INIT_STMT (t))
9336 0 : cxx_eval_constant_expression (ctx, FOR_INIT_STMT (t), vc_discard,
9337 : non_constant_p, overflow_p, jump_target);
9338 927745 : if (*non_constant_p)
9339 : return NULL_TREE;
9340 927745 : body = FOR_BODY (t);
9341 927745 : cond = FOR_COND (t);
9342 927745 : expr = FOR_EXPR (t);
9343 927745 : cond_prep = FOR_COND_PREP (t);
9344 927745 : cond_cleanup = FOR_COND_CLEANUP (t);
9345 927745 : count = -1;
9346 927745 : break;
9347 0 : default:
9348 0 : gcc_unreachable ();
9349 : }
9350 6658406 : if (cond_prep)
9351 12 : gcc_assert (TREE_CODE (cond_prep) == BIND_EXPR);
9352 31540769 : auto cleanup_cond = [&] {
9353 : /* Clean up the condition variable after each iteration. */
9354 24882363 : if (cond_cleanup_depth && !*non_constant_p)
9355 : {
9356 105 : auto_vec<tree, 4> cleanups (cond_cleanup_depth);
9357 105 : tree s = BIND_EXPR_BODY (cond_prep);
9358 105 : unsigned i;
9359 210 : for (i = cond_cleanup_depth; i; --i)
9360 : {
9361 105 : tree_stmt_iterator iter = tsi_last (s);
9362 105 : s = tsi_stmt (iter);
9363 105 : cleanups.quick_push (CLEANUP_EXPR (s));
9364 105 : s = CLEANUP_BODY (s);
9365 : }
9366 105 : tree c;
9367 420 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, c)
9368 105 : cxx_eval_constant_expression (ctx, c, vc_discard, non_constant_p,
9369 : overflow_p, jump_target);
9370 105 : }
9371 24882363 : if (cond_prep)
9372 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
9373 222 : decl; decl = DECL_CHAIN (decl))
9374 111 : destroy_value_checked (ctx, decl, non_constant_p);
9375 6658406 : };
9376 19552716 : do
9377 : {
9378 19552716 : if (count != -1)
9379 : {
9380 18259394 : if (body)
9381 18259394 : cxx_eval_constant_expression (ctx, body, vc_discard,
9382 : non_constant_p, overflow_p,
9383 : jump_target);
9384 18259394 : if (breaks (jump_target))
9385 : {
9386 35437 : *jump_target = NULL_TREE;
9387 35437 : break;
9388 : }
9389 :
9390 18223957 : if (TREE_CODE (t) != LOOP_EXPR && continues (jump_target))
9391 570 : *jump_target = NULL_TREE;
9392 :
9393 18223957 : if (expr)
9394 5433381 : cxx_eval_constant_expression (ctx, expr, vc_discard,
9395 : non_constant_p, overflow_p,
9396 : jump_target);
9397 18223957 : cleanup_cond ();
9398 : }
9399 :
9400 19517279 : if (cond_prep)
9401 : {
9402 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
9403 222 : decl; decl = DECL_CHAIN (decl))
9404 111 : ctx->global->clear_value (decl);
9405 111 : if (cond_cleanup)
9406 : {
9407 : /* If COND_CLEANUP is non-NULL, we need to evaluate DEPTH
9408 : nested STATEMENT_LISTs from inside of BIND_EXPR_BODY,
9409 : but defer the evaluation of CLEANUP_EXPRs of CLEANUP_STMT
9410 : at the end of those STATEMENT_LISTs. */
9411 111 : cond_cleanup_depth = 0;
9412 111 : tree s = BIND_EXPR_BODY (cond_prep);
9413 111 : for (unsigned depth = tree_to_uhwi (cond_cleanup);
9414 222 : depth; --depth)
9415 : {
9416 111 : for (tree_stmt_iterator i = tsi_start (s);
9417 321 : !tsi_end_p (i); ++i)
9418 : {
9419 321 : tree stmt = *i;
9420 321 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
9421 0 : continue;
9422 321 : if (tsi_one_before_end_p (i))
9423 : {
9424 : /* The last statement in the STATEMENT_LIST
9425 : has to be a CLEANUP_STMT (verified in
9426 : finish_loop_cond_prep). We want to
9427 : evaluate just its CLEANUP_BODY part but not
9428 : CLEANUP_EXPR part just yet. */
9429 105 : gcc_assert (TREE_CODE (stmt) == CLEANUP_STMT);
9430 : /* If the CLEANUP_STMT is not actually to be
9431 : evaluated, don't increment cond_cleanup_depth
9432 : so that we don't evaluate the CLEANUP_EXPR
9433 : for it later either. */
9434 105 : if (*jump_target)
9435 : {
9436 : depth = 1;
9437 : break;
9438 : }
9439 105 : ++cond_cleanup_depth;
9440 : /* If not in the innermost one, next iteration
9441 : will handle CLEANUP_BODY similarly. */
9442 105 : if (depth > 1)
9443 : {
9444 0 : s = CLEANUP_BODY (stmt);
9445 0 : break;
9446 : }
9447 : /* The innermost one can be evaluated normally. */
9448 105 : cxx_eval_constant_expression (ctx,
9449 105 : CLEANUP_BODY (stmt),
9450 : vc_discard,
9451 : non_constant_p,
9452 : overflow_p,
9453 : jump_target);
9454 105 : break;
9455 : }
9456 : /* And so should be evaluated statements which aren't
9457 : last in the STATEMENT_LIST. */
9458 216 : cxx_eval_constant_expression (ctx, stmt, vc_discard,
9459 : non_constant_p, overflow_p,
9460 : jump_target);
9461 216 : if (*non_constant_p
9462 210 : || returns (jump_target)
9463 210 : || breaks (jump_target)
9464 210 : || continues (jump_target)
9465 531 : || throws (jump_target))
9466 : {
9467 : depth = 1;
9468 : break;
9469 : }
9470 : }
9471 : }
9472 : }
9473 : else
9474 0 : cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (cond_prep),
9475 : vc_discard, non_constant_p,
9476 : overflow_p, jump_target);
9477 : }
9478 :
9479 19517279 : if (cond)
9480 : {
9481 19509761 : tree res
9482 19509761 : = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
9483 : non_constant_p, overflow_p,
9484 : jump_target);
9485 19509761 : if (res)
9486 : {
9487 19454273 : if (verify_constant (res, ctx->quiet, non_constant_p,
9488 : overflow_p))
9489 : break;
9490 19268285 : if (integer_zerop (res))
9491 : break;
9492 : }
9493 : else
9494 55488 : gcc_assert (*jump_target);
9495 : }
9496 :
9497 12951683 : if (++count >= constexpr_loop_limit)
9498 : {
9499 27 : if (!ctx->quiet)
9500 9 : error_at (cp_expr_loc_or_input_loc (t),
9501 : "%<constexpr%> loop iteration count exceeds limit of %d "
9502 : "(use %<-fconstexpr-loop-limit=%> to increase the limit)",
9503 : constexpr_loop_limit);
9504 27 : *non_constant_p = true;
9505 27 : break;
9506 : }
9507 : }
9508 38797861 : while (!returns (jump_target)
9509 12894549 : && !breaks (jump_target)
9510 12894549 : && !continues (jump_target)
9511 12894642 : && (!switches (jump_target) || count == 0)
9512 12894519 : && !throws (jump_target)
9513 25903467 : && !*non_constant_p);
9514 :
9515 6658406 : cleanup_cond ();
9516 :
9517 6658406 : return NULL_TREE;
9518 : }
9519 :
9520 : /* Evaluate a SWITCH_EXPR for side-effects. Handles switch and break jump
9521 : semantics. */
9522 :
9523 : static tree
9524 50125 : cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
9525 : bool *non_constant_p, bool *overflow_p,
9526 : tree *jump_target)
9527 : {
9528 50125 : tree cond
9529 50125 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
9530 50125 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
9531 : non_constant_p, overflow_p,
9532 : jump_target);
9533 50125 : if (*jump_target)
9534 : return NULL_TREE;
9535 50125 : VERIFY_CONSTANT (cond);
9536 49832 : if (TREE_CODE (cond) != INTEGER_CST)
9537 : {
9538 : /* If the condition doesn't reduce to an INTEGER_CST it isn't a usable
9539 : switch condition even if it's constant enough for other things
9540 : (c++/113545). */
9541 0 : gcc_checking_assert (ctx->quiet);
9542 0 : *non_constant_p = true;
9543 0 : return t;
9544 : }
9545 :
9546 49832 : *jump_target = cond;
9547 :
9548 49832 : tree body
9549 49832 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_BODY (t) : SWITCH_BODY (t);
9550 49832 : constexpr_ctx new_ctx = *ctx;
9551 49832 : constexpr_switch_state css = css_default_not_seen;
9552 49832 : new_ctx.css_state = &css;
9553 49832 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
9554 : non_constant_p, overflow_p, jump_target);
9555 87139 : if (switches (jump_target) && css == css_default_seen)
9556 : {
9557 : /* If the SWITCH_EXPR body has default: label, process it once again,
9558 : this time instructing label_matches to return true for default:
9559 : label on switches (jump_target). */
9560 37267 : css = css_default_processing;
9561 37267 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
9562 : non_constant_p, overflow_p, jump_target);
9563 : }
9564 49832 : if (breaks (jump_target) || switches (jump_target))
9565 21437 : *jump_target = NULL_TREE;
9566 : return NULL_TREE;
9567 : }
9568 :
9569 : /* Find the object of TYPE under initialization in CTX. */
9570 :
9571 : static tree
9572 16716 : lookup_placeholder (const constexpr_ctx *ctx, value_cat lval, tree type)
9573 : {
9574 16716 : if (!ctx)
9575 : return NULL_TREE;
9576 :
9577 : /* Prefer the outermost matching object, but don't cross
9578 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors. */
9579 16320 : if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
9580 574 : if (tree outer_ob = lookup_placeholder (ctx->parent, lval, type))
9581 : return outer_ob;
9582 :
9583 : /* We could use ctx->object unconditionally, but using ctx->ctor when we
9584 : can is a minor optimization. */
9585 16142 : if (!lval && ctx->ctor && same_type_p (TREE_TYPE (ctx->ctor), type))
9586 302 : return ctx->ctor;
9587 :
9588 15840 : if (!ctx->object)
9589 : return NULL_TREE;
9590 :
9591 : /* Since an object cannot have a field of its own type, we can search outward
9592 : from ctx->object to find the unique containing object of TYPE. */
9593 : tree ob = ctx->object;
9594 15816 : while (ob)
9595 : {
9596 15816 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type))
9597 : break;
9598 219 : if (handled_component_p (ob))
9599 217 : ob = TREE_OPERAND (ob, 0);
9600 : else
9601 : ob = NULL_TREE;
9602 : }
9603 :
9604 : /* Like in replace_placeholders_r. */
9605 15599 : return unshare_expr (ob);
9606 : }
9607 :
9608 : /* Complain about an attempt to evaluate inline assembly. If FUNDEF_P is
9609 : true, we're checking a constexpr function body. */
9610 :
9611 : static void
9612 35 : inline_asm_in_constexpr_error (location_t loc, bool fundef_p)
9613 : {
9614 35 : auto_diagnostic_group d;
9615 35 : if (constexpr_error (loc, fundef_p, "inline assembly is not a "
9616 : "constant expression"))
9617 35 : inform (loc, "only unevaluated inline assembly is allowed in a "
9618 : "%<constexpr%> function in C++20");
9619 35 : }
9620 :
9621 : /* We're getting the constant value of DECL in a manifestly constant-evaluated
9622 : context; maybe complain about that. */
9623 :
9624 : static void
9625 93522871 : maybe_warn_about_constant_value (location_t loc, tree decl)
9626 : {
9627 93522871 : static bool explained = false;
9628 93522871 : auto_diagnostic_group d;
9629 93522871 : if (cxx_dialect >= cxx17
9630 93353324 : && warn_interference_size
9631 93353324 : && !OPTION_SET_P (param_destruct_interfere_size)
9632 93353324 : && DECL_CONTEXT (decl) == std_node
9633 19106291 : && DECL_NAME (decl)
9634 19106285 : && id_equal (DECL_NAME (decl), "hardware_destructive_interference_size")
9635 16 : && (LOCATION_FILE (input_location) != main_input_filename
9636 10 : || module_exporting_p ())
9637 93522874 : && warning_at (loc, OPT_Winterference_size, "use of %qD", decl)
9638 93522880 : && !explained)
9639 : {
9640 6 : explained = true;
9641 6 : inform (loc, "its value can vary between compiler versions or "
9642 : "with different %<-mtune%> or %<-mcpu%> flags");
9643 6 : inform (loc, "if this use is part of a public ABI, change it to "
9644 : "instead use a constant variable you define");
9645 6 : inform (loc, "the default value for the current CPU tuning "
9646 : "is %d bytes", param_destruct_interfere_size);
9647 6 : inform (loc, "you can stabilize this value with %<--param "
9648 : "hardware_destructive_interference_size=%d%>, or disable "
9649 : "this warning with %<-Wno-interference-size%>",
9650 : param_destruct_interfere_size);
9651 : }
9652 93522871 : }
9653 :
9654 : /* For element type ELT_TYPE, return the appropriate type of the heap object
9655 : containing such element(s). COOKIE_SIZE is NULL or the size of cookie
9656 : in bytes. If COOKIE_SIZE is NULL, return array type
9657 : ELT_TYPE[FULL_SIZE / sizeof(ELT_TYPE)], otherwise return
9658 : struct { size_t[COOKIE_SIZE/sizeof(size_t)]; ELT_TYPE[N]; }
9659 : where N is computed such that the size of the struct fits into FULL_SIZE.
9660 : If ARG_SIZE is non-NULL, it is the first argument to the new operator.
9661 : It should be passed if ELT_TYPE is zero sized type in which case FULL_SIZE
9662 : will be also 0 and so it is not possible to determine the actual array
9663 : size. CTX, NON_CONSTANT_P and OVERFLOW_P are used during constant
9664 : expression evaluation of subexpressions of ARG_SIZE. */
9665 :
9666 : static tree
9667 118067 : build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type,
9668 : tree cookie_size, tree full_size, tree arg_size,
9669 : bool *non_constant_p, bool *overflow_p,
9670 : tree *jump_target)
9671 : {
9672 118067 : gcc_assert (cookie_size == NULL_TREE || tree_fits_uhwi_p (cookie_size));
9673 118067 : gcc_assert (tree_fits_uhwi_p (full_size));
9674 118067 : unsigned HOST_WIDE_INT csz = cookie_size ? tree_to_uhwi (cookie_size) : 0;
9675 118067 : if (arg_size)
9676 : {
9677 9 : STRIP_NOPS (arg_size);
9678 9 : if (cookie_size)
9679 : {
9680 0 : if (TREE_CODE (arg_size) != PLUS_EXPR)
9681 : arg_size = NULL_TREE;
9682 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 0)) == INTEGER_CST
9683 0 : && tree_int_cst_equal (cookie_size,
9684 0 : TREE_OPERAND (arg_size, 0)))
9685 : {
9686 0 : arg_size = TREE_OPERAND (arg_size, 1);
9687 0 : STRIP_NOPS (arg_size);
9688 : }
9689 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 1)) == INTEGER_CST
9690 0 : && tree_int_cst_equal (cookie_size,
9691 0 : TREE_OPERAND (arg_size, 1)))
9692 : {
9693 0 : arg_size = TREE_OPERAND (arg_size, 0);
9694 0 : STRIP_NOPS (arg_size);
9695 : }
9696 : else
9697 : arg_size = NULL_TREE;
9698 : }
9699 9 : if (arg_size && TREE_CODE (arg_size) == MULT_EXPR)
9700 : {
9701 9 : tree op0 = TREE_OPERAND (arg_size, 0);
9702 9 : tree op1 = TREE_OPERAND (arg_size, 1);
9703 9 : if (integer_zerop (op0))
9704 9 : arg_size
9705 9 : = cxx_eval_constant_expression (ctx, op1, vc_prvalue,
9706 : non_constant_p, overflow_p,
9707 : jump_target);
9708 0 : else if (integer_zerop (op1))
9709 0 : arg_size
9710 0 : = cxx_eval_constant_expression (ctx, op0, vc_prvalue,
9711 : non_constant_p, overflow_p,
9712 : jump_target);
9713 : else
9714 : arg_size = NULL_TREE;
9715 9 : if (*jump_target)
9716 : return NULL_TREE;
9717 : }
9718 : else
9719 : arg_size = NULL_TREE;
9720 : }
9721 :
9722 9 : unsigned HOST_WIDE_INT fsz = tree_to_uhwi (arg_size ? arg_size : full_size);
9723 118067 : if (!arg_size)
9724 : {
9725 118058 : unsigned HOST_WIDE_INT esz = int_size_in_bytes (elt_type);
9726 118058 : gcc_assert (fsz >= csz);
9727 118058 : fsz -= csz;
9728 118058 : if (esz)
9729 118058 : fsz /= esz;
9730 : }
9731 118067 : tree itype2 = build_index_type (size_int (fsz - 1));
9732 118067 : if (!cookie_size)
9733 118058 : return build_cplus_array_type (elt_type, itype2);
9734 9 : return build_new_constexpr_heap_type (elt_type, cookie_size, itype2);
9735 : }
9736 :
9737 : /* Handle the case when a cleanup of some expression throws. JMP_TARGET
9738 : indicates whether the cleanup threw or not, *JUMP_TARGET indicates whether
9739 : the expression which needed the cleanup threw. If both threw, diagnose
9740 : it and return NULL, otherwise return R. If only the cleanup threw, set
9741 : *JUMP_TARGET to the exception object from the cleanup. */
9742 :
9743 : static tree
9744 1743141 : merge_jump_target (location_t loc, const constexpr_ctx *ctx, tree r,
9745 : bool *non_constant_p, tree *jump_target, tree jmp_target)
9746 : {
9747 1743141 : if (!throws (&jmp_target))
9748 : return r;
9749 14 : if (throws (jump_target))
9750 : {
9751 : /* [except.throw]/9 - If the exception handling mechanism
9752 : handling an uncaught exception directly invokes a function
9753 : that exits via an exception, the function std::terminate is
9754 : invoked. */
9755 12 : if (!ctx->quiet)
9756 : {
9757 4 : auto_diagnostic_group d;
9758 4 : diagnose_std_terminate (loc, ctx, *jump_target);
9759 4 : inform (loc, "destructor exited with an exception");
9760 4 : }
9761 12 : *non_constant_p = true;
9762 12 : *jump_target = NULL_TREE;
9763 12 : return NULL_TREE;
9764 : }
9765 2 : *jump_target = jmp_target;
9766 2 : return r;
9767 : }
9768 :
9769 : /* Attempt to reduce the expression T to a constant value.
9770 : On failure, issue diagnostic and return error_mark_node. */
9771 : /* FIXME unify with c_fully_fold */
9772 : /* FIXME overflow_p is too global */
9773 :
9774 : tree
9775 3034099408 : cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
9776 : value_cat lval,
9777 : bool *non_constant_p, bool *overflow_p,
9778 : tree *jump_target)
9779 : {
9780 3034099408 : if (*jump_target)
9781 : {
9782 : /* If we are jumping, ignore all statements/expressions except those
9783 : that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies. */
9784 1623032 : switch (TREE_CODE (t))
9785 : {
9786 : case BIND_EXPR:
9787 : case STATEMENT_LIST:
9788 : case LOOP_EXPR:
9789 : case COND_EXPR:
9790 : case IF_STMT:
9791 : case DO_STMT:
9792 : case WHILE_STMT:
9793 : case FOR_STMT:
9794 : break;
9795 502182 : case LABEL_EXPR:
9796 502182 : case CASE_LABEL_EXPR:
9797 502182 : if (label_matches (ctx, jump_target, t))
9798 : /* Found it. */
9799 49792 : *jump_target = NULL_TREE;
9800 : return NULL_TREE;
9801 : default:
9802 : return NULL_TREE;
9803 : }
9804 : }
9805 3032722222 : if (error_operand_p (t))
9806 : {
9807 194 : *non_constant_p = true;
9808 194 : return t;
9809 : }
9810 :
9811 : /* Change the input location to the currently processed expression for
9812 : better error messages when a subexpression has no location. */
9813 3032722028 : location_t loc = cp_expr_loc_or_input_loc (t);
9814 6065438624 : iloc_sentinel sentinel (loc);
9815 :
9816 3032722028 : STRIP_ANY_LOCATION_WRAPPER (t);
9817 :
9818 3032722028 : if (CONSTANT_CLASS_P (t))
9819 : {
9820 462999556 : if (TREE_OVERFLOW (t))
9821 : {
9822 62 : if (!ctx->quiet)
9823 15 : permerror (input_location, "overflow in constant expression");
9824 62 : if (!flag_permissive || ctx->quiet)
9825 59 : *overflow_p = true;
9826 : }
9827 :
9828 462999556 : if (TREE_CODE (t) == INTEGER_CST
9829 440650653 : && TYPE_PTR_P (TREE_TYPE (t))
9830 : /* INTEGER_CST with pointer-to-method type is only used
9831 : for a virtual method in a pointer to member function.
9832 : Don't reject those. */
9833 2120012 : && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != METHOD_TYPE
9834 465119244 : && !integer_zerop (t))
9835 : {
9836 6 : if (!ctx->quiet)
9837 0 : error ("value %qE of type %qT is not a constant expression",
9838 0 : t, TREE_TYPE (t));
9839 6 : *non_constant_p = true;
9840 : }
9841 :
9842 : return t;
9843 : }
9844 :
9845 : /* Avoid excessively long constexpr evaluations. */
9846 2569722472 : if (++ctx->global->constexpr_ops_count >= constexpr_ops_limit)
9847 : {
9848 9 : if (!ctx->quiet)
9849 3 : error_at (loc,
9850 : "%<constexpr%> evaluation operation count exceeds limit of "
9851 : "%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
9852 : constexpr_ops_limit);
9853 9 : ctx->global->constexpr_ops_count = INTTYPE_MINIMUM (HOST_WIDE_INT);
9854 9 : *non_constant_p = true;
9855 9 : return t;
9856 : }
9857 :
9858 2569722463 : constexpr_ctx new_ctx;
9859 2569722463 : tree r = t;
9860 :
9861 2569722463 : tree_code tcode = TREE_CODE (t);
9862 2569722463 : switch (tcode)
9863 : {
9864 60011685 : case RESULT_DECL:
9865 60011685 : if (lval)
9866 : return t;
9867 : /* We ask for an rvalue for the RESULT_DECL when indirecting
9868 : through an invisible reference, or in named return value
9869 : optimization. */
9870 147328 : if (tree v = ctx->global->get_value (t))
9871 : return v;
9872 : else
9873 : {
9874 3 : if (!ctx->quiet)
9875 0 : error ("%qE is not a constant expression", t);
9876 3 : *non_constant_p = true;
9877 : }
9878 3 : break;
9879 :
9880 300272715 : case VAR_DECL:
9881 300272715 : if (DECL_HAS_VALUE_EXPR_P (t))
9882 : {
9883 9233643 : if (is_normal_capture_proxy (t)
9884 9233643 : && current_function_decl == DECL_CONTEXT (t))
9885 : {
9886 : /* Function parms aren't constexpr within the function
9887 : definition, so don't try to look at the closure. But if the
9888 : captured variable is constant, try to evaluate it directly. */
9889 629991 : r = DECL_CAPTURED_VARIABLE (t);
9890 : }
9891 : else
9892 8603652 : r = DECL_VALUE_EXPR (t);
9893 :
9894 9233643 : tree type = TREE_TYPE (t);
9895 9233643 : if (TYPE_REF_P (type) != TYPE_REF_P (TREE_TYPE (r)))
9896 : {
9897 : /* Adjust r to match the reference-ness of t. */
9898 258658 : if (TYPE_REF_P (type))
9899 254467 : r = build_address (r);
9900 : else
9901 4191 : r = convert_from_reference (r);
9902 : }
9903 9233643 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
9904 9233643 : overflow_p, jump_target);
9905 : }
9906 : /* fall through */
9907 301831324 : case CONST_DECL:
9908 : /* We used to not check lval for CONST_DECL, but darwin.cc uses
9909 : CONST_DECL for aggregate constants. */
9910 301831324 : if (lval)
9911 : return t;
9912 214738017 : else if (t == ctx->object)
9913 1027930 : return ctx->ctor;
9914 213710087 : if (VAR_P (t))
9915 : {
9916 202917841 : if (tree v = ctx->global->get_value (t))
9917 : {
9918 : r = v;
9919 : break;
9920 : }
9921 137757515 : if (ctx->global->is_outside_lifetime (t))
9922 : {
9923 137 : if (!ctx->quiet)
9924 39 : outside_lifetime_error (loc, t);
9925 137 : *non_constant_p = true;
9926 137 : break;
9927 : }
9928 : }
9929 148549624 : if (ctx->manifestly_const_eval == mce_true)
9930 93522871 : maybe_warn_about_constant_value (loc, t);
9931 148549624 : if (COMPLETE_TYPE_P (TREE_TYPE (t))
9932 148549624 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9933 : {
9934 : /* If the class is empty, we aren't actually loading anything. */
9935 252909 : r = build_constructor (TREE_TYPE (t), NULL);
9936 252909 : TREE_CONSTANT (r) = true;
9937 : }
9938 148296715 : else if (ctx->strict)
9939 147947331 : r = decl_really_constant_value (t, /*unshare_p=*/false);
9940 : else
9941 349384 : r = decl_constant_value (t, /*unshare_p=*/false);
9942 148546927 : if (TREE_CODE (r) == TARGET_EXPR
9943 148546927 : && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
9944 0 : r = TARGET_EXPR_INITIAL (r);
9945 148546927 : if (DECL_P (r)
9946 : /* P2280 allows references to unknown. */
9947 148835876 : && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
9948 : {
9949 34645199 : if (!ctx->quiet)
9950 179 : non_const_var_error (loc, r, /*fundef_p*/false);
9951 34645199 : *non_constant_p = true;
9952 : }
9953 : break;
9954 :
9955 : case DEBUG_BEGIN_STMT:
9956 : /* ??? It might be nice to retain this information somehow, so
9957 : as to be able to step into a constexpr function call. */
9958 : /* Fall through. */
9959 :
9960 : case FUNCTION_DECL:
9961 : case TEMPLATE_DECL:
9962 : case LABEL_DECL:
9963 : case LABEL_EXPR:
9964 : case CASE_LABEL_EXPR:
9965 : case PREDICT_EXPR:
9966 : case OMP_DECLARE_MAPPER:
9967 : case REFLECT_EXPR:
9968 : return t;
9969 :
9970 307504563 : case PARM_DECL:
9971 307504563 : if (lval && !TYPE_REF_P (TREE_TYPE (t)))
9972 : {
9973 : /* glvalue use. */
9974 21867217 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9975 220671 : if (tree v = ctx->global->get_value (t))
9976 2068887702 : r = v;
9977 : }
9978 285637346 : else if (tree v = ctx->global->get_value (t))
9979 : {
9980 166964231 : r = v;
9981 166964231 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9982 11305 : r = cxx_eval_constant_expression (ctx, r, vc_prvalue,
9983 : non_constant_p, overflow_p,
9984 : jump_target);
9985 166964231 : if (*jump_target)
9986 : return NULL_TREE;
9987 : }
9988 118673115 : else if (lval)
9989 : /* Defer in case this is only used for its type. */;
9990 118673115 : else if (ctx->global->is_outside_lifetime (t))
9991 : {
9992 18 : if (!ctx->quiet)
9993 6 : outside_lifetime_error (loc, t);
9994 18 : *non_constant_p = true;
9995 18 : break;
9996 : }
9997 118673097 : else if (COMPLETE_TYPE_P (TREE_TYPE (t))
9998 118673097 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9999 : {
10000 : /* If the class is empty, we aren't actually loading anything. */
10001 41524 : r = build_constructor (TREE_TYPE (t), NULL);
10002 41524 : TREE_CONSTANT (r) = true;
10003 : }
10004 118631573 : else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t)))
10005 : /* P2280 allows references to unknown... */;
10006 118354968 : else if (p2280_active_p (ctx) && is_this_parameter (t))
10007 : /* ...as well as the this pointer. */;
10008 : else
10009 : {
10010 117900652 : if (!ctx->quiet)
10011 199 : error ("%qE is not a constant expression", t);
10012 117900652 : *non_constant_p = true;
10013 : }
10014 : break;
10015 :
10016 207676478 : case CALL_EXPR:
10017 207676478 : case AGGR_INIT_EXPR:
10018 207676478 : r = cxx_eval_call_expression (ctx, t, lval,
10019 : non_constant_p, overflow_p, jump_target);
10020 207676478 : break;
10021 :
10022 21519559 : case DECL_EXPR:
10023 21519559 : {
10024 21519559 : r = DECL_EXPR_DECL (t);
10025 21519559 : if (TREE_CODE (r) == USING_DECL)
10026 : {
10027 9442 : r = void_node;
10028 9442 : break;
10029 : }
10030 :
10031 21510117 : if (VAR_P (r)
10032 21510117 : && (TREE_STATIC (r)
10033 21346602 : || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
10034 : /* Allow __FUNCTION__ etc. */
10035 163515 : && !DECL_ARTIFICIAL (r)
10036 21511014 : && !decl_constant_var_p (r))
10037 : {
10038 7 : if (!ctx->quiet)
10039 : {
10040 2 : if (CP_DECL_THREAD_LOCAL_P (r))
10041 1 : error_at (loc, "control passes through definition of %qD "
10042 : "with thread storage duration", r);
10043 : else
10044 1 : error_at (loc, "control passes through definition of %qD "
10045 : "with static storage duration", r);
10046 : }
10047 7 : *non_constant_p = true;
10048 7 : break;
10049 : }
10050 :
10051 : /* make_rtl_for_nonlocal_decl could have deferred emission of
10052 : a local static var, but if it appears in a statement expression
10053 : which is constant expression evaluated to e.g. just the address
10054 : of the variable, its DECL_EXPR will never be seen during
10055 : gimple lowering's record_vars_into as the statement expression
10056 : will not be in the IL at all. */
10057 21510110 : if (VAR_P (r)
10058 21510110 : && TREE_STATIC (r)
10059 163508 : && !DECL_REALLY_EXTERN (r)
10060 163486 : && DECL_FUNCTION_SCOPE_P (r)
10061 163486 : && !var_in_maybe_constexpr_fn (r)
10062 21510113 : && decl_constant_var_p (r))
10063 : {
10064 3 : varpool_node *node = varpool_node::get (r);
10065 3 : if (node == NULL || !node->definition)
10066 3 : rest_of_decl_compilation (r, 0, at_eof);
10067 : }
10068 :
10069 42777007 : if (AGGREGATE_TYPE_P (TREE_TYPE (r))
10070 40118650 : || VECTOR_TYPE_P (TREE_TYPE (r)))
10071 : {
10072 2904534 : new_ctx = *ctx;
10073 2904534 : new_ctx.object = r;
10074 2904534 : new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
10075 2904534 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
10076 2904534 : ctx->global->put_value (r, new_ctx.ctor);
10077 2904534 : ctx = &new_ctx;
10078 : }
10079 :
10080 21510110 : if (tree init = DECL_INITIAL (r))
10081 : {
10082 11225507 : init = cxx_eval_constant_expression (ctx, init, vc_prvalue,
10083 : non_constant_p, overflow_p,
10084 : jump_target);
10085 11225507 : if (*jump_target)
10086 : return NULL_TREE;
10087 : /* Don't share a CONSTRUCTOR that might be changed. */
10088 11225507 : init = unshare_constructor (init);
10089 : /* Remember that a constant object's constructor has already
10090 : run. */
10091 22451014 : if (CLASS_TYPE_P (TREE_TYPE (r))
10092 11775624 : && CP_TYPE_CONST_P (TREE_TYPE (r)))
10093 71517 : TREE_READONLY (init) = true;
10094 11225507 : ctx->global->put_value (r, init);
10095 : }
10096 10284603 : else if (ctx == &new_ctx)
10097 : /* We gave it a CONSTRUCTOR above. */;
10098 : else
10099 8007285 : ctx->global->put_value (r, NULL_TREE);
10100 : }
10101 : break;
10102 :
10103 27091191 : case TARGET_EXPR:
10104 27091191 : {
10105 27091191 : tree type = TREE_TYPE (t);
10106 :
10107 27091191 : if (!literal_type_p (type))
10108 : {
10109 7079 : if (!ctx->quiet)
10110 : {
10111 0 : auto_diagnostic_group d;
10112 0 : error ("temporary of non-literal type %qT in a "
10113 : "constant expression", type);
10114 0 : explain_non_literal_class (type);
10115 0 : }
10116 7079 : *non_constant_p = true;
10117 11842906 : break;
10118 : }
10119 27084112 : gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (t));
10120 : /* Avoid evaluating a TARGET_EXPR more than once. */
10121 27084112 : tree slot = TARGET_EXPR_SLOT (t);
10122 27084112 : if (tree v = ctx->global->get_value (slot))
10123 : {
10124 2136 : if (lval)
10125 10938441 : return slot;
10126 : r = v;
10127 : break;
10128 : }
10129 27081976 : if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
10130 : {
10131 : /* We're being expanded without an explicit target, so start
10132 : initializing a new object; expansion with an explicit target
10133 : strips the TARGET_EXPR before we get here. */
10134 20567134 : new_ctx = *ctx;
10135 : /* Link CTX to NEW_CTX so that lookup_placeholder can resolve
10136 : any PLACEHOLDER_EXPR within the initializer that refers to the
10137 : former object under construction. */
10138 20567134 : new_ctx.parent = ctx;
10139 20567134 : new_ctx.ctor = build_constructor (type, NULL);
10140 20567134 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
10141 20567134 : new_ctx.object = slot;
10142 20567134 : ctx->global->put_value (new_ctx.object, new_ctx.ctor);
10143 20567134 : ctx = &new_ctx;
10144 : }
10145 :
10146 : /* If the initializer is complex, evaluate it to initialize slot. */
10147 27081976 : bool is_complex = target_expr_needs_replace (t);
10148 27081976 : if (is_complex)
10149 : /* In case no initialization actually happens, clear out any
10150 : void_node from a previous evaluation. */
10151 493 : ctx->global->put_value (slot, NULL_TREE);
10152 :
10153 : /* Pass vc_prvalue because this indicates
10154 : initialization of a temporary. */
10155 27081976 : r = cxx_eval_constant_expression (ctx, TARGET_EXPR_INITIAL (t),
10156 : vc_prvalue, non_constant_p,
10157 : overflow_p, jump_target);
10158 27081976 : if (*non_constant_p)
10159 : break;
10160 15247235 : if (ctx->save_exprs)
10161 10083863 : ctx->save_exprs->safe_push (slot);
10162 15247235 : if (*jump_target)
10163 : {
10164 669 : if (!is_complex
10165 669 : && !(AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
10166 : /* If TARGET_EXPR_INITIAL throws exception and slot's value
10167 : has not been changed yet, CLEANUP_POINT_EXPR handling
10168 : could see there void_node from a previous evaluation
10169 : and complain. */
10170 6 : ctx->global->put_value (slot, NULL_TREE);
10171 : return NULL_TREE;
10172 : }
10173 15246566 : if (!is_complex)
10174 : {
10175 15246153 : r = unshare_constructor (r);
10176 : /* Adjust the type of the result to the type of the temporary. */
10177 15246153 : r = adjust_temp_type (type, r);
10178 15246153 : ctx->global->put_value (slot, r);
10179 : }
10180 15246566 : if (TARGET_EXPR_CLEANUP (t)
10181 15246566 : && (!CLEANUP_EH_ONLY (t) || cxx_dialect >= cxx26))
10182 : {
10183 1443095 : ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t));
10184 : /* Mark CLEANUP_EH_ONLY cleanups by pushing NULL_TREE after
10185 : them. */
10186 1443095 : if (CLEANUP_EH_ONLY (t))
10187 2164 : ctx->global->cleanups->safe_push (NULL_TREE);
10188 : }
10189 15246566 : if (lval)
10190 : return slot;
10191 4309844 : if (is_complex)
10192 0 : r = ctx->global->get_value (slot);
10193 : }
10194 4309844 : break;
10195 :
10196 104159316 : case INIT_EXPR:
10197 104159316 : case MODIFY_EXPR:
10198 104159316 : gcc_assert (jump_target == NULL || *jump_target == NULL_TREE);
10199 104159316 : r = cxx_eval_store_expression (ctx, t, lval,
10200 : non_constant_p, overflow_p, jump_target);
10201 104159316 : break;
10202 :
10203 0 : case SCOPE_REF:
10204 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
10205 : lval,
10206 : non_constant_p, overflow_p,
10207 : jump_target);
10208 0 : break;
10209 :
10210 64957569 : case RETURN_EXPR:
10211 64957569 : if (TREE_OPERAND (t, 0) != NULL_TREE)
10212 64631633 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10213 : lval,
10214 : non_constant_p, overflow_p,
10215 : jump_target);
10216 64957565 : if (!throws (jump_target))
10217 64957197 : *jump_target = t;
10218 : break;
10219 54031 : case BREAK_STMT:
10220 54031 : case CONTINUE_STMT:
10221 54031 : *jump_target = t;
10222 54031 : break;
10223 :
10224 968489 : case SAVE_EXPR:
10225 : /* Avoid evaluating a SAVE_EXPR more than once. */
10226 968489 : if (tree v = ctx->global->get_value (t))
10227 : r = v;
10228 : else
10229 : {
10230 946460 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10231 : vc_prvalue, non_constant_p,
10232 : overflow_p, jump_target);
10233 946460 : if (*non_constant_p || *jump_target)
10234 : break;
10235 12799 : ctx->global->put_value (t, r);
10236 12799 : if (ctx->save_exprs)
10237 9259 : ctx->save_exprs->safe_push (t);
10238 : }
10239 : break;
10240 :
10241 63127074 : case NON_LVALUE_EXPR:
10242 63127074 : case EXPR_STMT:
10243 63127074 : case EH_SPEC_BLOCK:
10244 63127074 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10245 : lval,
10246 : non_constant_p, overflow_p,
10247 : jump_target);
10248 63127074 : break;
10249 :
10250 9408 : case TRY_BLOCK:
10251 9408 : r = cxx_eval_constant_expression (ctx, TRY_STMTS (t), lval,
10252 : non_constant_p, overflow_p,
10253 : jump_target);
10254 9408 : if (!*non_constant_p && throws (jump_target))
10255 3787 : if (tree h = TRY_HANDLERS (t))
10256 : {
10257 3787 : tree type = strip_array_types (TREE_TYPE (*jump_target));
10258 3787 : if (TREE_CODE (h) == STATEMENT_LIST)
10259 : {
10260 938 : for (tree stmt : tsi_range (h))
10261 904 : if (TREE_CODE (stmt) == HANDLER
10262 904 : && handler_match_for_exception_type (stmt, type))
10263 : {
10264 : h = stmt;
10265 : break;
10266 : }
10267 462 : if (TREE_CODE (h) == STATEMENT_LIST)
10268 : h = NULL_TREE;
10269 : }
10270 3325 : else if (TREE_CODE (h) != HANDLER
10271 3325 : || !handler_match_for_exception_type (h, type))
10272 : h = NULL_TREE;
10273 : if (h)
10274 : {
10275 3753 : gcc_assert (VAR_P (*jump_target));
10276 3753 : ctx->global->caught_exceptions.safe_push (*jump_target);
10277 3753 : ctx->global->caught_exceptions.safe_push (HANDLER_TYPE (h));
10278 3753 : *jump_target = NULL_TREE;
10279 3753 : r = cxx_eval_constant_expression (ctx, HANDLER_BODY (h),
10280 : vc_discard, non_constant_p,
10281 : overflow_p, jump_target);
10282 : }
10283 : }
10284 : break;
10285 :
10286 92355289 : case CLEANUP_POINT_EXPR:
10287 92355289 : {
10288 92355289 : auto_vec<tree, 2> cleanups;
10289 92355289 : vec<tree> *prev_cleanups = ctx->global->cleanups;
10290 92355289 : ctx->global->cleanups = &cleanups;
10291 :
10292 92355289 : auto_vec<tree, 10> save_exprs;
10293 92355289 : constexpr_ctx new_ctx = *ctx;
10294 92355289 : new_ctx.save_exprs = &save_exprs;
10295 :
10296 92355289 : r = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 0),
10297 : lval,
10298 : non_constant_p, overflow_p,
10299 : jump_target);
10300 :
10301 92355287 : ctx->global->cleanups = prev_cleanups;
10302 92355287 : unsigned int i;
10303 92355287 : tree cleanup, jmp_target = NULL_TREE;
10304 92355287 : bool eh = throws (jump_target);
10305 : /* Evaluate the cleanups. */
10306 186051243 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
10307 1340669 : if (cleanup == NULL_TREE)
10308 : {
10309 : /* NULL_TREE cleanup is a marker that before it is
10310 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it
10311 : if the body didn't throw. */
10312 2141 : if (!eh)
10313 2139 : --i;
10314 : }
10315 : else
10316 1338528 : cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard,
10317 : non_constant_p, overflow_p,
10318 : &jmp_target);
10319 :
10320 : /* Forget SAVE_EXPRs and TARGET_EXPRs created by this
10321 : full-expression. */
10322 287158983 : for (tree save_expr : save_exprs)
10323 10093122 : destroy_value_checked (ctx, save_expr, non_constant_p);
10324 92355287 : if (throws (&jmp_target))
10325 0 : *jump_target = jmp_target;
10326 92355287 : }
10327 92355287 : break;
10328 :
10329 59300419 : case MUST_NOT_THROW_EXPR:
10330 59300419 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10331 : lval,
10332 : non_constant_p, overflow_p,
10333 : jump_target);
10334 59300417 : if (throws (jump_target))
10335 : {
10336 : /* [except.handle]/7 - If the search for a handler exits the
10337 : function body of a function with a non-throwing exception
10338 : specification, the function std::terminate is invoked. */
10339 54 : if (!ctx->quiet)
10340 : {
10341 18 : auto_diagnostic_group d;
10342 18 : diagnose_std_terminate (loc, ctx, *jump_target);
10343 18 : if (MUST_NOT_THROW_NOEXCEPT_P (t)
10344 14 : && ctx->call
10345 32 : && ctx->call->fundef)
10346 14 : inform (loc, "uncaught exception exited from %<noexcept%> "
10347 : "function %qD",
10348 : ctx->call->fundef->decl);
10349 4 : else if (MUST_NOT_THROW_THROW_P (t))
10350 2 : inform (loc, "destructor exited with an exception after "
10351 : "initializing the exception object");
10352 2 : else if (MUST_NOT_THROW_CATCH_P (t))
10353 2 : inform (loc, "constructor exited with another exception while "
10354 : "entering handler");
10355 18 : }
10356 54 : *non_constant_p = true;
10357 54 : *jump_target = NULL_TREE;
10358 54 : r = NULL_TREE;
10359 : }
10360 : break;
10361 :
10362 0 : case TRY_CATCH_EXPR:
10363 0 : if (TREE_OPERAND (t, 0) == NULL_TREE)
10364 : {
10365 0 : r = void_node;
10366 0 : break;
10367 : }
10368 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10369 : non_constant_p, overflow_p,
10370 : jump_target);
10371 0 : if (!*non_constant_p && throws (jump_target))
10372 : {
10373 0 : tree jmp_target = NULL_TREE;
10374 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
10375 : non_constant_p, overflow_p,
10376 : &jmp_target);
10377 0 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10378 : jmp_target);
10379 : }
10380 : break;
10381 :
10382 842 : case TRY_FINALLY_EXPR:
10383 842 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10384 : non_constant_p, overflow_p,
10385 : jump_target);
10386 842 : if (!*non_constant_p)
10387 : {
10388 827 : tree jmp_target = NULL_TREE;
10389 : /* Also evaluate the cleanup. */
10390 827 : if (TREE_CODE (TREE_OPERAND (t, 1)) == EH_ELSE_EXPR
10391 827 : && throws (jump_target))
10392 0 : cxx_eval_constant_expression (ctx,
10393 0 : TREE_OPERAND (TREE_OPERAND (t, 1),
10394 : 1), vc_discard,
10395 : non_constant_p, overflow_p,
10396 : &jmp_target);
10397 : else
10398 827 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
10399 : non_constant_p, overflow_p,
10400 : &jmp_target);
10401 827 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10402 : jmp_target);
10403 : }
10404 : break;
10405 :
10406 0 : case EH_ELSE_EXPR:
10407 : /* Evaluate any cleanup that applies to non-EH exits. */
10408 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_discard,
10409 : non_constant_p, overflow_p,
10410 : jump_target);
10411 :
10412 : /* The EH path is handled in TRY_FINALLY_EXPR handling above. */
10413 0 : break;
10414 :
10415 3928722 : case CLEANUP_STMT:
10416 3928722 : r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
10417 : non_constant_p, overflow_p,
10418 : jump_target);
10419 3928736 : if ((!CLEANUP_EH_ONLY (t) || throws (jump_target)) && !*non_constant_p)
10420 : {
10421 1742314 : iloc_sentinel ils (loc);
10422 1742314 : tree jmp_target = NULL_TREE;
10423 : /* Also evaluate the cleanup. */
10424 1742314 : cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), vc_discard,
10425 : non_constant_p, overflow_p,
10426 : &jmp_target);
10427 1742314 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10428 : jmp_target);
10429 1742314 : }
10430 : break;
10431 :
10432 : /* These differ from cxx_eval_unary_expression in that this doesn't
10433 : check for a constant operand or result; an address can be
10434 : constant without its operand being, and vice versa. */
10435 104458535 : case MEM_REF:
10436 104458535 : case INDIRECT_REF:
10437 104458535 : r = cxx_eval_indirect_ref (ctx, t, lval,
10438 : non_constant_p, overflow_p,
10439 : jump_target);
10440 104458535 : break;
10441 :
10442 101872205 : case ADDR_EXPR:
10443 101872205 : {
10444 101872205 : tree oldop = TREE_OPERAND (t, 0);
10445 101872205 : tree op = cxx_eval_constant_expression (ctx, oldop, vc_glvalue,
10446 : non_constant_p, overflow_p,
10447 : jump_target);
10448 101872205 : if (*jump_target)
10449 : return NULL_TREE;
10450 : /* Don't VERIFY_CONSTANT here. */
10451 101872200 : if (*non_constant_p)
10452 : return t;
10453 82193588 : gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
10454 : /* This function does more aggressive folding than fold itself. */
10455 82193588 : r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
10456 82193588 : if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
10457 : {
10458 56965417 : ggc_free (r);
10459 56965417 : return t;
10460 : }
10461 : break;
10462 : }
10463 :
10464 858342 : case REALPART_EXPR:
10465 858342 : case IMAGPART_EXPR:
10466 858342 : if (lval)
10467 : {
10468 1386 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10469 : non_constant_p, overflow_p,
10470 : jump_target);
10471 1386 : if (*jump_target)
10472 : return NULL_TREE;
10473 1386 : if (r == error_mark_node)
10474 : ;
10475 1386 : else if (r == TREE_OPERAND (t, 0) || lval == vc_discard)
10476 : r = t;
10477 : else
10478 1276 : r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
10479 : break;
10480 : }
10481 : /* FALLTHRU */
10482 26018126 : case CONJ_EXPR:
10483 26018126 : case FIX_TRUNC_EXPR:
10484 26018126 : case FLOAT_EXPR:
10485 26018126 : case NEGATE_EXPR:
10486 26018126 : case ABS_EXPR:
10487 26018126 : case ABSU_EXPR:
10488 26018126 : case BIT_NOT_EXPR:
10489 26018126 : case TRUTH_NOT_EXPR:
10490 26018126 : case FIXED_CONVERT_EXPR:
10491 26018126 : case VEC_DUPLICATE_EXPR:
10492 26018126 : r = cxx_eval_unary_expression (ctx, t, lval,
10493 : non_constant_p, overflow_p,
10494 : jump_target);
10495 26018126 : break;
10496 :
10497 9421938 : case SIZEOF_EXPR:
10498 9421938 : r = fold_sizeof_expr (t);
10499 : /* In a template, fold_sizeof_expr may merely create a new SIZEOF_EXPR,
10500 : which could lead to an infinite recursion. */
10501 9421938 : if (TREE_CODE (r) != SIZEOF_EXPR)
10502 9421938 : r = cxx_eval_constant_expression (ctx, r, lval,
10503 : non_constant_p, overflow_p,
10504 : jump_target);
10505 : else
10506 : {
10507 0 : *non_constant_p = true;
10508 0 : gcc_assert (ctx->quiet);
10509 : }
10510 :
10511 : break;
10512 :
10513 13695755 : case COMPOUND_EXPR:
10514 13695755 : {
10515 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
10516 : COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
10517 : introduced by build_call_a. */
10518 13695755 : tree op0 = TREE_OPERAND (t, 0);
10519 13695755 : tree op1 = TREE_OPERAND (t, 1);
10520 13695755 : STRIP_NOPS (op1);
10521 5567094 : if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
10522 16296238 : || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
10523 6858563 : r = cxx_eval_constant_expression (ctx, op0,
10524 : lval, non_constant_p, overflow_p,
10525 : jump_target);
10526 : else
10527 : {
10528 : /* Check that the LHS is constant and then discard it. */
10529 6837192 : cxx_eval_constant_expression (ctx, op0, vc_discard,
10530 : non_constant_p, overflow_p,
10531 : jump_target);
10532 6837192 : if (*jump_target)
10533 : return NULL_TREE;
10534 6829981 : if (*non_constant_p)
10535 : return t;
10536 6550517 : op1 = TREE_OPERAND (t, 1);
10537 6550517 : r = cxx_eval_constant_expression (ctx, op1,
10538 : lval, non_constant_p, overflow_p,
10539 : jump_target);
10540 : }
10541 : }
10542 : break;
10543 :
10544 112842931 : case POINTER_PLUS_EXPR:
10545 112842931 : case POINTER_DIFF_EXPR:
10546 112842931 : case PLUS_EXPR:
10547 112842931 : case MINUS_EXPR:
10548 112842931 : case MULT_EXPR:
10549 112842931 : case TRUNC_DIV_EXPR:
10550 112842931 : case CEIL_DIV_EXPR:
10551 112842931 : case FLOOR_DIV_EXPR:
10552 112842931 : case ROUND_DIV_EXPR:
10553 112842931 : case TRUNC_MOD_EXPR:
10554 112842931 : case CEIL_MOD_EXPR:
10555 112842931 : case ROUND_MOD_EXPR:
10556 112842931 : case RDIV_EXPR:
10557 112842931 : case EXACT_DIV_EXPR:
10558 112842931 : case MIN_EXPR:
10559 112842931 : case MAX_EXPR:
10560 112842931 : case LSHIFT_EXPR:
10561 112842931 : case RSHIFT_EXPR:
10562 112842931 : case LROTATE_EXPR:
10563 112842931 : case RROTATE_EXPR:
10564 112842931 : case BIT_IOR_EXPR:
10565 112842931 : case BIT_XOR_EXPR:
10566 112842931 : case BIT_AND_EXPR:
10567 112842931 : case TRUTH_XOR_EXPR:
10568 112842931 : case LT_EXPR:
10569 112842931 : case LE_EXPR:
10570 112842931 : case GT_EXPR:
10571 112842931 : case GE_EXPR:
10572 112842931 : case EQ_EXPR:
10573 112842931 : case NE_EXPR:
10574 112842931 : case SPACESHIP_EXPR:
10575 112842931 : case UNORDERED_EXPR:
10576 112842931 : case ORDERED_EXPR:
10577 112842931 : case UNLT_EXPR:
10578 112842931 : case UNLE_EXPR:
10579 112842931 : case UNGT_EXPR:
10580 112842931 : case UNGE_EXPR:
10581 112842931 : case UNEQ_EXPR:
10582 112842931 : case LTGT_EXPR:
10583 112842931 : case RANGE_EXPR:
10584 112842931 : case COMPLEX_EXPR:
10585 112842931 : r = cxx_eval_binary_expression (ctx, t, lval,
10586 : non_constant_p, overflow_p,
10587 : jump_target);
10588 112842931 : break;
10589 :
10590 : /* fold can introduce non-IF versions of these; still treat them as
10591 : short-circuiting. */
10592 15609291 : case TRUTH_AND_EXPR:
10593 15609291 : case TRUTH_ANDIF_EXPR:
10594 15609291 : r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
10595 : boolean_true_node,
10596 : non_constant_p, overflow_p,
10597 : jump_target);
10598 15609291 : break;
10599 :
10600 3060198 : case TRUTH_OR_EXPR:
10601 3060198 : case TRUTH_ORIF_EXPR:
10602 3060198 : r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
10603 : boolean_false_node,
10604 : non_constant_p, overflow_p,
10605 : jump_target);
10606 3060198 : break;
10607 :
10608 15683020 : case ARRAY_REF:
10609 15683020 : r = cxx_eval_array_reference (ctx, t, lval,
10610 : non_constant_p, overflow_p,
10611 : jump_target);
10612 15683020 : break;
10613 :
10614 116311114 : case COMPONENT_REF:
10615 116311114 : if (is_overloaded_fn (t))
10616 : {
10617 : /* We can only get here in checking mode via
10618 : build_non_dependent_expr, because any expression that
10619 : calls or takes the address of the function will have
10620 : pulled a FUNCTION_DECL out of the COMPONENT_REF. */
10621 6 : gcc_checking_assert (ctx->quiet || errorcount);
10622 6 : *non_constant_p = true;
10623 6 : return t;
10624 : }
10625 116311108 : r = cxx_eval_component_reference (ctx, t, lval,
10626 : non_constant_p, overflow_p,
10627 : jump_target);
10628 116311108 : break;
10629 :
10630 40745 : case BIT_FIELD_REF:
10631 40745 : r = cxx_eval_bit_field_ref (ctx, t, lval,
10632 : non_constant_p, overflow_p,
10633 : jump_target);
10634 40745 : break;
10635 :
10636 39660171 : case COND_EXPR:
10637 39660171 : case IF_STMT:
10638 39660171 : if (*jump_target)
10639 : {
10640 151552 : tree orig_jump = *jump_target;
10641 151552 : tree arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 1))
10642 303104 : ? TREE_OPERAND (t, 1) : void_node);
10643 : /* When jumping to a label, the label might be either in the
10644 : then or else blocks, so process then block first in skipping
10645 : mode first, and if we are still in the skipping mode at its end,
10646 : process the else block too. */
10647 151552 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
10648 : overflow_p, jump_target);
10649 : /* It's possible that we found the label in the then block. But
10650 : it could have been followed by another jumping statement, e.g.
10651 : say we're looking for case 1:
10652 : if (cond)
10653 : {
10654 : // skipped statements
10655 : case 1:; // clears up *jump_target
10656 : return 1; // and sets it to a RETURN_EXPR
10657 : }
10658 : else { ... }
10659 : in which case we need not go looking to the else block.
10660 : (goto is not allowed in a constexpr function.) */
10661 151552 : if (*jump_target == orig_jump)
10662 : {
10663 151609 : arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 2))
10664 151609 : ? TREE_OPERAND (t, 2) : void_node);
10665 151514 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
10666 : overflow_p, jump_target);
10667 : }
10668 : break;
10669 : }
10670 39508619 : r = cxx_eval_conditional_expression (ctx, t, lval,
10671 : non_constant_p, overflow_p,
10672 : jump_target);
10673 39508619 : break;
10674 11755 : case VEC_COND_EXPR:
10675 11755 : r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
10676 : overflow_p, jump_target);
10677 11755 : break;
10678 :
10679 23407267 : case CONSTRUCTOR:
10680 23407267 : if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
10681 : {
10682 : /* Don't re-process a constant CONSTRUCTOR. */
10683 20018508 : verify_constructor_flags (t);
10684 20018508 : if (TREE_CONSTANT (t))
10685 : return t;
10686 : }
10687 3388759 : if (TREE_CLOBBER_P (t))
10688 : {
10689 : /* Assignment from a clobber is handled in cxx_eval_store_expression;
10690 : a clobber by itself isn't a constant-expression. */
10691 242 : gcc_assert (ctx->quiet);
10692 242 : *non_constant_p = true;
10693 242 : break;
10694 : }
10695 3388517 : r = cxx_eval_bare_aggregate (ctx, t, lval,
10696 : non_constant_p, overflow_p, jump_target);
10697 3388517 : break;
10698 :
10699 792 : case VEC_INIT_EXPR:
10700 : /* We can get this in a defaulted constructor for a class with a
10701 : non-static data member of array type. Either the initializer will
10702 : be NULL, meaning default-initialization, or it will be an lvalue
10703 : or xvalue of the same type, meaning direct-initialization from the
10704 : corresponding member. */
10705 792 : r = cxx_eval_vec_init (ctx, t, lval,
10706 : non_constant_p, overflow_p, jump_target);
10707 792 : break;
10708 :
10709 43640 : case VEC_PERM_EXPR:
10710 43640 : r = cxx_eval_trinary_expression (ctx, t, lval,
10711 : non_constant_p, overflow_p,
10712 : jump_target);
10713 43640 : break;
10714 :
10715 7 : case PAREN_EXPR:
10716 7 : gcc_assert (!REF_PARENTHESIZED_P (t));
10717 : /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
10718 : constant expressions since it's unaffected by -fassociative-math. */
10719 7 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10720 : non_constant_p, overflow_p,
10721 : jump_target);
10722 7 : break;
10723 :
10724 444613709 : case NOP_EXPR:
10725 444613709 : if (REINTERPRET_CAST_P (t))
10726 : {
10727 145 : if (!ctx->quiet)
10728 6 : error_at (loc,
10729 : "%<reinterpret_cast%> is not a constant expression");
10730 145 : *non_constant_p = true;
10731 145 : return t;
10732 : }
10733 : /* FALLTHROUGH. */
10734 557142307 : case CONVERT_EXPR:
10735 557142307 : case VIEW_CONVERT_EXPR:
10736 557142307 : case UNARY_PLUS_EXPR:
10737 557142307 : {
10738 557142307 : tree oldop = TREE_OPERAND (t, 0);
10739 :
10740 557142307 : tree op = cxx_eval_constant_expression (ctx, oldop,
10741 557142307 : VOID_TYPE_P (TREE_TYPE (t))
10742 : ? vc_discard
10743 : : tcode == VIEW_CONVERT_EXPR
10744 523228605 : ? lval : vc_prvalue,
10745 : non_constant_p, overflow_p,
10746 : jump_target);
10747 557139608 : if (*jump_target)
10748 : return NULL_TREE;
10749 557135592 : if (*non_constant_p)
10750 : return t;
10751 449242114 : tree type = TREE_TYPE (t);
10752 :
10753 449242114 : if (VOID_TYPE_P (type))
10754 32705220 : return void_node;
10755 :
10756 416536894 : if (TREE_CODE (t) == CONVERT_EXPR
10757 61027642 : && ARITHMETIC_TYPE_P (type)
10758 5092860 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10759 416560645 : && ctx->strict)
10760 : {
10761 23656 : if (!ctx->quiet)
10762 54 : error_at (loc,
10763 : "conversion from pointer type %qT to arithmetic type "
10764 54 : "%qT in a constant expression", TREE_TYPE (op), type);
10765 23656 : *non_constant_p = true;
10766 23656 : return t;
10767 : }
10768 :
10769 : /* [expr.const]: a conversion from type cv void* to a pointer-to-object
10770 : type cannot be part of a core constant expression as a resolution to
10771 : DR 1312. */
10772 154407492 : if (TYPE_PTROB_P (type)
10773 151018768 : && TYPE_PTR_P (TREE_TYPE (op))
10774 94957189 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
10775 : /* Inside a call to std::construct_at,
10776 : std::allocator<T>::{,de}allocate, or
10777 : std::source_location::current, we permit casting from void*
10778 : because that is compiler-generated code. */
10779 1910177 : && !is_std_construct_at (ctx->call)
10780 166600 : && !is_std_allocator_allocate_deallocate (ctx->call)
10781 416599254 : && !is_std_source_location_current (ctx->call))
10782 : {
10783 : /* Likewise, don't error when casting from void* when OP is
10784 : &heap uninit and similar. */
10785 85857 : tree sop = tree_strip_nop_conversions (op);
10786 85857 : tree decl = NULL_TREE;
10787 85857 : if (TREE_CODE (sop) == ADDR_EXPR)
10788 63652 : decl = TREE_OPERAND (sop, 0);
10789 63652 : if (decl
10790 63652 : && VAR_P (decl)
10791 62224 : && DECL_ARTIFICIAL (decl)
10792 125442 : && (DECL_NAME (decl) == heap_identifier
10793 39827 : || DECL_NAME (decl) == heap_uninit_identifier
10794 4545 : || DECL_NAME (decl) == heap_vec_identifier
10795 2612 : || DECL_NAME (decl) == heap_vec_uninit_identifier))
10796 : /* OK */;
10797 : /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
10798 : cv void" to a pointer-to-object type T unless P is a null
10799 : pointer value or points to an object whose type is similar to
10800 : T. */
10801 24478 : else if (cxx_dialect > cxx23)
10802 : {
10803 24288 : if (integer_zerop (sop))
10804 30 : return build_int_cst (type, 0);
10805 24258 : r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10806 : NULL, jump_target);
10807 24258 : if (*jump_target)
10808 : return NULL_TREE;
10809 24258 : if (r)
10810 : {
10811 24211 : r = build1 (ADDR_EXPR, type, r);
10812 24211 : break;
10813 : }
10814 47 : if (!ctx->quiet)
10815 : {
10816 5 : gcc_assert (TREE_CODE (sop) == ADDR_EXPR);
10817 5 : auto_diagnostic_group d;
10818 5 : error_at (loc, "cast from %qT is not allowed in a "
10819 : "constant expression because "
10820 : "pointed-to type %qT is not similar to %qT",
10821 5 : TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)),
10822 5 : TREE_TYPE (type));
10823 5 : tree obj = build_fold_indirect_ref (sop);
10824 5 : if (TREE_CODE (obj) == COMPONENT_REF)
10825 4 : obj = TREE_OPERAND (obj, 1);
10826 5 : if (DECL_P (obj))
10827 5 : inform (DECL_SOURCE_LOCATION (obj),
10828 : "pointed-to object declared here");
10829 5 : }
10830 47 : *non_constant_p = true;
10831 47 : return t;
10832 : }
10833 : else
10834 : {
10835 190 : if (!ctx->quiet)
10836 26 : error_at (loc, "cast from %qT is not allowed in a "
10837 : "constant expression before C++26",
10838 26 : TREE_TYPE (op));
10839 190 : *non_constant_p = true;
10840 190 : return t;
10841 : }
10842 : }
10843 :
10844 : /* [expr.static.cast]/10: A prvalue of type "pointer to cv1 B", where
10845 : B is a class type, can be converted to a prvalue of type
10846 : "pointer to cv2 D", where D is a complete class derived from B, ...
10847 : If the prvalue of type "pointer to cv1 B" points to a B that is
10848 : actually a base class subobject of an object of type D, the
10849 : resulting pointer points to the enclosing object of type D.
10850 : Otherwise, the behavior is undefined.
10851 : Similarly [expr.static.cast]/2 for references. */
10852 416488760 : if (INDIRECT_TYPE_P (type)
10853 258623526 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10854 258488200 : && COMPLETE_TYPE_P (TREE_TYPE (type))
10855 255282791 : && !integer_zerop (op)
10856 671044634 : && is_properly_derived_from (TREE_TYPE (type),
10857 254555874 : TREE_TYPE (TREE_TYPE (op))))
10858 : {
10859 14503 : tree sop = tree_strip_nop_conversions (op);
10860 14503 : if (cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10861 : NULL, jump_target) == NULL_TREE)
10862 : {
10863 284 : tree dyntype = NULL_TREE;
10864 284 : if (!ctx->quiet && TREE_CODE (sop) == ADDR_EXPR)
10865 : {
10866 44 : sop = TREE_OPERAND (sop, 0);
10867 44 : while (TREE_CODE (sop) == COMPONENT_REF
10868 59 : && DECL_FIELD_IS_BASE (TREE_OPERAND (sop, 1)))
10869 15 : sop = TREE_OPERAND (sop, 0);
10870 44 : dyntype = strip_array_types (TREE_TYPE (sop));
10871 44 : if (same_type_p (dyntype, TREE_TYPE (TREE_TYPE (op))))
10872 261 : dyntype = NULL_TREE;
10873 : }
10874 284 : if (!ctx->quiet)
10875 : {
10876 53 : if (dyntype)
10877 23 : error_at (loc, "%qT operand (of dynamic type %qT) is "
10878 : "not a base class subobject of a %qT object",
10879 23 : TREE_TYPE (TREE_TYPE (op)), dyntype,
10880 23 : TREE_TYPE (type));
10881 : else
10882 30 : error_at (loc, "%qT operand is not a base class "
10883 : "subobject of a %qT object",
10884 30 : TREE_TYPE (TREE_TYPE (op)), TREE_TYPE (type));
10885 : }
10886 284 : *non_constant_p = true;
10887 284 : return t;
10888 : }
10889 : }
10890 :
10891 416488476 : if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
10892 : {
10893 1064 : op = cplus_expand_constant (op);
10894 1064 : if (TREE_CODE (op) == PTRMEM_CST)
10895 : {
10896 21 : if (!ctx->quiet)
10897 3 : error_at (loc, "%qE is not a constant expression when the "
10898 : "class %qT is still incomplete", op,
10899 3 : PTRMEM_CST_CLASS (op));
10900 21 : *non_constant_p = true;
10901 21 : return t;
10902 : }
10903 : }
10904 :
10905 416488455 : if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
10906 : {
10907 657 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
10908 657 : && !can_convert_qual (type, op))
10909 6 : op = cplus_expand_constant (op);
10910 657 : return cp_fold_convert (type, op);
10911 : }
10912 :
10913 416487798 : if (INDIRECT_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
10914 : {
10915 838542 : if (integer_zerop (op))
10916 : {
10917 781498 : if (TYPE_REF_P (type))
10918 : {
10919 36 : if (!ctx->quiet)
10920 4 : error_at (loc, "dereferencing a null pointer");
10921 36 : *non_constant_p = true;
10922 36 : return t;
10923 : }
10924 : }
10925 57044 : else if (TYPE_PTR_P (type)
10926 57044 : && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
10927 : /* INTEGER_CST with pointer-to-method type is only used
10928 : for a virtual method in a pointer to member function.
10929 : Don't reject those. */
10930 : ;
10931 : else
10932 : {
10933 : /* This detects for example:
10934 : reinterpret_cast<void*>(sizeof 0)
10935 : */
10936 57041 : if (!ctx->quiet)
10937 6 : error_at (loc, "%<reinterpret_cast<%T>(%E)%> is not "
10938 : "a constant expression",
10939 : type, op);
10940 57041 : *non_constant_p = true;
10941 57041 : return t;
10942 : }
10943 : }
10944 :
10945 416430721 : if (INDIRECT_TYPE_P (type)
10946 258566165 : && TREE_CODE (op) == NOP_EXPR
10947 124018992 : && TREE_TYPE (op) == ptr_type_node
10948 519056 : && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR
10949 515969 : && VAR_P (TREE_OPERAND (TREE_OPERAND (op, 0), 0))
10950 416833840 : && (DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10951 403119 : 0)) == heap_uninit_identifier
10952 287253 : || DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10953 287253 : 0)) == heap_vec_uninit_identifier))
10954 : {
10955 118067 : tree var = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10956 118067 : tree var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
10957 118067 : tree elt_type = TREE_TYPE (type);
10958 118067 : tree cookie_size = NULL_TREE;
10959 118067 : tree arg_size = NULL_TREE;
10960 118067 : if (TREE_CODE (elt_type) == RECORD_TYPE
10961 118067 : && TYPE_IDENTIFIER (elt_type) == heap_identifier)
10962 : {
10963 9 : tree fld1 = TYPE_FIELDS (elt_type);
10964 9 : tree fld2 = DECL_CHAIN (fld1);
10965 9 : elt_type = TREE_TYPE (TREE_TYPE (fld2));
10966 9 : cookie_size = TYPE_SIZE_UNIT (TREE_TYPE (fld1));
10967 : }
10968 118067 : DECL_NAME (var)
10969 118067 : = (DECL_NAME (var) == heap_uninit_identifier
10970 118067 : ? heap_identifier : heap_vec_identifier);
10971 : /* For zero sized elt_type, try to recover how many outer_nelts
10972 : it should have. */
10973 118067 : if ((cookie_size ? tree_int_cst_equal (var_size, cookie_size)
10974 118058 : : integer_zerop (var_size))
10975 105 : && !int_size_in_bytes (elt_type)
10976 9 : && TREE_CODE (oldop) == CALL_EXPR
10977 118085 : && call_expr_nargs (oldop) >= 1)
10978 9 : if (tree fun = get_function_named_in_call (oldop))
10979 9 : if (cxx_replaceable_global_alloc_fn (fun)
10980 9 : && IDENTIFIER_NEW_OP_P (DECL_NAME (fun)))
10981 9 : arg_size = CALL_EXPR_ARG (oldop, 0);
10982 118067 : tree new_type
10983 118067 : = build_new_constexpr_heap_type (ctx, elt_type, cookie_size,
10984 : var_size, arg_size,
10985 : non_constant_p, overflow_p,
10986 : jump_target);
10987 118067 : if (*jump_target)
10988 : return NULL_TREE;
10989 118067 : TREE_TYPE (var) = new_type;
10990 118067 : TREE_TYPE (TREE_OPERAND (op, 0))
10991 118067 : = build_pointer_type (TREE_TYPE (var));
10992 118067 : if (is_std_allocator_allocate (ctx->call))
10993 : {
10994 : /* [allocator.members]/5: This function starts the lifetime
10995 : of the array object, but not that of any of the array
10996 : elements. */
10997 80584 : tree ctor = build_constructor (new_type, NULL);
10998 80584 : CONSTRUCTOR_NO_CLEARING (ctor) = 1;
10999 80584 : CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
11000 80584 : ctx->global->put_value (var, ctor);
11001 : }
11002 : }
11003 :
11004 : /* This can happen for std::meta::info(^^int) where the cast has no
11005 : meaning. */
11006 416430721 : if (REFLECTION_TYPE_P (type) && REFLECT_EXPR_P (op))
11007 : {
11008 : r = op;
11009 : break;
11010 : }
11011 :
11012 416340315 : if (op == oldop && tcode != UNARY_PLUS_EXPR)
11013 : /* We didn't fold at the top so we could check for ptr-int
11014 : conversion. */
11015 32756205 : return fold (t);
11016 :
11017 383584110 : tree sop;
11018 :
11019 : /* Handle an array's bounds having been deduced after we built
11020 : the wrapping expression. */
11021 383584110 : if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
11022 : r = op;
11023 167898292 : else if (sop = tree_strip_nop_conversions (op),
11024 235465792 : sop != op && (same_type_ignoring_tlq_and_bounds_p
11025 67567500 : (type, TREE_TYPE (sop))))
11026 : r = sop;
11027 138759730 : else if (tcode == UNARY_PLUS_EXPR)
11028 0 : r = fold_convert (TREE_TYPE (t), op);
11029 : else
11030 138759730 : r = fold_build1 (tcode, type, op);
11031 :
11032 : /* Conversion of an out-of-range value has implementation-defined
11033 : behavior; the language considers it different from arithmetic
11034 : overflow, which is undefined. */
11035 383584110 : if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
11036 13279 : TREE_OVERFLOW (r) = false;
11037 : }
11038 : break;
11039 :
11040 9773 : case EXCESS_PRECISION_EXPR:
11041 9773 : {
11042 9773 : tree oldop = TREE_OPERAND (t, 0);
11043 :
11044 9773 : tree op = cxx_eval_constant_expression (ctx, oldop,
11045 : lval,
11046 : non_constant_p, overflow_p,
11047 : jump_target);
11048 9773 : if (*jump_target)
11049 : return NULL_TREE;
11050 9773 : if (*non_constant_p)
11051 : return t;
11052 9767 : r = fold_convert (TREE_TYPE (t), op);
11053 9767 : break;
11054 : }
11055 :
11056 66533 : case EMPTY_CLASS_EXPR:
11057 : /* Handle EMPTY_CLASS_EXPR produced by build_call_a by lowering
11058 : it to an appropriate CONSTRUCTOR. */
11059 66533 : return build_constructor (TREE_TYPE (t), NULL);
11060 :
11061 48416820 : case STATEMENT_LIST:
11062 48416820 : new_ctx = *ctx;
11063 48416820 : new_ctx.ctor = new_ctx.object = NULL_TREE;
11064 48416820 : return cxx_eval_statement_list (&new_ctx, t,
11065 48416816 : non_constant_p, overflow_p, jump_target);
11066 :
11067 33666670 : case BIND_EXPR:
11068 : /* Pre-emptively clear the vars declared by this BIND_EXPR from the value
11069 : map, so that when checking whether they're already destroyed later we
11070 : don't get confused by remnants of previous calls. */
11071 52946483 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
11072 19279813 : ctx->global->clear_value (decl);
11073 33666670 : r = cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
11074 : lval,
11075 : non_constant_p, overflow_p,
11076 : jump_target);
11077 52946479 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
11078 19279811 : destroy_value_checked (ctx, decl, non_constant_p);
11079 : break;
11080 :
11081 8840345 : case PREINCREMENT_EXPR:
11082 8840345 : case POSTINCREMENT_EXPR:
11083 8840345 : case PREDECREMENT_EXPR:
11084 8840345 : case POSTDECREMENT_EXPR:
11085 8840345 : return cxx_eval_increment_expression (ctx, t,
11086 : lval, non_constant_p, overflow_p,
11087 8840345 : jump_target);
11088 :
11089 2182 : case THROW_EXPR:
11090 2182 : if (cxx_dialect >= cxx26)
11091 1855 : return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
11092 : non_constant_p, overflow_p,
11093 1855 : jump_target);
11094 : /* FALLTHROUGH */
11095 335 : case LAMBDA_EXPR:
11096 335 : case NEW_EXPR:
11097 335 : case VEC_NEW_EXPR:
11098 335 : case DELETE_EXPR:
11099 335 : case VEC_DELETE_EXPR:
11100 335 : case MODOP_EXPR:
11101 : /* GCC internal stuff. */
11102 335 : case VA_ARG_EXPR:
11103 335 : case BASELINK:
11104 335 : case OFFSET_REF:
11105 335 : if (!ctx->quiet)
11106 86 : error_at (loc, "expression %qE is not a constant expression", t);
11107 335 : *non_constant_p = true;
11108 335 : break;
11109 :
11110 407213 : case OBJ_TYPE_REF:
11111 : /* Virtual function lookup. We don't need to do anything fancy. */
11112 407213 : return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t),
11113 : lval, non_constant_p, overflow_p,
11114 407213 : jump_target);
11115 :
11116 16142 : case PLACEHOLDER_EXPR:
11117 : /* Use of the value or address of the current object. */
11118 16142 : if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
11119 : {
11120 15899 : if (TREE_CODE (ctor) == CONSTRUCTOR)
11121 : return ctor;
11122 : else
11123 15597 : return cxx_eval_constant_expression (ctx, ctor, lval,
11124 : non_constant_p, overflow_p,
11125 15597 : jump_target);
11126 : }
11127 : /* A placeholder without a referent. We can get here when
11128 : checking whether NSDMIs are noexcept, or in massage_init_elt;
11129 : just say it's non-constant for now. */
11130 243 : gcc_assert (ctx->quiet);
11131 243 : *non_constant_p = true;
11132 243 : break;
11133 :
11134 6921 : case EXIT_EXPR:
11135 6921 : {
11136 6921 : tree cond = TREE_OPERAND (t, 0);
11137 6921 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
11138 : non_constant_p, overflow_p,
11139 : jump_target);
11140 6921 : if (*jump_target)
11141 : return NULL_TREE;
11142 6921 : VERIFY_CONSTANT (cond);
11143 6921 : if (integer_nonzerop (cond))
11144 3385 : *jump_target = t;
11145 : }
11146 : break;
11147 :
11148 83 : case GOTO_EXPR:
11149 83 : if (breaks (&TREE_OPERAND (t, 0))
11150 83 : || continues (&TREE_OPERAND (t, 0)))
11151 64 : *jump_target = TREE_OPERAND (t, 0);
11152 : else
11153 : {
11154 19 : if (!ctx->quiet)
11155 1 : error_at (loc, "%<goto%> is not a constant expression");
11156 19 : *non_constant_p = true;
11157 : }
11158 : break;
11159 :
11160 6658406 : case LOOP_EXPR:
11161 6658406 : case DO_STMT:
11162 6658406 : case WHILE_STMT:
11163 6658406 : case FOR_STMT:
11164 6658406 : cxx_eval_loop_expr (ctx, t,
11165 : non_constant_p, overflow_p, jump_target);
11166 6658406 : break;
11167 :
11168 50125 : case SWITCH_EXPR:
11169 50125 : case SWITCH_STMT:
11170 50125 : cxx_eval_switch_expr (ctx, t,
11171 : non_constant_p, overflow_p, jump_target);
11172 50125 : break;
11173 :
11174 215 : case REQUIRES_EXPR:
11175 : /* It's possible to get a requires-expression in a constant
11176 : expression. For example:
11177 :
11178 : template<typename T> concept bool C() {
11179 : return requires (T t) { t; };
11180 : }
11181 :
11182 : template<typename T> requires !C<T>() void f(T);
11183 :
11184 : Normalization leaves f with the associated constraint
11185 : '!requires (T t) { ... }' which is not transformed into
11186 : a constraint. */
11187 215 : if (!processing_template_decl)
11188 215 : return evaluate_requires_expr (t);
11189 : else
11190 0 : *non_constant_p = true;
11191 0 : return t;
11192 :
11193 1395375 : case ANNOTATE_EXPR:
11194 1395375 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
11195 : lval,
11196 : non_constant_p, overflow_p,
11197 : jump_target);
11198 1395375 : break;
11199 :
11200 9366 : case USING_STMT:
11201 9366 : r = void_node;
11202 9366 : break;
11203 :
11204 32 : case ASSERTION_STMT:
11205 32 : case PRECONDITION_STMT:
11206 32 : case POSTCONDITION_STMT:
11207 32 : {
11208 32 : r = void_node;
11209 : /* Only record the first fail, and do not go further is the semantic
11210 : is 'ignore'. */
11211 32 : if (*non_constant_p || ctx->global->contract_statement
11212 64 : || contract_ignored_p (t))
11213 : break;
11214 :
11215 32 : tree cond = CONTRACT_CONDITION (t);
11216 32 : if (!potential_rvalue_constant_expression (cond))
11217 : {
11218 6 : ctx->global->contract_statement = t;
11219 6 : ctx->global->contract_condition_non_const = true;
11220 6 : break;
11221 : }
11222 :
11223 : /* We need to evaluate and stash the result of this here, since whether
11224 : it needs to be reported (and how) depends on whether the containing
11225 : expression is otherwise const. */
11226 26 : bool ctrct_non_const_p = false;
11227 26 : bool ctrct_overflow_p = false;
11228 26 : tree jmp_target = NULL_TREE;
11229 26 : constexpr_ctx new_ctx = *ctx;
11230 26 : new_ctx.quiet = true;
11231 : /* Avoid modification of existing values. */
11232 26 : modifiable_tracker ms (new_ctx.global);
11233 26 : tree eval =
11234 26 : cxx_eval_constant_expression (&new_ctx, cond, vc_prvalue,
11235 : &ctrct_non_const_p,
11236 : &ctrct_overflow_p, &jmp_target);
11237 : /* Not a constant. */
11238 26 : if (ctrct_non_const_p)
11239 : {
11240 0 : ctx->global->contract_statement = t;
11241 0 : ctx->global->contract_condition_non_const = true;
11242 0 : break;
11243 : }
11244 : /* Constant, but check failed. */
11245 26 : if (integer_zerop (eval))
11246 24 : ctx->global->contract_statement = t;
11247 26 : }
11248 26 : break;
11249 :
11250 2776080 : case TEMPLATE_ID_EXPR:
11251 2776080 : {
11252 : /* We can evaluate template-id that refers to a concept only if
11253 : the template arguments are non-dependent. */
11254 2776080 : gcc_assert (concept_check_p (t));
11255 :
11256 2776080 : if (!value_dependent_expression_p (t)
11257 2776080 : && !uid_sensitive_constexpr_evaluation_p ())
11258 2775157 : r = evaluate_concept_check (t);
11259 : else
11260 923 : *non_constant_p = true;
11261 :
11262 : break;
11263 : }
11264 :
11265 51 : case ASM_EXPR:
11266 51 : if (!ctx->quiet)
11267 29 : inline_asm_in_constexpr_error (loc, /*constexpr_fundef_p*/false);
11268 51 : *non_constant_p = true;
11269 51 : return t;
11270 :
11271 4047 : case BIT_CAST_EXPR:
11272 4047 : if (lval)
11273 : {
11274 0 : if (!ctx->quiet)
11275 0 : error_at (EXPR_LOCATION (t),
11276 : "address of a call to %qs is not a constant expression",
11277 : "__builtin_bit_cast");
11278 0 : *non_constant_p = true;
11279 0 : return t;
11280 : }
11281 4047 : r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p, jump_target);
11282 4047 : break;
11283 :
11284 0 : case OMP_PARALLEL:
11285 0 : case OMP_TASK:
11286 0 : case OMP_FOR:
11287 0 : case OMP_SIMD:
11288 0 : case OMP_DISTRIBUTE:
11289 0 : case OMP_TASKLOOP:
11290 0 : case OMP_LOOP:
11291 0 : case OMP_TEAMS:
11292 0 : case OMP_TARGET_DATA:
11293 0 : case OMP_TARGET:
11294 0 : case OMP_SECTIONS:
11295 0 : case OMP_ORDERED:
11296 0 : case OMP_CRITICAL:
11297 0 : case OMP_SINGLE:
11298 0 : case OMP_SCAN:
11299 0 : case OMP_SCOPE:
11300 0 : case OMP_SECTION:
11301 0 : case OMP_STRUCTURED_BLOCK:
11302 0 : case OMP_MASTER:
11303 0 : case OMP_MASKED:
11304 0 : case OMP_TASKGROUP:
11305 0 : case OMP_TARGET_UPDATE:
11306 0 : case OMP_TARGET_ENTER_DATA:
11307 0 : case OMP_TARGET_EXIT_DATA:
11308 0 : case OMP_ATOMIC:
11309 0 : case OMP_ATOMIC_READ:
11310 0 : case OMP_ATOMIC_CAPTURE_OLD:
11311 0 : case OMP_ATOMIC_CAPTURE_NEW:
11312 0 : case OMP_DEPOBJ:
11313 0 : case OACC_PARALLEL:
11314 0 : case OACC_KERNELS:
11315 0 : case OACC_SERIAL:
11316 0 : case OACC_DATA:
11317 0 : case OACC_HOST_DATA:
11318 0 : case OACC_LOOP:
11319 0 : case OACC_CACHE:
11320 0 : case OACC_DECLARE:
11321 0 : case OACC_ENTER_DATA:
11322 0 : case OACC_EXIT_DATA:
11323 0 : case OACC_UPDATE:
11324 0 : if (!ctx->quiet)
11325 0 : error_at (EXPR_LOCATION (t),
11326 : "statement is not a constant expression");
11327 0 : *non_constant_p = true;
11328 0 : break;
11329 :
11330 0 : default:
11331 0 : if (STATEMENT_CODE_P (TREE_CODE (t)))
11332 : {
11333 : /* This function doesn't know how to deal with pre-genericize
11334 : statements; this can only happen with statement-expressions,
11335 : so for now just fail. */
11336 0 : if (!ctx->quiet)
11337 0 : error_at (EXPR_LOCATION (t),
11338 : "statement is not a constant expression");
11339 : }
11340 0 : else if (flag_checking)
11341 0 : internal_error ("unexpected expression %qE of kind %s", t,
11342 : get_tree_code_name (TREE_CODE (t)));
11343 0 : *non_constant_p = true;
11344 0 : break;
11345 : }
11346 :
11347 2068887702 : if (r == error_mark_node)
11348 14700416 : *non_constant_p = true;
11349 :
11350 135851663 : if (r == void_node && lval != vc_discard && !*jump_target
11351 2068905937 : && !VOID_TYPE_P (TREE_TYPE (t)))
11352 : {
11353 : /* For diagnostic quality we should have handled this sooner, where we
11354 : can be more specific about the out-of-lifetime object. But here we
11355 : can still be correct. */
11356 2 : gcc_checking_assert (false);
11357 : if (!ctx->quiet)
11358 : error_at (EXPR_LOCATION (t),
11359 : "%qE accesses an object outside its lifetime", t);
11360 : *non_constant_p = true;
11361 : }
11362 :
11363 2068887700 : if (*non_constant_p)
11364 : return t;
11365 : else
11366 1644537380 : return r;
11367 : }
11368 :
11369 : /* P0859: A function is needed for constant evaluation if it is a constexpr
11370 : function that is named by an expression ([basic.def.odr]) that is
11371 : potentially constant evaluated.
11372 :
11373 : So we need to instantiate any constexpr functions mentioned by the
11374 : expression even if the definition isn't needed for evaluating the
11375 : expression. */
11376 :
11377 : static tree
11378 597589125 : instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
11379 : {
11380 597589125 : if (TREE_CODE (*tp) == FUNCTION_DECL
11381 12274349 : && DECL_DECLARED_CONSTEXPR_P (*tp)
11382 12136514 : && !DECL_INITIAL (*tp)
11383 3129246 : && !trivial_fn_p (*tp)
11384 3129097 : && (DECL_TEMPLOID_INSTANTIATION (*tp) || DECL_DEFAULTED_FN (*tp))
11385 597589125 : && !uid_sensitive_constexpr_evaluation_p ())
11386 : {
11387 3099653 : ++function_depth;
11388 3099653 : if (DECL_TEMPLOID_INSTANTIATION (*tp))
11389 3099621 : instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
11390 : else
11391 32 : synthesize_method (*tp);
11392 3099653 : --function_depth;
11393 : }
11394 594489472 : else if (TREE_CODE (*tp) == CALL_EXPR
11395 582710928 : || TREE_CODE (*tp) == AGGR_INIT_EXPR)
11396 : {
11397 12339434 : if (EXPR_HAS_LOCATION (*tp))
11398 12332501 : input_location = EXPR_LOCATION (*tp);
11399 : }
11400 :
11401 597589125 : if (!EXPR_P (*tp))
11402 341792546 : *walk_subtrees = 0;
11403 :
11404 597589125 : return NULL_TREE;
11405 : }
11406 :
11407 : static void
11408 291651064 : instantiate_constexpr_fns (tree t)
11409 : {
11410 291651064 : location_t loc = input_location;
11411 291651064 : cp_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
11412 291651064 : input_location = loc;
11413 291651064 : }
11414 :
11415 : /* Look for heap variables in the expression *TP. */
11416 :
11417 : static tree
11418 379000 : find_heap_var_refs (tree *tp, int *walk_subtrees, void */*data*/)
11419 : {
11420 379000 : if (VAR_P (*tp)
11421 379000 : && (DECL_NAME (*tp) == heap_uninit_identifier
11422 9988 : || DECL_NAME (*tp) == heap_identifier
11423 3100 : || DECL_NAME (*tp) == heap_vec_uninit_identifier
11424 2343 : || DECL_NAME (*tp) == heap_vec_identifier
11425 583 : || DECL_NAME (*tp) == heap_deleted_identifier))
11426 : return *tp;
11427 :
11428 264757 : if (TYPE_P (*tp))
11429 68 : *walk_subtrees = 0;
11430 : return NULL_TREE;
11431 : }
11432 :
11433 : /* Find immediate function decls in *TP if any. */
11434 :
11435 : static tree
11436 626800672 : find_immediate_fndecl (tree *tp, int *walk_subtrees, void */*data*/)
11437 : {
11438 630895347 : if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (*tp))
11439 : return *tp;
11440 626794084 : if (TREE_CODE (*tp) == PTRMEM_CST
11441 29868 : && TREE_CODE (PTRMEM_CST_MEMBER (*tp)) == FUNCTION_DECL
11442 626823141 : && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (*tp)))
11443 : return PTRMEM_CST_MEMBER (*tp);
11444 626793971 : if (REFLECT_EXPR_P (*tp))
11445 86348 : *walk_subtrees = 0;
11446 : return NULL_TREE;
11447 : }
11448 :
11449 : /* T has TREE_CONSTANT set but has been deemed not a valid C++ constant
11450 : expression. Return a version of T that has TREE_CONSTANT cleared. */
11451 :
11452 : static tree
11453 147654 : mark_non_constant (tree t)
11454 : {
11455 147654 : gcc_checking_assert (TREE_CONSTANT (t));
11456 :
11457 : /* This isn't actually constant, so unset TREE_CONSTANT.
11458 : Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
11459 : it to be set if it is invariant address, even when it is not
11460 : a valid C++ constant expression. Wrap it with a NOP_EXPR
11461 : instead. */
11462 147654 : if (EXPR_P (t) && TREE_CODE (t) != ADDR_EXPR)
11463 145698 : t = copy_node (t);
11464 1956 : else if (TREE_CODE (t) == CONSTRUCTOR)
11465 480 : t = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (t), t);
11466 : else
11467 1476 : t = build_nop (TREE_TYPE (t), t);
11468 147654 : TREE_CONSTANT (t) = false;
11469 147654 : return t;
11470 : }
11471 :
11472 : /* If we have a successful constant evaluation, now check whether there is
11473 : a failed or non-constant contract that would invalidate this. */
11474 :
11475 : static bool
11476 570712333 : check_for_failed_contracts (constexpr_ctx *ctx)
11477 : {
11478 570712333 : constexpr_global_ctx *const global_ctx = ctx->global;
11479 570712333 : if (!flag_contracts || !global_ctx->contract_statement)
11480 : return false;
11481 :
11482 30 : location_t loc = EXPR_LOCATION (global_ctx->contract_statement);
11483 30 : enum diagnostics::kind kind;
11484 30 : bool error = false;
11485 : /* [intro.compliance.general]/2.3.4. */
11486 : /* [basic.contract.eval]/8. */
11487 30 : if (ctx->manifestly_const_eval != mce_true)
11488 : {
11489 : /* When !MCE, silently return not constant. */
11490 : return true;
11491 : }
11492 27 : else if (contract_terminating_p (global_ctx->contract_statement))
11493 : {
11494 : kind = diagnostics::kind::error;
11495 : error = true;
11496 : }
11497 : else
11498 6 : kind = diagnostics::kind::warning;
11499 :
11500 : /* [basic.contract.eval]/7.3 */
11501 27 : if (global_ctx->contract_condition_non_const)
11502 : {
11503 6 : emit_diagnostic (kind, loc, 0, "contract condition is not constant");
11504 6 : return error;
11505 : }
11506 :
11507 : /* Otherwise, the evaluation was const, but determined to be false. */
11508 21 : emit_diagnostic (kind, loc, 0,
11509 : "contract predicate is false in constant expression");
11510 21 : return error;
11511 : }
11512 :
11513 : /* ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
11514 : STRICT has the same sense as for constant_value_1: true if we only allow
11515 : conforming C++ constant expressions, or false if we want a constant value
11516 : even if it doesn't conform.
11517 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
11518 : per P0595 even when ALLOW_NON_CONSTANT is true.
11519 : CONSTEXPR_DTOR is true when evaluating the dtor of a constexpr variable.
11520 : OBJECT must be non-NULL in that case. */
11521 :
11522 : static tree
11523 580835290 : cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
11524 : bool strict = true,
11525 : mce_value manifestly_const_eval = mce_unknown,
11526 : bool constexpr_dtor = false,
11527 : tree object = NULL_TREE)
11528 : {
11529 580835290 : auto_timevar time (TV_CONSTEXPR);
11530 :
11531 580835290 : bool non_constant_p = false;
11532 580835290 : bool overflow_p = false;
11533 :
11534 580835290 : if (BRACE_ENCLOSED_INITIALIZER_P (t))
11535 : {
11536 0 : gcc_checking_assert (allow_non_constant);
11537 : return t;
11538 : }
11539 :
11540 580835290 : constexpr_global_ctx global_ctx;
11541 580835290 : constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
11542 : allow_non_constant, strict,
11543 580835290 : !allow_non_constant ? mce_true : manifestly_const_eval };
11544 :
11545 : /* Turn off -frounding-math for manifestly constant evaluation. */
11546 580835290 : warning_sentinel rm (flag_rounding_math,
11547 580835290 : ctx.manifestly_const_eval == mce_true);
11548 580835290 : tree type = (object
11549 580835290 : ? cv_unqualified (TREE_TYPE (object))
11550 513919451 : : initialized_type (t));
11551 580835290 : tree r = t;
11552 580835290 : bool is_consteval = false;
11553 580835290 : if (VOID_TYPE_P (type))
11554 : {
11555 10114691 : if (!constexpr_dtor)
11556 : {
11557 10114691 : if (cxx_dialect < cxx20)
11558 : return t;
11559 : /* We could have a COMPOUND_EXPR here coming from
11560 : keep_unused_object_arg. */
11561 10103641 : tree x = extract_call_expr (t);
11562 10103641 : if (x == NULL_TREE || x == error_mark_node)
11563 : return t;
11564 : /* Calls to immediate functions returning void need to be
11565 : evaluated. */
11566 10103599 : tree fndecl = cp_get_callee_fndecl_nofold (x);
11567 20207198 : if (fndecl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (fndecl))
11568 : return t;
11569 : else
11570 623 : is_consteval = true;
11571 623 : tree lam;
11572 623 : if (manifestly_const_eval == mce_true
11573 1152 : && LAMBDA_FUNCTION_P (fndecl)
11574 523 : && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fndecl)))
11575 1146 : && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
11576 516 : global_ctx.consteval_block = fndecl;
11577 : }
11578 : }
11579 570720599 : else if (cxx_dialect >= cxx20
11580 561810879 : && (TREE_CODE (t) == CALL_EXPR
11581 482789353 : || TREE_CODE (t) == AGGR_INIT_EXPR
11582 477657008 : || TREE_CODE (t) == TARGET_EXPR))
11583 : {
11584 89626983 : tree x = t;
11585 89626983 : if (TREE_CODE (x) == TARGET_EXPR)
11586 5473112 : x = TARGET_EXPR_INITIAL (x);
11587 89626983 : tree fndecl = cp_get_callee_fndecl_nofold (x);
11588 176468637 : if (fndecl && DECL_IMMEDIATE_FUNCTION_P (fndecl))
11589 : is_consteval = true;
11590 : /* Don't try to evaluate a std::vector constructor taking an integer, it
11591 : will fail in the 'if (heap_var)' block below after doing all the work
11592 : (c++/113835). This will need adjustment if P3554 is accepted. Note
11593 : that evaluation of e.g. the vector default constructor can succeed, so
11594 : we don't shortcut all vector constructors. */
11595 173683308 : if (fndecl && DECL_CONSTRUCTOR_P (fndecl) && allow_non_constant
11596 11558207 : && is_std_class (type, "vector") && call_expr_nargs (x) > 1
11597 89651563 : && TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE)
11598 : return t;
11599 : }
11600 570719175 : if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
11601 : {
11602 : /* In C++14 an NSDMI can participate in aggregate initialization,
11603 : and can refer to the address of the object being initialized, so
11604 : we need to pass in the relevant VAR_DECL if we want to do the
11605 : evaluation in a single pass. The evaluation will dynamically
11606 : update ctx.values for the VAR_DECL. We use the same strategy
11607 : for C++11 constexpr constructors that refer to the object being
11608 : initialized. */
11609 49747622 : if (constexpr_dtor)
11610 : {
11611 202 : gcc_assert (object && VAR_P (object));
11612 202 : gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
11613 202 : gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
11614 202 : if (error_operand_p (DECL_INITIAL (object)))
11615 : return t;
11616 185 : ctx.ctor = unshare_expr (DECL_INITIAL (object));
11617 185 : TREE_READONLY (ctx.ctor) = false;
11618 : /* Temporarily force decl_really_constant_value to return false
11619 : for it, we want to use ctx.ctor for the current value instead. */
11620 185 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = false;
11621 : }
11622 : else
11623 : {
11624 49747420 : ctx.ctor = build_constructor (type, NULL);
11625 49747420 : CONSTRUCTOR_NO_CLEARING (ctx.ctor) = true;
11626 : }
11627 49747605 : if (!object)
11628 : {
11629 22050439 : if (TREE_CODE (t) == CALL_EXPR)
11630 : {
11631 : /* If T is calling a constructor to initialize an object, reframe
11632 : it as an AGGR_INIT_EXPR to avoid trying to modify an object
11633 : from outside the constant evaluation, which will fail even if
11634 : the value is actually constant (is_constant_evaluated3.C). */
11635 9991039 : tree fn = cp_get_callee_fndecl_nofold (t);
11636 19981870 : if (fn && DECL_CONSTRUCTOR_P (fn))
11637 : {
11638 4106361 : object = CALL_EXPR_ARG (t, 0);
11639 4106361 : object = build_fold_indirect_ref (object);
11640 4106361 : r = build_aggr_init_expr (type, r);
11641 : }
11642 : }
11643 12059400 : else if (TREE_CODE (t) == TARGET_EXPR)
11644 5367887 : object = TARGET_EXPR_SLOT (t);
11645 6691513 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
11646 708670 : object = AGGR_INIT_EXPR_SLOT (t);
11647 : }
11648 49747605 : ctx.object = object;
11649 49747605 : if (object)
11650 37880084 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
11651 : (type, TREE_TYPE (object)));
11652 37880084 : if (object && DECL_P (object))
11653 31721939 : global_ctx.put_value (object, ctx.ctor);
11654 49747605 : if (TREE_CODE (r) == TARGET_EXPR)
11655 : /* Avoid creating another CONSTRUCTOR when we expand the
11656 : TARGET_EXPR. */
11657 5509636 : r = TARGET_EXPR_INITIAL (r);
11658 : }
11659 :
11660 : /* uid_sensitive_constexpr_evaluation_value restricts warning-dependent
11661 : constexpr evaluation to avoid unnecessary template instantiation, and is
11662 : always done with mce_unknown. But due to gaps in the restriction logic
11663 : we may still end up taking an evaluation path that in turn requires
11664 : manifestly constant evaluation, and such evaluation must not be
11665 : restricted since it likely has semantic consequences.
11666 : TODO: Remove/replace the mechanism in GCC 17. */
11667 570719158 : auto uids = make_temp_override (uid_sensitive_constexpr_evaluation_value);
11668 570719158 : if (ctx.manifestly_const_eval == mce_true)
11669 291651064 : uid_sensitive_constexpr_evaluation_value = false;
11670 :
11671 570719158 : auto_vec<tree, 16> cleanups;
11672 570719158 : global_ctx.cleanups = &cleanups;
11673 :
11674 570719158 : if (manifestly_const_eval == mce_true)
11675 291651064 : instantiate_constexpr_fns (r);
11676 570719158 : tree jmp_target = NULL_TREE;
11677 570719158 : r = cxx_eval_constant_expression (&ctx, r, vc_prvalue,
11678 : &non_constant_p, &overflow_p,
11679 : &jmp_target);
11680 570717795 : if (throws (&jmp_target) && !non_constant_p)
11681 : {
11682 1336 : if (!ctx.quiet)
11683 374 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
11684 1336 : non_constant_p = true;
11685 1336 : jmp_target = NULL_TREE;
11686 1336 : r = t;
11687 : }
11688 570715123 : else if (!non_constant_p && jmp_target)
11689 : {
11690 24 : non_constant_p = true;
11691 24 : if (!ctx.quiet)
11692 : {
11693 3 : if (breaks (&jmp_target))
11694 3 : error ("%<break%> outside of a loop or %<switch%>");
11695 0 : else if (continues (&jmp_target))
11696 0 : error ("%<continue%> outside of a loop");
11697 0 : else if (returns (&jmp_target))
11698 0 : error ("%<return%> in a statement expression");
11699 : else
11700 0 : gcc_unreachable ();
11701 : }
11702 24 : r = t;
11703 : }
11704 :
11705 : /* If we got a non-simple TARGET_EXPR, the initializer was a sequence
11706 : of statements, and the result ought to be stored in ctx.ctor. */
11707 570716459 : if (r == void_node && !constexpr_dtor && ctx.ctor)
11708 0 : r = ctx.ctor;
11709 :
11710 570716459 : unsigned int i;
11711 570716459 : tree cleanup;
11712 570716459 : jmp_target = NULL_TREE;
11713 : /* Evaluate the cleanups. */
11714 1141535346 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
11715 102428 : if (cleanup == NULL_TREE)
11716 : /* NULL_TREE cleanup is a marker that before it is
11717 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it. */
11718 23 : --i;
11719 : else
11720 102405 : cxx_eval_constant_expression (&ctx, cleanup, vc_discard,
11721 : &non_constant_p, &overflow_p,
11722 : &jmp_target);
11723 570716459 : if (throws (&jmp_target) && !non_constant_p)
11724 : {
11725 0 : if (!ctx.quiet)
11726 0 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
11727 0 : non_constant_p = true;
11728 0 : r = t;
11729 : }
11730 :
11731 : /* Mutable logic is a bit tricky: we want to allow initialization of
11732 : constexpr variables with mutable members, but we can't copy those
11733 : members to another constexpr variable. */
11734 570716459 : if (!non_constant_p
11735 418989259 : && TREE_CODE (r) == CONSTRUCTOR
11736 587727444 : && CONSTRUCTOR_MUTABLE_POISON (r))
11737 : {
11738 93 : if (!allow_non_constant)
11739 6 : error ("%qE is not a constant expression because it refers to "
11740 : "mutable subobjects of %qT", t, type);
11741 93 : non_constant_p = true;
11742 : }
11743 :
11744 418989166 : if (!non_constant_p && cxx_dialect >= cxx20
11745 989705625 : && !global_ctx.heap_vars.is_empty ())
11746 : {
11747 123273 : tree heap_var = cp_walk_tree_without_duplicates (&r, find_heap_var_refs,
11748 : NULL);
11749 123273 : unsigned int i;
11750 123273 : if (heap_var)
11751 : {
11752 114243 : if (!allow_non_constant && !non_constant_p)
11753 : {
11754 17 : auto_diagnostic_group d;
11755 17 : if (DECL_LANG_SPECIFIC (heap_var))
11756 4 : error ("%qE is not a constant expression because it refers to "
11757 : "exception object allocated with "
11758 : "%<__cxa_allocate_exception%>", t);
11759 : else
11760 13 : error ("%qE is not a constant expression because it refers to "
11761 : "a result of %<operator new%>", t);
11762 17 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11763 17 : }
11764 114243 : r = t;
11765 114243 : non_constant_p = true;
11766 : }
11767 319796 : FOR_EACH_VEC_ELT (global_ctx.heap_vars, i, heap_var)
11768 : {
11769 196523 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
11770 : {
11771 114815 : if (!allow_non_constant && !non_constant_p)
11772 : {
11773 16 : auto_diagnostic_group d;
11774 16 : error ("%qE is not a constant expression because allocated "
11775 : "storage has not been deallocated", t);
11776 16 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11777 16 : }
11778 114815 : r = t;
11779 114815 : non_constant_p = true;
11780 : }
11781 : }
11782 : }
11783 :
11784 : /* Check that immediate invocation does not return an expression referencing
11785 : any immediate function decls. */
11786 570716459 : if (!non_constant_p && cxx_dialect >= cxx20)
11787 826316430 : if (tree immediate_fndecl
11788 413158215 : = cp_walk_tree_without_duplicates (&r, find_immediate_fndecl,
11789 : NULL))
11790 : {
11791 6701 : if (!allow_non_constant && !non_constant_p)
11792 : {
11793 78 : if (is_consteval)
11794 36 : error_at (cp_expr_loc_or_input_loc (t),
11795 : "immediate evaluation returns address of immediate "
11796 : "function %qD", immediate_fndecl);
11797 : else
11798 64 : error_at (cp_expr_loc_or_input_loc (t),
11799 : "constant evaluation returns address of immediate "
11800 : "function %qD", immediate_fndecl);
11801 : }
11802 6701 : r = t;
11803 6701 : non_constant_p = true;
11804 : }
11805 :
11806 570716459 : if (!non_constant_p && !constexpr_dtor)
11807 418867975 : verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
11808 :
11809 : /* After verify_constant because reduced_constant_expression_p can unset
11810 : CONSTRUCTOR_NO_CLEARING. */
11811 570716459 : if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
11812 : {
11813 69916 : if (!allow_non_constant)
11814 45 : error ("%qE is not a constant expression because it refers to "
11815 : "an incompletely initialized variable", t);
11816 69916 : TREE_CONSTANT (r) = false;
11817 69916 : non_constant_p = true;
11818 : }
11819 :
11820 570716459 : if (non_constant_p)
11821 : /* If we saw something bad, go back to our argument. The wrapping below is
11822 : only for the cases of TREE_CONSTANT argument or overflow. */
11823 154289243 : r = t;
11824 :
11825 570716459 : if (!non_constant_p && overflow_p)
11826 215 : non_constant_p = true;
11827 :
11828 : /* Unshare the result. */
11829 570716459 : bool should_unshare = true;
11830 570716459 : if (r == t || (TREE_CODE (t) == TARGET_EXPR
11831 1509629 : && TARGET_EXPR_INITIAL (t) == r))
11832 : should_unshare = false;
11833 :
11834 570716459 : if (non_constant_p && !allow_non_constant)
11835 4126 : return error_mark_node;
11836 570712333 : else if (check_for_failed_contracts (&ctx))
11837 : {
11838 24 : if (manifestly_const_eval == mce_true)
11839 : /* If MCE, we gave a hard error and return error_mark_node. */
11840 21 : return error_mark_node;
11841 : else
11842 : {
11843 : /* Otherwise treat it as non-constant so the violation is still
11844 : detectable at run-time. */
11845 3 : gcc_checking_assert (allow_non_constant);
11846 : return t;
11847 : }
11848 : }
11849 570712309 : else if (non_constant_p && TREE_CONSTANT (r))
11850 143156 : r = mark_non_constant (r);
11851 570569153 : else if (non_constant_p)
11852 : return t;
11853 :
11854 416570133 : if (constexpr_dtor)
11855 : {
11856 167 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
11857 167 : return r;
11858 : }
11859 :
11860 : /* Check we are not trying to return the wrong type. */
11861 416569966 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
11862 : {
11863 : /* If so, this is not a constant expression. */
11864 155 : if (!allow_non_constant)
11865 2 : error ("%qE is not a constant expression because it initializes "
11866 2 : "a %qT rather than %qT", t, TREE_TYPE (t), type);
11867 : return t;
11868 : }
11869 :
11870 416569811 : if (should_unshare)
11871 233979018 : r = unshare_expr (r);
11872 :
11873 416569811 : if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
11874 : {
11875 16004956 : r = adjust_temp_type (type, r);
11876 16004956 : if (TREE_CODE (t) == TARGET_EXPR
11877 16004956 : && TARGET_EXPR_INITIAL (t) == r)
11878 : return t;
11879 15049188 : else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR
11880 2527101 : || TREE_CODE (t) == AGGR_INIT_EXPR)
11881 : /* Don't add a TARGET_EXPR if our argument didn't have one. */;
11882 838429 : else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t))
11883 768 : r = get_target_expr (r);
11884 837661 : else if (processing_template_decl)
11885 : /* Don't insert TARGET_EXPR in template trees. */
11886 : return r;
11887 : else
11888 : {
11889 837658 : r = get_target_expr (r, tf_warning_or_error | tf_no_cleanup);
11890 837658 : TREE_CONSTANT (r) = true;
11891 : }
11892 : }
11893 :
11894 415614040 : if (TREE_CODE (t) == TARGET_EXPR
11895 553861 : && TREE_CODE (r) == TARGET_EXPR)
11896 : {
11897 : /* Preserve this flag for potential_constant_expression, and the others
11898 : for good measure. */
11899 553749 : TARGET_EXPR_ELIDING_P (r) = TARGET_EXPR_ELIDING_P (t);
11900 553749 : TARGET_EXPR_IMPLICIT_P (r) = TARGET_EXPR_IMPLICIT_P (t);
11901 553749 : TARGET_EXPR_LIST_INIT_P (r) = TARGET_EXPR_LIST_INIT_P (t);
11902 553749 : TARGET_EXPR_DIRECT_INIT_P (r) = TARGET_EXPR_DIRECT_INIT_P (t);
11903 : }
11904 :
11905 : /* Remember the original location if that wouldn't need a wrapper. */
11906 415614040 : if (location_t loc = EXPR_LOCATION (t))
11907 190173370 : protected_set_expr_location (r, loc);
11908 :
11909 415614040 : return r;
11910 580832591 : }
11911 :
11912 : /* If T represents a constant expression returns its reduced value.
11913 : Otherwise return error_mark_node. */
11914 :
11915 : tree
11916 159613361 : cxx_constant_value (tree t, tree decl /* = NULL_TREE */,
11917 : tsubst_flags_t complain /* = tf_error */)
11918 : {
11919 159613361 : bool sfinae = !(complain & tf_error);
11920 159613361 : tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, mce_true, false, decl);
11921 159613361 : if (sfinae && !TREE_CONSTANT (r))
11922 2985 : r = error_mark_node;
11923 159613361 : return r;
11924 : }
11925 :
11926 : /* Like cxx_constant_value, but used for evaluation of constexpr destructors
11927 : of constexpr variables. The actual initializer of DECL is not modified. */
11928 :
11929 : void
11930 202 : cxx_constant_dtor (tree t, tree decl)
11931 : {
11932 202 : cxx_eval_outermost_constant_expr (t, false, true, mce_true, true, decl);
11933 202 : }
11934 :
11935 : /* Helper routine for fold_simple function. Either return simplified
11936 : expression T, otherwise NULL_TREE.
11937 : In contrast to cp_fully_fold, and to maybe_constant_value, we try to fold
11938 : even if we are within template-declaration. So be careful on call, as in
11939 : such case types can be undefined. */
11940 :
11941 : static tree
11942 171379990 : fold_simple_1 (tree t)
11943 : {
11944 171379990 : tree op1;
11945 171379990 : enum tree_code code = TREE_CODE (t);
11946 :
11947 171379990 : switch (code)
11948 : {
11949 : case INTEGER_CST:
11950 : case REAL_CST:
11951 : case VECTOR_CST:
11952 : case FIXED_CST:
11953 : case COMPLEX_CST:
11954 : return t;
11955 :
11956 1464167 : case SIZEOF_EXPR:
11957 1464167 : return fold_sizeof_expr (t);
11958 :
11959 40619705 : case ABS_EXPR:
11960 40619705 : case ABSU_EXPR:
11961 40619705 : case CONJ_EXPR:
11962 40619705 : case REALPART_EXPR:
11963 40619705 : case IMAGPART_EXPR:
11964 40619705 : case NEGATE_EXPR:
11965 40619705 : case BIT_NOT_EXPR:
11966 40619705 : case TRUTH_NOT_EXPR:
11967 40619705 : case VIEW_CONVERT_EXPR:
11968 40619705 : CASE_CONVERT:
11969 40619705 : case FLOAT_EXPR:
11970 40619705 : case FIX_TRUNC_EXPR:
11971 40619705 : case FIXED_CONVERT_EXPR:
11972 40619705 : case ADDR_SPACE_CONVERT_EXPR:
11973 :
11974 40619705 : op1 = TREE_OPERAND (t, 0);
11975 :
11976 40619705 : t = const_unop (code, TREE_TYPE (t), op1);
11977 40619705 : if (!t)
11978 : return NULL_TREE;
11979 :
11980 6248230 : if (CONVERT_EXPR_CODE_P (code)
11981 6248230 : && TREE_OVERFLOW_P (t) && !TREE_OVERFLOW_P (op1))
11982 0 : TREE_OVERFLOW (t) = false;
11983 : return t;
11984 :
11985 : default:
11986 : return NULL_TREE;
11987 : }
11988 : }
11989 :
11990 : /* If T is a simple constant expression, returns its simplified value.
11991 : Otherwise returns T. In contrast to maybe_constant_value we
11992 : simplify only few operations on constant-expressions, and we don't
11993 : try to simplify constexpressions. */
11994 :
11995 : tree
11996 172193275 : fold_simple (tree t)
11997 : {
11998 172193275 : if (processing_template_decl)
11999 : return t;
12000 :
12001 171379990 : tree r = fold_simple_1 (t);
12002 171379990 : if (r)
12003 120470148 : return r;
12004 :
12005 : return t;
12006 : }
12007 :
12008 : /* Try folding the expression T to a simple constant.
12009 : Returns that constant, otherwise returns T. */
12010 :
12011 : tree
12012 1684465 : fold_to_constant (tree t)
12013 : {
12014 1684465 : if (processing_template_decl)
12015 : return t;
12016 :
12017 1586981 : tree r = fold (t);
12018 1586981 : if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
12019 : return r;
12020 : else
12021 141116 : return t;
12022 : }
12023 :
12024 : /* If T is a constant expression, returns its reduced value.
12025 : Otherwise, if T does not have TREE_CONSTANT set, returns T.
12026 : Otherwise, returns a version of T without TREE_CONSTANT.
12027 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
12028 : as per P0595. */
12029 :
12030 : static GTY((deletable)) hash_map<tree, tree> *cv_cache;
12031 :
12032 : tree
12033 874381819 : maybe_constant_value (tree t, tree decl /* = NULL_TREE */,
12034 : mce_value manifestly_const_eval /* = mce_unknown */)
12035 : {
12036 874381819 : tree orig_t = t;
12037 874381819 : tree r;
12038 :
12039 874381819 : if (EXPR_P (t) && manifestly_const_eval == mce_unknown)
12040 : {
12041 : /* Look up each operand in the cv_cache first to see if we've already
12042 : reduced it, and reuse that result to avoid quadratic behavior if
12043 : we're called when building up a large expression. */
12044 252731392 : int n = cp_tree_operand_length (t);
12045 252731392 : tree *ops = XALLOCAVEC (tree, n);
12046 252731392 : bool rebuild = false;
12047 707346146 : for (int i = 0; i < n; ++i)
12048 : {
12049 454614754 : ops[i] = TREE_OPERAND (t, i);
12050 939926791 : if (tree *cached = hash_map_safe_get (cv_cache, ops[i]))
12051 31431413 : if (*cached != ops[i])
12052 : {
12053 9822863 : ops[i] = *cached;
12054 9822863 : rebuild = true;
12055 : }
12056 : }
12057 252731392 : if (rebuild)
12058 : {
12059 8246843 : t = copy_node (t);
12060 26862667 : for (int i = 0; i < n; ++i)
12061 18615824 : TREE_OPERAND (t, i) = ops[i];
12062 : }
12063 : }
12064 :
12065 874381819 : if (!is_nondependent_constant_expression (t))
12066 : {
12067 0 : if (TREE_OVERFLOW_P (t)
12068 129205297 : || (!processing_template_decl && TREE_CONSTANT (t)))
12069 4498 : t = mark_non_constant (t);
12070 129205297 : return t;
12071 : }
12072 745176522 : else if (CONSTANT_CLASS_P (t))
12073 : /* No caching or evaluation needed. */
12074 : return t;
12075 :
12076 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
12077 : but at least try folding it to a simple constant. */
12078 340516808 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
12079 511776 : return fold_to_constant (t);
12080 :
12081 323385479 : if (manifestly_const_eval != mce_unknown)
12082 : /* TODO: Extend the cache to be mce_value aware. And if we have a
12083 : previously cached mce_unknown result that's TREE_CONSTANT, it means
12084 : the reduced value is independent of mce_value and so we should
12085 : be able to reuse it in the mce_true/false case. */
12086 174615581 : return cxx_eval_outermost_constant_expr (t, true, true,
12087 174612882 : manifestly_const_eval, false, decl);
12088 :
12089 165389451 : if (cv_cache == NULL)
12090 151657 : cv_cache = hash_map<tree, tree>::create_ggc (101);
12091 165389451 : if (tree *cached = cv_cache->get (t))
12092 : {
12093 13466494 : r = *cached;
12094 13466494 : if (r != t)
12095 : {
12096 : /* Clear processing_template_decl for sake of break_out_target_exprs;
12097 : entries in the cv_cache are non-templated. */
12098 4539834 : processing_template_decl_sentinel ptds;
12099 :
12100 4539834 : r = break_out_target_exprs (r, /*clear_loc*/true);
12101 4539834 : protected_set_expr_location (r, EXPR_LOCATION (t));
12102 4539834 : }
12103 13466494 : return r;
12104 : }
12105 :
12106 151922957 : uid_sensitive_constexpr_evaluation_checker c;
12107 151922957 : r = cxx_eval_outermost_constant_expr (t, true, true,
12108 : manifestly_const_eval, false, decl);
12109 151922957 : gcc_checking_assert (r == t
12110 : || CONVERT_EXPR_P (t)
12111 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
12112 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
12113 : || !cp_tree_equal (r, t));
12114 151922957 : if (!c.evaluation_restricted_p ())
12115 151679929 : cv_cache->put (orig_t, r);
12116 : return r;
12117 : }
12118 :
12119 : /* Dispose of the whole CV_CACHE. */
12120 :
12121 : static void
12122 41399344 : clear_cv_cache (void)
12123 : {
12124 41399344 : if (cv_cache != NULL)
12125 41064181 : cv_cache->empty ();
12126 41399344 : }
12127 :
12128 : /* Dispose of the whole CV_CACHE and FOLD_CACHE. */
12129 :
12130 : void
12131 41399344 : clear_cv_and_fold_caches ()
12132 : {
12133 41399344 : clear_cv_cache ();
12134 41399344 : clear_fold_cache ();
12135 41399344 : }
12136 :
12137 : /* Internal function handling expressions in templates for
12138 : fold_non_dependent_expr and fold_non_dependent_init.
12139 :
12140 : If we're in a template, but T isn't value dependent, simplify
12141 : it. We're supposed to treat:
12142 :
12143 : template <typename T> void f(T[1 + 1]);
12144 : template <typename T> void f(T[2]);
12145 :
12146 : as two declarations of the same function, for example. */
12147 :
12148 : static tree
12149 31852580 : fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
12150 : bool manifestly_const_eval,
12151 : tree object)
12152 : {
12153 31852580 : gcc_assert (processing_template_decl);
12154 :
12155 31852580 : if (is_nondependent_constant_expression (t))
12156 : {
12157 17738468 : processing_template_decl_sentinel s;
12158 17738468 : t = instantiate_non_dependent_expr_internal (t, complain);
12159 :
12160 17738468 : if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t))
12161 : {
12162 0 : if (TREE_OVERFLOW_P (t))
12163 : {
12164 0 : t = build_nop (TREE_TYPE (t), t);
12165 0 : TREE_CONSTANT (t) = false;
12166 : }
12167 : return t;
12168 : }
12169 17738468 : else if (CONSTANT_CLASS_P (t))
12170 : /* No evaluation needed. */
12171 : return t;
12172 :
12173 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
12174 : but at least try folding it to a simple constant. */
12175 4684832 : if (cp_unevaluated_operand && !manifestly_const_eval)
12176 89 : return fold_to_constant (t);
12177 :
12178 4684743 : tree r = cxx_eval_outermost_constant_expr (t, true, true,
12179 : mce_value (manifestly_const_eval),
12180 : false, object);
12181 : /* cp_tree_equal looks through NOPs, so allow them. */
12182 4684743 : gcc_checking_assert (r == t
12183 : || CONVERT_EXPR_P (t)
12184 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
12185 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
12186 : || !cp_tree_equal (r, t));
12187 : return r;
12188 17738468 : }
12189 14114112 : else if (TREE_OVERFLOW_P (t))
12190 : {
12191 0 : t = build_nop (TREE_TYPE (t), t);
12192 0 : TREE_CONSTANT (t) = false;
12193 : }
12194 :
12195 : return t;
12196 : }
12197 :
12198 : /* Like maybe_constant_value but first fully instantiate the argument.
12199 :
12200 : Note: this is equivalent to instantiate_non_dependent_expr (t, complain)
12201 : followed by maybe_constant_value but is more efficient,
12202 : because it calls instantiation_dependent_expression_p and
12203 : potential_constant_expression at most once.
12204 : The manifestly_const_eval argument is passed to maybe_constant_value.
12205 :
12206 : Callers should generally pass their active complain, or if they are in a
12207 : non-template, diagnosing context, they can use the default of
12208 : tf_warning_or_error. Callers that might be within a template context, don't
12209 : have a complain parameter, and aren't going to remember the result for long
12210 : (e.g. null_ptr_cst_p), can pass tf_none and deal with error_mark_node
12211 : appropriately. */
12212 :
12213 : tree
12214 267309345 : fold_non_dependent_expr (tree t,
12215 : tsubst_flags_t complain /* = tf_warning_or_error */,
12216 : bool manifestly_const_eval /* = false */,
12217 : tree object /* = NULL_TREE */)
12218 : {
12219 267309345 : if (t == NULL_TREE)
12220 : return NULL_TREE;
12221 :
12222 266178836 : if (processing_template_decl)
12223 30716915 : return fold_non_dependent_expr_template (t, complain,
12224 30716915 : manifestly_const_eval, object);
12225 :
12226 235461921 : return maybe_constant_value (t, object, mce_value (manifestly_const_eval));
12227 : }
12228 :
12229 : /* Like fold_non_dependent_expr, but if EXPR couldn't be folded to a constant,
12230 : return the original expression. */
12231 :
12232 : tree
12233 2389885 : maybe_fold_non_dependent_expr (tree expr,
12234 : tsubst_flags_t complain/*=tf_warning_or_error*/)
12235 : {
12236 2389885 : tree t = fold_non_dependent_expr (expr, complain);
12237 2389885 : if (t && TREE_CONSTANT (t))
12238 1138620 : return t;
12239 :
12240 : return expr;
12241 : }
12242 :
12243 : /* Like maybe_constant_init but first fully instantiate the argument. */
12244 :
12245 : tree
12246 63272688 : fold_non_dependent_init (tree t,
12247 : tsubst_flags_t complain /*=tf_warning_or_error*/,
12248 : bool manifestly_const_eval /*=false*/,
12249 : tree object /* = NULL_TREE */)
12250 : {
12251 63272688 : if (t == NULL_TREE)
12252 : return NULL_TREE;
12253 :
12254 63272688 : if (processing_template_decl)
12255 : {
12256 1135665 : t = fold_non_dependent_expr_template (t, complain,
12257 : manifestly_const_eval, object);
12258 : /* maybe_constant_init does this stripping, so do it here too. */
12259 1135665 : if (TREE_CODE (t) == TARGET_EXPR)
12260 : {
12261 2107 : tree init = TARGET_EXPR_INITIAL (t);
12262 2107 : if (TREE_CODE (init) == CONSTRUCTOR)
12263 63272688 : t = init;
12264 : }
12265 : return t;
12266 : }
12267 :
12268 62137023 : return maybe_constant_init (t, object, manifestly_const_eval);
12269 : }
12270 :
12271 : /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
12272 : than wrapped in a TARGET_EXPR.
12273 : ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
12274 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
12275 : per P0595 even when ALLOW_NON_CONSTANT is true. */
12276 :
12277 : static tree
12278 176356874 : maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
12279 : mce_value manifestly_const_eval)
12280 : {
12281 176356874 : if (!t)
12282 : return t;
12283 176356874 : if (TREE_CODE (t) == EXPR_STMT)
12284 264 : t = TREE_OPERAND (t, 0);
12285 176356874 : if (TREE_CODE (t) == CONVERT_EXPR
12286 176356874 : && VOID_TYPE_P (TREE_TYPE (t)))
12287 2840 : t = TREE_OPERAND (t, 0);
12288 : /* If the types don't match, the INIT_EXPR is initializing a subobject of
12289 : DECL and losing that information would cause mischief later. */
12290 176356874 : if (TREE_CODE (t) == INIT_EXPR
12291 176356874 : && (!decl
12292 2594 : || same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (decl),
12293 2594 : TREE_TYPE (t))))
12294 1692 : t = TREE_OPERAND (t, 1);
12295 176356874 : if (TREE_CODE (t) == TARGET_EXPR)
12296 7896225 : t = TARGET_EXPR_INITIAL (t);
12297 176356874 : if (!is_nondependent_static_init_expression (t))
12298 : /* Don't try to evaluate it. */;
12299 142549786 : else if (CONSTANT_CLASS_P (t) && TREE_CODE (t) != PTRMEM_CST)
12300 : /* No evaluation needed. PTRMEM_CST needs the immediate fn check. */;
12301 : else
12302 : {
12303 : /* [basic.start.static] allows constant-initialization of variables with
12304 : static or thread storage duration even if it isn't required, but we
12305 : shouldn't bend the rules the same way for automatic variables.
12306 :
12307 : But still enforce the requirements of constexpr/constinit.
12308 : [dcl.constinit] "If a variable declared with the constinit specifier
12309 : has dynamic initialization, the program is ill-formed, even if the
12310 : implementation would perform that initialization as a static
12311 : initialization." */
12312 43460380 : bool is_static = (decl && DECL_P (decl)
12313 103752689 : && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
12314 : bool strict = (!is_static
12315 : || (decl && DECL_P (decl)
12316 3462898 : && (DECL_DECLARED_CONSTEXPR_P (decl)
12317 995293 : || DECL_DECLARED_CONSTINIT_P (decl))));
12318 : if (is_static)
12319 : manifestly_const_eval = mce_true;
12320 :
12321 66073019 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
12322 89255 : return fold_to_constant (t);
12323 :
12324 65983764 : t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
12325 : manifestly_const_eval,
12326 : false, decl);
12327 : }
12328 176267619 : if (TREE_CODE (t) == TARGET_EXPR)
12329 : {
12330 284119 : tree init = TARGET_EXPR_INITIAL (t);
12331 284119 : if (TREE_CODE (init) == CONSTRUCTOR)
12332 176356874 : t = init;
12333 : }
12334 : return t;
12335 : }
12336 :
12337 : /* Wrapper for maybe_constant_init_1 which permits non constants. */
12338 :
12339 : tree
12340 96668619 : maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
12341 : {
12342 96668619 : return maybe_constant_init_1 (t, decl, true, mce_value (manifestly_const_eval));
12343 : }
12344 :
12345 : tree
12346 79686026 : maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval)
12347 : {
12348 79686026 : return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
12349 : }
12350 :
12351 : /* Wrapper for maybe_constant_init_1 which does not permit non constants. */
12352 :
12353 : tree
12354 2229 : cxx_constant_init (tree t, tree decl)
12355 : {
12356 2229 : return maybe_constant_init_1 (t, decl, false, mce_true);
12357 : }
12358 :
12359 : /* Return true if CALL_EXPR T might throw during constant evaluation. */
12360 :
12361 : static bool
12362 232561354 : callee_might_throw (tree t)
12363 : {
12364 232561354 : if (cxx_dialect < cxx26 || !flag_exceptions)
12365 : return false;
12366 36739523 : tree callee = cp_get_callee (t);
12367 36739523 : if (callee == NULL_TREE)
12368 : return false;
12369 36682597 : tree callee_fn = cp_get_fndecl_from_callee (callee, false);
12370 36682597 : return (!flag_enforce_eh_specs
12371 36682597 : || type_dependent_expression_p (callee)
12372 33645032 : || !POINTER_TYPE_P (TREE_TYPE (callee))
12373 68132149 : || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee)))
12374 14762855 : && (callee_fn == NULL_TREE || !TREE_NOTHROW (callee_fn))));
12375 : }
12376 :
12377 : #if 0
12378 : /* FIXME see ADDR_EXPR section in potential_constant_expression_1. */
12379 : /* Return true if the object referred to by REF has automatic or thread
12380 : local storage. */
12381 :
12382 : enum { ck_ok, ck_bad, ck_unknown };
12383 : static int
12384 : check_automatic_or_tls (tree ref)
12385 : {
12386 : machine_mode mode;
12387 : poly_int64 bitsize, bitpos;
12388 : tree offset;
12389 : int volatilep = 0, unsignedp = 0;
12390 : tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
12391 : &mode, &unsignedp, &volatilep, false);
12392 : duration_kind dk;
12393 :
12394 : /* If there isn't a decl in the middle, we don't know the linkage here,
12395 : and this isn't a constant expression anyway. */
12396 : if (!DECL_P (decl))
12397 : return ck_unknown;
12398 : dk = decl_storage_duration (decl);
12399 : return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
12400 : }
12401 : #endif
12402 :
12403 : /* Data structure for passing data from potential_constant_expression_1
12404 : to check_for_return_continue via cp_walk_tree. */
12405 : struct check_for_return_continue_data {
12406 : hash_set<tree> *pset;
12407 : tree continue_stmt;
12408 : tree break_stmt;
12409 : bool could_throw;
12410 : };
12411 :
12412 : /* Helper function for potential_constant_expression_1 SWITCH_STMT handling,
12413 : called through cp_walk_tree. Return the first RETURN_EXPR found, or note
12414 : the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found.
12415 : For C++26 also note presence of possibly throwing calls. */
12416 : static tree
12417 51818948 : check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
12418 : {
12419 51818948 : tree t = *tp, s, b;
12420 51818948 : check_for_return_continue_data *d = (check_for_return_continue_data *) data;
12421 51818948 : switch (TREE_CODE (t))
12422 : {
12423 : case RETURN_EXPR:
12424 : return t;
12425 :
12426 28 : case CONTINUE_STMT:
12427 28 : if (d->continue_stmt == NULL_TREE)
12428 28 : d->continue_stmt = t;
12429 : break;
12430 :
12431 3270 : case BREAK_STMT:
12432 3270 : if (d->break_stmt == NULL_TREE)
12433 1347 : d->break_stmt = t;
12434 : break;
12435 :
12436 : #define RECUR(x) \
12437 : if (tree r = cp_walk_tree (&x, check_for_return_continue, data, \
12438 : d->pset)) \
12439 : return r
12440 :
12441 : /* For loops, walk subtrees manually, so that continue stmts found
12442 : inside of the bodies of the loops are ignored. */
12443 42375 : case DO_STMT:
12444 42375 : *walk_subtrees = 0;
12445 42375 : RECUR (DO_COND (t));
12446 42375 : s = d->continue_stmt;
12447 42375 : b = d->break_stmt;
12448 42375 : RECUR (DO_BODY (t));
12449 42375 : d->continue_stmt = s;
12450 42375 : d->break_stmt = b;
12451 42375 : break;
12452 :
12453 127 : case WHILE_STMT:
12454 127 : *walk_subtrees = 0;
12455 127 : RECUR (WHILE_COND_PREP (t));
12456 127 : RECUR (WHILE_COND (t));
12457 127 : s = d->continue_stmt;
12458 127 : b = d->break_stmt;
12459 127 : RECUR (WHILE_BODY (t));
12460 113 : d->continue_stmt = s;
12461 113 : d->break_stmt = b;
12462 113 : break;
12463 :
12464 402 : case FOR_STMT:
12465 402 : *walk_subtrees = 0;
12466 402 : RECUR (FOR_INIT_STMT (t));
12467 402 : RECUR (FOR_COND_PREP (t));
12468 402 : RECUR (FOR_COND (t));
12469 402 : RECUR (FOR_EXPR (t));
12470 402 : s = d->continue_stmt;
12471 402 : b = d->break_stmt;
12472 402 : RECUR (FOR_BODY (t));
12473 348 : d->continue_stmt = s;
12474 348 : d->break_stmt = b;
12475 348 : break;
12476 :
12477 0 : case RANGE_FOR_STMT:
12478 0 : *walk_subtrees = 0;
12479 0 : RECUR (RANGE_FOR_EXPR (t));
12480 0 : s = d->continue_stmt;
12481 0 : b = d->break_stmt;
12482 0 : RECUR (RANGE_FOR_BODY (t));
12483 0 : d->continue_stmt = s;
12484 0 : d->break_stmt = b;
12485 0 : break;
12486 :
12487 209 : case SWITCH_STMT:
12488 209 : *walk_subtrees = 0;
12489 209 : RECUR (SWITCH_STMT_COND (t));
12490 209 : b = d->break_stmt;
12491 209 : RECUR (SWITCH_STMT_BODY (t));
12492 189 : d->break_stmt = b;
12493 189 : break;
12494 : #undef RECUR
12495 :
12496 : case STATEMENT_LIST:
12497 : case CONSTRUCTOR:
12498 : break;
12499 :
12500 2662415 : case AGGR_INIT_EXPR:
12501 2662415 : case CALL_EXPR:
12502 : /* In C++26 a function could throw. */
12503 2662415 : if (callee_might_throw (t))
12504 126697 : d->could_throw = true;
12505 : break;
12506 :
12507 47693144 : default:
12508 47693144 : if (!EXPR_P (t))
12509 14815196 : *walk_subtrees = 0;
12510 : break;
12511 : }
12512 :
12513 : return NULL_TREE;
12514 : }
12515 :
12516 : /* Return true if T denotes a potentially constant expression. Issue
12517 : diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
12518 : an lvalue-rvalue conversion is implied. If NOW is true, we want to
12519 : consider the expression in the current context, independent of constexpr
12520 : substitution. If FUNDEF_P is true, we're checking a constexpr function body
12521 : and hard errors should not be reported by constexpr_error.
12522 :
12523 : C++0x [expr.const] used to say
12524 :
12525 : 6 An expression is a potential constant expression if it is
12526 : a constant expression where all occurrences of function
12527 : parameters are replaced by arbitrary constant expressions
12528 : of the appropriate type.
12529 :
12530 : 2 A conditional expression is a constant expression unless it
12531 : involves one of the following as a potentially evaluated
12532 : subexpression (3.2), but subexpressions of logical AND (5.14),
12533 : logical OR (5.15), and conditional (5.16) operations that are
12534 : not evaluated are not considered. */
12535 :
12536 : static bool
12537 4991608149 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
12538 : bool fundef_p, tsubst_flags_t flags,
12539 : tree *jump_target)
12540 : {
12541 : #define RECUR(T,RV) \
12542 : potential_constant_expression_1 ((T), (RV), strict, now, fundef_p, flags, \
12543 : jump_target)
12544 :
12545 4991608149 : enum { any = false, rval = true };
12546 4991608149 : int i;
12547 4991608149 : tree tmp;
12548 :
12549 4991608149 : if (t == error_mark_node)
12550 : return false;
12551 4991595677 : if (t == NULL_TREE)
12552 : return true;
12553 4983374608 : location_t loc = cp_expr_loc_or_input_loc (t);
12554 4983374608 : iloc_sentinel ils = loc;
12555 :
12556 4983374608 : if (*jump_target)
12557 : /* If we are jumping, ignore everything. This is simpler than the
12558 : cxx_eval_constant_expression handling because we only need to be
12559 : conservatively correct, and we don't necessarily have a constant value
12560 : available, so we don't bother with switch tracking. */
12561 : return true;
12562 :
12563 2247100 : if (TREE_THIS_VOLATILE (t) && want_rval
12564 1269766 : && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))
12565 4973858691 : && !NULLPTR_TYPE_P (TREE_TYPE (t)))
12566 : {
12567 78674 : if (TREE_CLOBBER_P (t))
12568 : {
12569 : /* We should have caught any clobbers in INIT/MODIFY_EXPR. */
12570 0 : gcc_checking_assert (false);
12571 : return true;
12572 : }
12573 :
12574 78674 : if (flags & tf_error)
12575 25 : constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of "
12576 : "a volatile lvalue %qE with type %qT", t,
12577 25 : TREE_TYPE (t));
12578 : return false;
12579 : }
12580 4973701316 : if (CONSTANT_CLASS_P (t))
12581 : return true;
12582 3625527088 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
12583 3625527088 : && TREE_TYPE (t) == error_mark_node)
12584 : return false;
12585 :
12586 3625527045 : switch (TREE_CODE (t))
12587 : {
12588 : case FUNCTION_DECL:
12589 : case BASELINK:
12590 : case TEMPLATE_DECL:
12591 : case OVERLOAD:
12592 : case TEMPLATE_ID_EXPR:
12593 : case LABEL_DECL:
12594 : case CASE_LABEL_EXPR:
12595 : case PREDICT_EXPR:
12596 : case CONST_DECL:
12597 : case SIZEOF_EXPR:
12598 : case ALIGNOF_EXPR:
12599 : case OFFSETOF_EXPR:
12600 : case NOEXCEPT_EXPR:
12601 : case TEMPLATE_PARM_INDEX:
12602 : case TRAIT_EXPR:
12603 : case IDENTIFIER_NODE:
12604 : case USERDEF_LITERAL:
12605 : /* We can see a FIELD_DECL in a pointer-to-member expression. */
12606 : case FIELD_DECL:
12607 : case RESULT_DECL:
12608 : case USING_DECL:
12609 : case USING_STMT:
12610 : case PLACEHOLDER_EXPR:
12611 : case REQUIRES_EXPR:
12612 : case STATIC_ASSERT:
12613 : case DEBUG_BEGIN_STMT:
12614 : case REFLECT_EXPR:
12615 : return true;
12616 :
12617 25043124 : case RETURN_EXPR:
12618 25043124 : if (!RECUR (TREE_OPERAND (t, 0), any))
12619 : return false;
12620 : /* FALLTHROUGH */
12621 :
12622 24874738 : case BREAK_STMT:
12623 24874738 : case CONTINUE_STMT:
12624 24874738 : *jump_target = t;
12625 24874738 : return true;
12626 :
12627 396308442 : case PARM_DECL:
12628 396308442 : if (now && want_rval)
12629 : {
12630 101892623 : tree type = TREE_TYPE (t);
12631 101892623 : if (dependent_type_p (type)
12632 72719995 : || !COMPLETE_TYPE_P (processing_template_decl
12633 : ? type : complete_type (type))
12634 174612618 : || is_really_empty_class (type, /*ignore_vptr*/false))
12635 : /* An empty class has no data to read. */
12636 : return true;
12637 72719289 : if (flags & tf_error)
12638 22 : constexpr_error (input_location, fundef_p,
12639 : "%qE is not a constant expression", t);
12640 : return false;
12641 : }
12642 : return true;
12643 :
12644 287041512 : case AGGR_INIT_EXPR:
12645 287041512 : case CALL_EXPR:
12646 : /* -- an invocation of a function other than a constexpr function
12647 : or a constexpr constructor. */
12648 287041512 : {
12649 287041512 : tree fun = get_function_named_in_call (t);
12650 287041512 : const int nargs = call_expr_nargs (t);
12651 287041512 : i = 0;
12652 :
12653 287041512 : if (fun == NULL_TREE)
12654 : {
12655 : /* Reset to allow the function to continue past the end
12656 : of the block below. Otherwise return early. */
12657 428073 : bool bail = true;
12658 :
12659 428073 : if (TREE_CODE (t) == CALL_EXPR
12660 428073 : && CALL_EXPR_FN (t) == NULL_TREE)
12661 428073 : switch (CALL_EXPR_IFN (t))
12662 : {
12663 : /* These should be ignored, they are optimized away from
12664 : constexpr functions. */
12665 : case IFN_UBSAN_NULL:
12666 : case IFN_UBSAN_BOUNDS:
12667 : case IFN_UBSAN_VPTR:
12668 : case IFN_FALLTHROUGH:
12669 : case IFN_ASSUME:
12670 : return true;
12671 :
12672 : case IFN_ADD_OVERFLOW:
12673 : case IFN_SUB_OVERFLOW:
12674 : case IFN_MUL_OVERFLOW:
12675 : case IFN_LAUNDER:
12676 : case IFN_VEC_CONVERT:
12677 : case IFN_BSWAP:
12678 : case IFN_BITREVERSE:
12679 : bail = false;
12680 : break;
12681 :
12682 : default:
12683 : break;
12684 : }
12685 :
12686 : if (bail)
12687 : {
12688 : /* fold_call_expr can't do anything with IFN calls. */
12689 172 : if (flags & tf_error)
12690 0 : constexpr_error (loc, fundef_p,
12691 : "call to internal function %qE", t);
12692 : return false;
12693 : }
12694 : }
12695 :
12696 286613439 : if (fun && is_overloaded_fn (fun))
12697 : {
12698 267654770 : if (!RECUR (fun, true))
12699 : return false;
12700 267228433 : fun = get_fns (fun);
12701 :
12702 267228433 : if (TREE_CODE (fun) == FUNCTION_DECL)
12703 : {
12704 249199982 : if (builtin_valid_in_constant_expr_p (fun))
12705 : return true;
12706 247371504 : if (!maybe_constexpr_fn (fun)
12707 : /* Allow any built-in function; if the expansion
12708 : isn't constant, we'll deal with that then. */
12709 55593542 : && !fndecl_built_in_p (fun)
12710 : /* In C++20, replaceable global allocation functions
12711 : are constant expressions. */
12712 37928179 : && (!cxx_replaceable_global_alloc_fn (fun)
12713 995259 : || TREE_CODE (t) != CALL_EXPR
12714 995259 : || (!CALL_FROM_NEW_OR_DELETE_P (t)
12715 363431 : && (current_function_decl == NULL_TREE
12716 363431 : || !is_std_allocator_allocate_deallocate
12717 363431 : (current_function_decl))))
12718 : /* Allow placement new in std::construct_at. */
12719 36939991 : && (!cxx_placement_new_fn (fun)
12720 403712 : || TREE_CODE (t) != CALL_EXPR
12721 403712 : || current_function_decl == NULL_TREE
12722 403700 : || !is_std_construct_at (current_function_decl))
12723 36667189 : && !cxx_dynamic_cast_fn_p (fun)
12724 284035082 : && !cxx_cxa_builtin_fn_p (fun))
12725 : {
12726 : /* In C++26 evaluation of the function arguments might
12727 : throw and in that case it is irrelevant whether
12728 : fun is constexpr or not. */
12729 36610591 : if (cxx_dialect >= cxx26)
12730 8079798 : for (; i < nargs; ++i)
12731 : {
12732 4847723 : tree x = get_nth_callarg (t, i);
12733 4847723 : bool rv = processing_template_decl ? any : rval;
12734 4847723 : bool sub_now = false;
12735 4847723 : if (!potential_constant_expression_1 (x, rv, strict,
12736 : sub_now,
12737 : fundef_p,
12738 : flags,
12739 : jump_target))
12740 : return false;
12741 4559532 : if (throws (jump_target))
12742 : return true;
12743 : }
12744 36293111 : if ((flags & tf_error)
12745 36293111 : && constexpr_error (loc, fundef_p,
12746 : "call to non-%<constexpr%> "
12747 : "function %qD", fun))
12748 272 : explain_invalid_constexpr_fn (fun);
12749 : return false;
12750 : }
12751 : }
12752 :
12753 228789364 : fun = OVL_FIRST (fun);
12754 : /* Skip initial arguments to base constructors. */
12755 228789364 : if (DECL_BASE_CONSTRUCTOR_P (fun))
12756 4191905 : i = num_artificial_parms_for (fun);
12757 : }
12758 18958669 : else if (fun)
12759 : {
12760 18958669 : if (TREE_TYPE (fun)
12761 18958669 : && FUNCTION_POINTER_TYPE_P (TREE_TYPE (fun)))
12762 : want_rval = rval;
12763 : else
12764 : want_rval = any;
12765 18958669 : if (RECUR (fun, want_rval))
12766 : /* Might end up being a constant function pointer. But it
12767 : could also be a function object with constexpr op(), so
12768 : we pass 'any' so that the underlying VAR_DECL is deemed
12769 : as potentially-constant even though it wasn't declared
12770 : constexpr. */;
12771 : else
12772 : return false;
12773 : }
12774 549964922 : for (; i < nargs; ++i)
12775 : {
12776 320009955 : tree x = get_nth_callarg (t, i);
12777 : /* In a template, reference arguments haven't been converted to
12778 : REFERENCE_TYPE and we might not even know if the parameter
12779 : is a reference, so accept lvalue constants too. */
12780 320009955 : bool rv = processing_template_decl ? any : rval;
12781 : /* Don't require an immediately constant value, as constexpr
12782 : substitution might not use the value of the argument. */
12783 320009955 : bool sub_now = false;
12784 320009955 : if (!potential_constant_expression_1 (x, rv, strict,
12785 : sub_now, fundef_p, flags,
12786 : jump_target))
12787 : return false;
12788 3248596506 : if (throws (jump_target))
12789 : return true;
12790 : }
12791 : /* In C++26 a function could throw. */
12792 229954967 : if (*jump_target == NULL_TREE && callee_might_throw (t))
12793 11652845 : *jump_target = void_node;
12794 : return true;
12795 : }
12796 :
12797 204634728 : case NON_LVALUE_EXPR:
12798 : /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
12799 : -- an lvalue of integral type that refers to a non-volatile
12800 : const variable or static data member initialized with
12801 : constant expressions, or
12802 :
12803 : -- an lvalue of literal type that refers to non-volatile
12804 : object defined with constexpr, or that refers to a
12805 : sub-object of such an object; */
12806 204634728 : return RECUR (TREE_OPERAND (t, 0), rval);
12807 :
12808 71531 : case EXCESS_PRECISION_EXPR:
12809 71531 : return RECUR (TREE_OPERAND (t, 0), rval);
12810 :
12811 317215699 : case VAR_DECL:
12812 317215699 : if (DECL_HAS_VALUE_EXPR_P (t))
12813 : {
12814 5269144 : if (now && is_normal_capture_proxy (t))
12815 : {
12816 : /* -- in a lambda-expression, a reference to this or to a
12817 : variable with automatic storage duration defined outside that
12818 : lambda-expression, where the reference would be an
12819 : odr-use. */
12820 :
12821 471921 : if (want_rval)
12822 : /* Since we're doing an lvalue-rvalue conversion, this might
12823 : not be an odr-use, so evaluate the variable directly. */
12824 464938 : return RECUR (DECL_CAPTURED_VARIABLE (t), rval);
12825 :
12826 6983 : if (flags & tf_error)
12827 : {
12828 3 : tree cap = DECL_CAPTURED_VARIABLE (t);
12829 3 : auto_diagnostic_group d;
12830 3 : if (constexpr_error (input_location, fundef_p,
12831 : "lambda capture of %qE is not a "
12832 : "constant expression", cap)
12833 3 : && decl_constant_var_p (cap))
12834 3 : inform (input_location, "because it is used as a glvalue");
12835 3 : }
12836 : return false;
12837 : }
12838 4797223 : tree ve = DECL_VALUE_EXPR (t);
12839 : /* Treat __PRETTY_FUNCTION__ inside a template function as
12840 : potentially-constant. */
12841 4797223 : if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
12842 : return true;
12843 4797218 : if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
12844 2736 : return RECUR (TREE_VEC_ELT (ve, 0), rval);
12845 4794482 : return RECUR (ve, rval);
12846 : }
12847 311946555 : if (want_rval
12848 220615054 : && (now || !var_in_maybe_constexpr_fn (t))
12849 201164243 : && !type_dependent_expression_p (t)
12850 169141467 : && !decl_maybe_constant_var_p (t)
12851 55234633 : && !is_local_temp (t)
12852 54656462 : && (strict
12853 4121883 : || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
12854 1638010 : || (DECL_INITIAL (t)
12855 1167878 : && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)))
12856 54147163 : && COMPLETE_TYPE_P (TREE_TYPE (t))
12857 366093564 : && !is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
12858 : {
12859 54142164 : if (flags & tf_error)
12860 175 : non_const_var_error (loc, t, fundef_p);
12861 : return false;
12862 : }
12863 : return true;
12864 :
12865 451229562 : case NOP_EXPR:
12866 451229562 : if (REINTERPRET_CAST_P (t))
12867 : {
12868 163647 : if (flags & tf_error)
12869 49 : constexpr_error (loc, fundef_p, "%<reinterpret_cast%> is not a "
12870 : "constant expression");
12871 : return false;
12872 : }
12873 : /* FALLTHRU */
12874 908488647 : case CONVERT_EXPR:
12875 908488647 : case VIEW_CONVERT_EXPR:
12876 : /* -- a reinterpret_cast. FIXME not implemented, and this rule
12877 : may change to something more specific to type-punning (DR 1312). */
12878 908488647 : {
12879 908488647 : tree from = TREE_OPERAND (t, 0);
12880 908488647 : if (location_wrapper_p (t))
12881 372439511 : return (RECUR (from, want_rval));
12882 536049136 : if (INDIRECT_TYPE_P (TREE_TYPE (t)))
12883 : {
12884 305042598 : STRIP_ANY_LOCATION_WRAPPER (from);
12885 305042598 : if (TREE_CODE (from) == INTEGER_CST
12886 305042598 : && !integer_zerop (from))
12887 : {
12888 1647 : if (flags & tf_error)
12889 37 : constexpr_error (loc, fundef_p,
12890 : "%<reinterpret_cast%> from integer to "
12891 : "pointer");
12892 : return false;
12893 : }
12894 : }
12895 : /* convert_to_void used to fold these away to void_node, because they
12896 : are a discarded-value expression. */
12897 536047489 : if (TREE_CODE (t) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (t)))
12898 8811864 : return RECUR (from, /*want_rval=*/false);
12899 527235625 : return RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR);
12900 : }
12901 :
12902 12985 : case ADDRESSOF_EXPR:
12903 : /* This is like ADDR_EXPR, except it won't form pointer-to-member. */
12904 12985 : t = TREE_OPERAND (t, 0);
12905 12985 : goto handle_addr_expr;
12906 :
12907 100902700 : case ADDR_EXPR:
12908 : /* -- a unary operator & that is applied to an lvalue that
12909 : designates an object with thread or automatic storage
12910 : duration; */
12911 100902700 : t = TREE_OPERAND (t, 0);
12912 :
12913 100902700 : if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t))
12914 : /* A pointer-to-member constant. */
12915 : return true;
12916 :
12917 100915419 : handle_addr_expr:
12918 : #if 0
12919 : /* FIXME adjust when issue 1197 is fully resolved. For now don't do
12920 : any checking here, as we might dereference the pointer later. If
12921 : we remove this code, also remove check_automatic_or_tls. */
12922 : i = check_automatic_or_tls (t);
12923 : if (i == ck_ok)
12924 : return true;
12925 : if (i == ck_bad)
12926 : {
12927 : if (flags & tf_error)
12928 : error ("address-of an object %qE with thread local or "
12929 : "automatic storage is not a constant expression", t);
12930 : return false;
12931 : }
12932 : #endif
12933 100915419 : return RECUR (t, any);
12934 :
12935 108036615 : case COMPONENT_REF:
12936 108036615 : case ARROW_EXPR:
12937 108036615 : case OFFSET_REF:
12938 : /* -- a class member access unless its postfix-expression is
12939 : of literal type or of pointer to literal type. */
12940 : /* This test would be redundant, as it follows from the
12941 : postfix-expression being a potential constant expression. */
12942 108036615 : if (type_unknown_p (t))
12943 : return true;
12944 100023100 : if (is_overloaded_fn (t))
12945 : /* In a template, a COMPONENT_REF of a function expresses ob.fn(),
12946 : which uses ob as an lvalue. */
12947 102544792 : want_rval = false;
12948 102544792 : gcc_fallthrough ();
12949 :
12950 102544792 : case REALPART_EXPR:
12951 102544792 : case IMAGPART_EXPR:
12952 102544792 : case BIT_FIELD_REF:
12953 102544792 : return RECUR (TREE_OPERAND (t, 0), want_rval);
12954 :
12955 296088 : case EXPR_PACK_EXPANSION:
12956 296088 : return RECUR (PACK_EXPANSION_PATTERN (t), want_rval);
12957 :
12958 : case PACK_INDEX_EXPR:
12959 : return true;
12960 :
12961 113621701 : case INDIRECT_REF:
12962 113621701 : return RECUR (TREE_OPERAND (t, 0), rval);
12963 :
12964 25712896 : case STATEMENT_LIST:
12965 5084567369 : for (tree stmt : tsi_range (t))
12966 76008158 : if (!RECUR (stmt, any))
12967 4983374608 : return false;
12968 : return true;
12969 :
12970 5183949 : case MODIFY_EXPR:
12971 5183949 : if (cxx_dialect < cxx14)
12972 3893 : goto fail;
12973 5180056 : if (!RECUR (TREE_OPERAND (t, 0), any))
12974 : return false;
12975 : /* Just ignore clobbers. */
12976 4320590 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
12977 : return true;
12978 3837630 : if (!RECUR (TREE_OPERAND (t, 1), rval))
12979 : return false;
12980 : return true;
12981 :
12982 909938 : case MODOP_EXPR:
12983 909938 : if (cxx_dialect < cxx14)
12984 98 : goto fail;
12985 909840 : if (!RECUR (TREE_OPERAND (t, 0), rval))
12986 : return false;
12987 899231 : if (!RECUR (TREE_OPERAND (t, 2), rval))
12988 : return false;
12989 : return true;
12990 :
12991 553026 : case DO_STMT:
12992 553026 : if (!RECUR (DO_COND (t), rval))
12993 : return false;
12994 553026 : if (!RECUR (DO_BODY (t), any))
12995 : return false;
12996 552400 : if (breaks (jump_target) || continues (jump_target))
12997 5 : *jump_target = NULL_TREE;
12998 : return true;
12999 :
13000 455381 : case FOR_STMT:
13001 455381 : if (!RECUR (FOR_INIT_STMT (t), any))
13002 : return false;
13003 455381 : if (!RECUR (FOR_COND_PREP (t), any))
13004 : return false;
13005 455381 : tmp = FOR_COND (t);
13006 455381 : if (!RECUR (tmp, rval))
13007 : return false;
13008 455303 : if (tmp)
13009 : {
13010 406672 : if (!processing_template_decl)
13011 402118 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13012 : /* If we couldn't evaluate the condition, it might not ever be
13013 : true. */
13014 406672 : if (!integer_onep (tmp))
13015 : {
13016 : /* Before returning true, check if the for body can contain
13017 : a return. */
13018 406672 : hash_set<tree> pset;
13019 406672 : check_for_return_continue_data data = { &pset, NULL_TREE,
13020 406672 : NULL_TREE, false };
13021 406672 : if (tree ret_expr
13022 406672 : = cp_walk_tree (&FOR_BODY (t), check_for_return_continue,
13023 : &data, &pset))
13024 141444 : *jump_target = ret_expr;
13025 406672 : if (data.could_throw)
13026 17917 : *jump_target = void_node;
13027 406672 : return true;
13028 406672 : }
13029 : }
13030 48631 : if (!RECUR (FOR_EXPR (t), any))
13031 : return false;
13032 48631 : if (!RECUR (FOR_BODY (t), any))
13033 : return false;
13034 48631 : if (!RECUR (FOR_COND_CLEANUP (t), any))
13035 : return false;
13036 48631 : if (breaks (jump_target) || continues (jump_target))
13037 12 : *jump_target = NULL_TREE;
13038 : return true;
13039 :
13040 482 : case RANGE_FOR_STMT:
13041 482 : if (!RECUR (RANGE_FOR_INIT_STMT (t), any))
13042 : return false;
13043 482 : if (!RECUR (RANGE_FOR_EXPR (t), any))
13044 : return false;
13045 482 : if (!RECUR (RANGE_FOR_BODY (t), any))
13046 : return false;
13047 480 : if (breaks (jump_target) || continues (jump_target))
13048 0 : *jump_target = NULL_TREE;
13049 : return true;
13050 :
13051 169319 : case WHILE_STMT:
13052 169319 : if (!RECUR (WHILE_COND_PREP (t), any))
13053 : return false;
13054 169319 : tmp = WHILE_COND (t);
13055 169319 : if (!RECUR (tmp, rval))
13056 : return false;
13057 169255 : if (!processing_template_decl)
13058 169218 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13059 : /* If we couldn't evaluate the condition, it might not ever be true. */
13060 169255 : if (!integer_onep (tmp))
13061 : {
13062 : /* Before returning true, check if the while body can contain
13063 : a return. */
13064 159047 : hash_set<tree> pset;
13065 159047 : check_for_return_continue_data data = { &pset, NULL_TREE,
13066 159047 : NULL_TREE, false };
13067 159047 : if (tree ret_expr
13068 159047 : = cp_walk_tree (&WHILE_BODY (t), check_for_return_continue,
13069 : &data, &pset))
13070 476 : *jump_target = ret_expr;
13071 159047 : if (data.could_throw)
13072 4621 : *jump_target = void_node;
13073 159047 : return true;
13074 159047 : }
13075 10208 : if (!RECUR (WHILE_BODY (t), any))
13076 : return false;
13077 10197 : if (!RECUR (WHILE_COND_CLEANUP (t), any))
13078 : return false;
13079 10197 : if (breaks (jump_target) || continues (jump_target))
13080 24 : *jump_target = NULL_TREE;
13081 : return true;
13082 :
13083 43153 : case SWITCH_STMT:
13084 43153 : if (!RECUR (SWITCH_STMT_COND (t), rval))
13085 : return false;
13086 : /* FIXME we don't check SWITCH_STMT_BODY currently, because even
13087 : unreachable labels would be checked and it is enough if there is
13088 : a single switch cond value for which it is a valid constant
13089 : expression. We need to check if there are any RETURN_EXPRs
13090 : or CONTINUE_STMTs inside of the body though, as in that case
13091 : we need to set *jump_target. */
13092 : else
13093 : {
13094 43143 : hash_set<tree> pset;
13095 43143 : check_for_return_continue_data data = { &pset, NULL_TREE,
13096 43143 : NULL_TREE, false };
13097 43143 : if (tree ret_expr
13098 43143 : = cp_walk_tree (&SWITCH_STMT_BODY (t), check_for_return_continue,
13099 : &data, &pset))
13100 : /* The switch might return. */
13101 42750 : *jump_target = ret_expr;
13102 393 : else if (data.continue_stmt)
13103 : /* The switch can't return, but might continue. */
13104 3 : *jump_target = data.continue_stmt;
13105 43143 : if (data.could_throw)
13106 1861 : *jump_target = void_node;
13107 43143 : }
13108 43143 : return true;
13109 :
13110 50 : case STMT_EXPR:
13111 50 : return RECUR (STMT_EXPR_STMT (t), rval);
13112 :
13113 627465 : case LAMBDA_EXPR:
13114 627465 : if (cxx_dialect >= cxx17)
13115 : /* In C++17 lambdas can be constexpr, don't give up yet. */
13116 : return true;
13117 476 : else if (flags & tf_error)
13118 0 : constexpr_error (loc, fundef_p, "lambda-expression is not a "
13119 : "constant expression before C++17");
13120 : return false;
13121 :
13122 114284 : case NEW_EXPR:
13123 114284 : case VEC_NEW_EXPR:
13124 114284 : case DELETE_EXPR:
13125 114284 : case VEC_DELETE_EXPR:
13126 114284 : if (cxx_dialect >= cxx20)
13127 : /* In C++20, new-expressions are potentially constant. */
13128 : return true;
13129 1077 : else if (flags & tf_error)
13130 0 : constexpr_error (loc, fundef_p, "new-expression is not a "
13131 : "constant expression before C++20");
13132 : return false;
13133 :
13134 85376 : case DYNAMIC_CAST_EXPR:
13135 85376 : case PSEUDO_DTOR_EXPR:
13136 85376 : case OMP_PARALLEL:
13137 85376 : case OMP_TASK:
13138 85376 : case OMP_FOR:
13139 85376 : case OMP_SIMD:
13140 85376 : case OMP_DISTRIBUTE:
13141 85376 : case OMP_TASKLOOP:
13142 85376 : case OMP_LOOP:
13143 85376 : case OMP_TEAMS:
13144 85376 : case OMP_TARGET_DATA:
13145 85376 : case OMP_TARGET:
13146 85376 : case OMP_SECTIONS:
13147 85376 : case OMP_ORDERED:
13148 85376 : case OMP_CRITICAL:
13149 85376 : case OMP_SINGLE:
13150 85376 : case OMP_SCAN:
13151 85376 : case OMP_SCOPE:
13152 85376 : case OMP_SECTION:
13153 85376 : case OMP_MASTER:
13154 85376 : case OMP_MASKED:
13155 85376 : case OMP_TASKGROUP:
13156 85376 : case OMP_TARGET_UPDATE:
13157 85376 : case OMP_TARGET_ENTER_DATA:
13158 85376 : case OMP_TARGET_EXIT_DATA:
13159 85376 : case OMP_ATOMIC:
13160 85376 : case OMP_ATOMIC_READ:
13161 85376 : case OMP_ATOMIC_CAPTURE_OLD:
13162 85376 : case OMP_ATOMIC_CAPTURE_NEW:
13163 85376 : case OMP_DEPOBJ:
13164 85376 : case OACC_PARALLEL:
13165 85376 : case OACC_KERNELS:
13166 85376 : case OACC_SERIAL:
13167 85376 : case OACC_DATA:
13168 85376 : case OACC_HOST_DATA:
13169 85376 : case OACC_LOOP:
13170 85376 : case OACC_CACHE:
13171 85376 : case OACC_DECLARE:
13172 85376 : case OACC_ENTER_DATA:
13173 85376 : case OACC_EXIT_DATA:
13174 85376 : case OACC_UPDATE:
13175 85376 : case OMP_ARRAY_SECTION:
13176 : /* GCC internal stuff. */
13177 85376 : case VA_ARG_EXPR:
13178 85376 : case TRANSACTION_EXPR:
13179 85376 : case AT_ENCODE_EXPR:
13180 85376 : fail:
13181 85376 : if (flags & tf_error)
13182 23 : constexpr_error (loc, fundef_p, "expression %qE is not a constant "
13183 : "expression", t);
13184 : return false;
13185 :
13186 : case OMP_DECLARE_MAPPER:
13187 : /* This can be used to initialize VAR_DECLs: it's treated as a magic
13188 : constant. */
13189 : return true;
13190 :
13191 26780 : case THROW_EXPR:
13192 26780 : if (cxx_dialect < cxx26)
13193 291 : goto fail;
13194 26489 : return RECUR (TREE_OPERAND (t, 0), rval);
13195 :
13196 531 : case ASM_EXPR:
13197 531 : if (flags & tf_error)
13198 6 : inline_asm_in_constexpr_error (loc, fundef_p);
13199 : return false;
13200 :
13201 544517 : case OBJ_TYPE_REF:
13202 544517 : if (cxx_dialect >= cxx20)
13203 : /* In C++20 virtual calls can be constexpr, don't give up yet. */
13204 : return true;
13205 9120 : else if (flags & tf_error)
13206 0 : constexpr_error (loc, fundef_p, "virtual functions cannot be "
13207 : "%<constexpr%> before C++20");
13208 : return false;
13209 :
13210 6617 : case TYPEID_EXPR:
13211 : /* In C++20, a typeid expression whose operand is of polymorphic
13212 : class type can be constexpr. */
13213 6617 : {
13214 6617 : tree e = TREE_OPERAND (t, 0);
13215 6617 : if (cxx_dialect < cxx20
13216 26 : && strict
13217 26 : && !TYPE_P (e)
13218 19 : && !type_dependent_expression_p (e)
13219 7 : && CLASS_TYPE_P (TREE_TYPE (e))
13220 6622 : && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
13221 : {
13222 4 : if (flags & tf_error)
13223 1 : constexpr_error (loc, fundef_p, "%<typeid%> is not a "
13224 : "constant expression because %qE is "
13225 : "of polymorphic type", e);
13226 : return false;
13227 : }
13228 : return true;
13229 : }
13230 :
13231 31571174 : case POINTER_DIFF_EXPR:
13232 31571174 : case MINUS_EXPR:
13233 31571174 : want_rval = true;
13234 31571174 : goto binary;
13235 :
13236 85788390 : case LT_EXPR:
13237 85788390 : case LE_EXPR:
13238 85788390 : case GT_EXPR:
13239 85788390 : case GE_EXPR:
13240 85788390 : case EQ_EXPR:
13241 85788390 : case NE_EXPR:
13242 85788390 : case SPACESHIP_EXPR:
13243 85788390 : want_rval = true;
13244 85788390 : goto binary;
13245 :
13246 2009114 : case PREINCREMENT_EXPR:
13247 2009114 : case POSTINCREMENT_EXPR:
13248 2009114 : case PREDECREMENT_EXPR:
13249 2009114 : case POSTDECREMENT_EXPR:
13250 2009114 : if (cxx_dialect < cxx14)
13251 9449 : goto fail;
13252 1999665 : goto unary;
13253 :
13254 1286771 : case BIT_NOT_EXPR:
13255 : /* A destructor. */
13256 1286771 : if (TYPE_P (TREE_OPERAND (t, 0)))
13257 : return true;
13258 : /* fall through. */
13259 :
13260 48771900 : case CONJ_EXPR:
13261 48771900 : case SAVE_EXPR:
13262 48771900 : case FIX_TRUNC_EXPR:
13263 48771900 : case FLOAT_EXPR:
13264 48771900 : case NEGATE_EXPR:
13265 48771900 : case ABS_EXPR:
13266 48771900 : case ABSU_EXPR:
13267 48771900 : case TRUTH_NOT_EXPR:
13268 48771900 : case FIXED_CONVERT_EXPR:
13269 48771900 : case UNARY_PLUS_EXPR:
13270 48771900 : case UNARY_LEFT_FOLD_EXPR:
13271 48771900 : case UNARY_RIGHT_FOLD_EXPR:
13272 48771900 : case VEC_DUPLICATE_EXPR:
13273 1286771 : unary:
13274 48771900 : return RECUR (TREE_OPERAND (t, 0), rval);
13275 :
13276 31824833 : case CAST_EXPR:
13277 31824833 : case CONST_CAST_EXPR:
13278 31824833 : case STATIC_CAST_EXPR:
13279 31824833 : case REINTERPRET_CAST_EXPR:
13280 31824833 : case IMPLICIT_CONV_EXPR:
13281 31824833 : if (!cast_valid_in_integral_constant_expression_p (TREE_TYPE (t)))
13282 : /* In C++98, a conversion to non-integral type can't be part of a
13283 : constant expression. */
13284 : {
13285 344 : if (flags & tf_error)
13286 0 : constexpr_error (loc, fundef_p,
13287 : "cast to non-integral type %qT in a constant "
13288 0 : "expression", TREE_TYPE (t));
13289 : return false;
13290 : }
13291 : /* This might be a conversion from a class to a (potentially) literal
13292 : type. Let's consider it potentially constant since the conversion
13293 : might be a constexpr user-defined conversion. */
13294 31824489 : else if (cxx_dialect >= cxx11
13295 31802028 : && (dependent_type_p (TREE_TYPE (t))
13296 11208976 : || !COMPLETE_TYPE_P (TREE_TYPE (t))
13297 11194238 : || literal_type_p (TREE_TYPE (t)))
13298 31763733 : && TREE_OPERAND (t, 0)
13299 63341447 : && (TREE_CODE (t) != CAST_EXPR
13300 23896224 : || !TREE_CHAIN (TREE_OPERAND (t, 0))))
13301 : {
13302 31473636 : tree from = TREE_OPERAND (t, 0);
13303 31473636 : if (TREE_CODE (t) == CAST_EXPR)
13304 23852902 : from = TREE_VALUE (from);
13305 31473636 : tree type = TREE_TYPE (from);
13306 : /* If this is a dependent type, it could end up being a class
13307 : with conversions. */
13308 31473636 : if (type == NULL_TREE || WILDCARD_TYPE_P (type))
13309 : return true;
13310 : /* Or a non-dependent class which has conversions. */
13311 596846 : else if (CLASS_TYPE_P (type)
13312 596846 : && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
13313 : return true;
13314 : }
13315 :
13316 25287562 : return (RECUR (TREE_OPERAND (t, 0),
13317 25287562 : !TYPE_REF_P (TREE_TYPE (t))));
13318 :
13319 14629436 : case BIND_EXPR:
13320 14629436 : return RECUR (BIND_EXPR_BODY (t), want_rval);
13321 :
13322 71614210 : case CLEANUP_POINT_EXPR:
13323 71614210 : case MUST_NOT_THROW_EXPR:
13324 71614210 : case TRY_CATCH_EXPR:
13325 : /* Even for C++26 handle TRY_BLOCK conservatively, if we detect the
13326 : body could throw, even with catch (...) among handlers we'd need
13327 : to analyze them in detail if they couldn't rethrow it. More
13328 : importantly though, throws (jump_target) is just conservative,
13329 : and there could be e.g.
13330 : try
13331 : {
13332 : possibly_throwing_fn (args);
13333 : break;
13334 : }
13335 : catch (...)
13336 : {
13337 : }
13338 : or continue or return instead of break. So, clearing *jump_target
13339 : because we see catch (...) handler might mean we missed break
13340 : etc. */
13341 71614210 : case TRY_BLOCK:
13342 71614210 : case EH_SPEC_BLOCK:
13343 71614210 : case EXPR_STMT:
13344 71614210 : case PAREN_EXPR:
13345 : /* For convenience. */
13346 71614210 : case LOOP_EXPR:
13347 71614210 : case EXIT_EXPR:
13348 71614210 : return RECUR (TREE_OPERAND (t, 0), want_rval);
13349 :
13350 13045400 : case DECL_EXPR:
13351 13045400 : tmp = DECL_EXPR_DECL (t);
13352 8664844 : if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)
13353 19127060 : && (processing_template_decl
13354 5595540 : ? !decl_maybe_constant_var_p (tmp)
13355 5109420 : : !decl_constant_var_p (tmp)))
13356 : {
13357 5030011 : if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
13358 : {
13359 8 : if (flags & tf_error)
13360 3 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
13361 : "%qD defined %<thread_local%> in "
13362 : "%<constexpr%> context", tmp);
13363 : return false;
13364 : }
13365 5030003 : else if (TREE_STATIC (tmp))
13366 : {
13367 148 : if (flags & tf_error)
13368 36 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
13369 : "%qD defined %<static%> in %<constexpr%> "
13370 : "context", tmp);
13371 : return false;
13372 : }
13373 5029855 : else if (!check_for_uninitialized_const_var
13374 5029855 : (tmp, /*constexpr_context_p=*/true, flags))
13375 : return false;
13376 : }
13377 13040299 : if (VAR_P (tmp))
13378 8659743 : return RECUR (DECL_INITIAL (tmp), want_rval);
13379 : return true;
13380 :
13381 43808 : case TRY_FINALLY_EXPR:
13382 43808 : return (RECUR (TREE_OPERAND (t, 0), want_rval)
13383 43808 : && RECUR (TREE_OPERAND (t, 1), any));
13384 :
13385 0 : case EH_ELSE_EXPR:
13386 : /* maybe_apply_function_contracts uses this to check postconditions only
13387 : on normal return. */
13388 0 : return (RECUR (TREE_OPERAND (t, 1), any)
13389 0 : || RECUR (TREE_OPERAND (t, 0), any));
13390 :
13391 24801914 : case SCOPE_REF:
13392 24801914 : return RECUR (TREE_OPERAND (t, 1), want_rval);
13393 :
13394 49895915 : case TARGET_EXPR:
13395 49895915 : if (!TARGET_EXPR_DIRECT_INIT_P (t)
13396 49686162 : && !TARGET_EXPR_ELIDING_P (t)
13397 89842308 : && !literal_type_p (TREE_TYPE (t)))
13398 : {
13399 909099 : if (flags & tf_error)
13400 : {
13401 25 : auto_diagnostic_group d;
13402 25 : if (constexpr_error (loc, fundef_p,
13403 : "temporary of non-literal type %qT in a "
13404 25 : "constant expression", TREE_TYPE (t)))
13405 25 : explain_non_literal_class (TREE_TYPE (t));
13406 25 : }
13407 : return false;
13408 : }
13409 : /* FALLTHRU */
13410 77857269 : case INIT_EXPR:
13411 77857269 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
13412 : return true;
13413 77736046 : return RECUR (TREE_OPERAND (t, 1), rval);
13414 :
13415 40314555 : case CONSTRUCTOR:
13416 40314555 : {
13417 40314555 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
13418 40314555 : constructor_elt *ce;
13419 5259786811 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
13420 237392744 : if (!RECUR (ce->value, want_rval))
13421 : return false;
13422 : return true;
13423 : }
13424 :
13425 21407752 : case TREE_LIST:
13426 21407752 : {
13427 21407752 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
13428 : || DECL_P (TREE_PURPOSE (t)));
13429 21407752 : if (!RECUR (TREE_VALUE (t), want_rval))
13430 : return false;
13431 19188064 : if (TREE_CHAIN (t) == NULL_TREE)
13432 : return true;
13433 55479 : return RECUR (TREE_CHAIN (t), want_rval);
13434 : }
13435 :
13436 15543362 : case TRUNC_DIV_EXPR:
13437 15543362 : case CEIL_DIV_EXPR:
13438 15543362 : case FLOOR_DIV_EXPR:
13439 15543362 : case ROUND_DIV_EXPR:
13440 15543362 : case TRUNC_MOD_EXPR:
13441 15543362 : case CEIL_MOD_EXPR:
13442 15543362 : case ROUND_MOD_EXPR:
13443 15543362 : {
13444 15543362 : tree denom = TREE_OPERAND (t, 1);
13445 15543362 : if (!RECUR (denom, rval))
13446 : return false;
13447 : /* We can't call cxx_eval_outermost_constant_expr on an expression
13448 : that hasn't been through instantiate_non_dependent_expr yet. */
13449 15018867 : if (!processing_template_decl)
13450 7971482 : denom = cxx_eval_outermost_constant_expr (denom, true);
13451 15018867 : if (integer_zerop (denom))
13452 : {
13453 378 : if (flags & tf_error)
13454 38 : constexpr_error (input_location, fundef_p,
13455 : "division by zero is not a constant expression");
13456 : return false;
13457 : }
13458 : else
13459 : {
13460 15018489 : want_rval = true;
13461 15018489 : return RECUR (TREE_OPERAND (t, 0), want_rval);
13462 : }
13463 : }
13464 :
13465 9774022 : case COMPOUND_EXPR:
13466 9774022 : {
13467 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
13468 : COMPOUND_EXPR; don't get confused. */
13469 9774022 : tree op0 = TREE_OPERAND (t, 0);
13470 9774022 : tree op1 = TREE_OPERAND (t, 1);
13471 9774022 : STRIP_NOPS (op1);
13472 9774022 : if (TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
13473 2742012 : return RECUR (op0, want_rval);
13474 : else
13475 7032010 : goto binary;
13476 : }
13477 :
13478 : /* If the first operand is the non-short-circuit constant, look at
13479 : the second operand; otherwise we only care about the first one for
13480 : potentiality. */
13481 19020930 : case TRUTH_AND_EXPR:
13482 19020930 : case TRUTH_ANDIF_EXPR:
13483 19020930 : tmp = boolean_true_node;
13484 19020930 : goto truth;
13485 7690765 : case TRUTH_OR_EXPR:
13486 7690765 : case TRUTH_ORIF_EXPR:
13487 7690765 : tmp = boolean_false_node;
13488 26711695 : truth:
13489 26711695 : {
13490 26711695 : tree op0 = TREE_OPERAND (t, 0);
13491 26711695 : tree op1 = TREE_OPERAND (t, 1);
13492 26711695 : if (!RECUR (op0, rval))
13493 : return false;
13494 18443705 : if (!(flags & tf_error) && RECUR (op1, rval))
13495 : /* When quiet, try to avoid expensive trial evaluation by first
13496 : checking potentiality of the second operand. */
13497 : return true;
13498 1856360 : if (!processing_template_decl)
13499 1451855 : op0 = cxx_eval_outermost_constant_expr (op0, true);
13500 1856360 : if (tree_int_cst_equal (op0, tmp))
13501 9124 : return (flags & tf_error) ? RECUR (op1, rval) : false;
13502 : else
13503 : return true;
13504 : }
13505 :
13506 : case PLUS_EXPR:
13507 : case MULT_EXPR:
13508 : case POINTER_PLUS_EXPR:
13509 : case RDIV_EXPR:
13510 : case EXACT_DIV_EXPR:
13511 : case MIN_EXPR:
13512 : case MAX_EXPR:
13513 : case LSHIFT_EXPR:
13514 : case RSHIFT_EXPR:
13515 : case LROTATE_EXPR:
13516 : case RROTATE_EXPR:
13517 : case BIT_IOR_EXPR:
13518 : case BIT_XOR_EXPR:
13519 : case BIT_AND_EXPR:
13520 : case TRUTH_XOR_EXPR:
13521 : case UNORDERED_EXPR:
13522 : case ORDERED_EXPR:
13523 : case UNLT_EXPR:
13524 : case UNLE_EXPR:
13525 : case UNGT_EXPR:
13526 : case UNGE_EXPR:
13527 : case UNEQ_EXPR:
13528 : case LTGT_EXPR:
13529 : case RANGE_EXPR:
13530 : case COMPLEX_EXPR:
13531 239895029 : want_rval = true;
13532 : /* Fall through. */
13533 252288612 : case ARRAY_REF:
13534 252288612 : case ARRAY_RANGE_REF:
13535 252288612 : case MEMBER_REF:
13536 252288612 : case DOTSTAR_EXPR:
13537 252288612 : case MEM_REF:
13538 252288612 : case BINARY_LEFT_FOLD_EXPR:
13539 252288612 : case BINARY_RIGHT_FOLD_EXPR:
13540 252288612 : binary:
13541 556049075 : for (i = 0; i < 2; ++i)
13542 411451735 : if (!RECUR (TREE_OPERAND (t, i), want_rval))
13543 : return false;
13544 : return true;
13545 :
13546 : case VEC_PERM_EXPR:
13547 121529 : for (i = 0; i < 3; ++i)
13548 120583 : if (!RECUR (TREE_OPERAND (t, i), true))
13549 : return false;
13550 : return true;
13551 :
13552 7632440 : case COND_EXPR:
13553 7632440 : if (COND_EXPR_IS_VEC_DELETE (t) && cxx_dialect < cxx20)
13554 : {
13555 8 : if (flags & tf_error)
13556 2 : constexpr_error (loc, fundef_p, "%<delete[]%> is not a "
13557 : "constant expression");
13558 : return false;
13559 : }
13560 : /* Fall through. */
13561 18401247 : case IF_STMT:
13562 18401247 : case VEC_COND_EXPR:
13563 : /* If the condition is a known constant, we know which of the legs we
13564 : care about; otherwise we only require that the condition and
13565 : either of the legs be potentially constant. */
13566 18401247 : tmp = TREE_OPERAND (t, 0);
13567 18401247 : if (!RECUR (tmp, rval))
13568 : return false;
13569 16078522 : if (!processing_template_decl)
13570 14020009 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13571 : /* potential_constant_expression* isn't told if it is called for
13572 : manifestly_const_eval or not, so for consteval if always
13573 : process both branches as if the condition is not a known
13574 : constant. */
13575 16078522 : if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
13576 : {
13577 16001588 : if (integer_zerop (tmp))
13578 3456945 : return RECUR (TREE_OPERAND (t, 2), want_rval);
13579 12544643 : else if (TREE_CODE (tmp) == INTEGER_CST)
13580 3831378 : return RECUR (TREE_OPERAND (t, 1), want_rval);
13581 : }
13582 8790199 : tmp = *jump_target;
13583 10152446 : for (i = 1; i < 3; ++i)
13584 : {
13585 10002268 : tree this_jump_target = tmp;
13586 10002268 : if (potential_constant_expression_1 (TREE_OPERAND (t, i),
13587 : want_rval, strict, now, fundef_p,
13588 : tf_none, &this_jump_target))
13589 : {
13590 8938860 : if (returns (&this_jump_target) || throws (&this_jump_target))
13591 2481348 : *jump_target = this_jump_target;
13592 6158673 : else if (!returns (jump_target) && !throws (jump_target))
13593 : {
13594 6158673 : if (breaks (&this_jump_target)
13595 6158673 : || continues (&this_jump_target))
13596 45 : *jump_target = this_jump_target;
13597 6158673 : if (i == 1)
13598 : {
13599 : /* If the then branch is potentially constant, but
13600 : does not return, check if the else branch
13601 : couldn't return, break or continue. */
13602 5097455 : hash_set<tree> pset;
13603 5097455 : check_for_return_continue_data data = { &pset, NULL_TREE,
13604 : NULL_TREE,
13605 5097455 : false };
13606 10194910 : if (tree ret_expr
13607 5097455 : = cp_walk_tree (&TREE_OPERAND (t, 2),
13608 : check_for_return_continue, &data,
13609 : &pset))
13610 80839 : *jump_target = ret_expr;
13611 5016616 : else if (*jump_target == NULL_TREE)
13612 : {
13613 5016574 : if (data.continue_stmt)
13614 0 : *jump_target = data.continue_stmt;
13615 5016574 : else if (data.break_stmt)
13616 13 : *jump_target = data.break_stmt;
13617 : }
13618 5097455 : if (data.could_throw)
13619 54634 : *jump_target = void_node;
13620 5097455 : }
13621 : }
13622 8640021 : return true;
13623 : }
13624 : }
13625 150178 : if (flags & tf_error)
13626 : {
13627 3 : if (TREE_CODE (t) == IF_STMT)
13628 3 : constexpr_error (loc, fundef_p, "neither branch of %<if%> is a "
13629 : "constant expression");
13630 : else
13631 0 : constexpr_error (loc, fundef_p, "expression %qE is not a "
13632 : "constant expression", t);
13633 : }
13634 : return false;
13635 :
13636 1746 : case VEC_INIT_EXPR:
13637 1746 : if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
13638 : return true;
13639 869 : if (flags & tf_error)
13640 : {
13641 3 : if (constexpr_error (loc, fundef_p, "non-constant array "
13642 : "initialization"))
13643 2 : diagnose_non_constexpr_vec_init (t);
13644 : }
13645 : return false;
13646 :
13647 : case TYPE_DECL:
13648 : case TAG_DEFN:
13649 : /* We can see these in statement-expressions. */
13650 : return true;
13651 :
13652 1500525 : case CLEANUP_STMT:
13653 1500525 : if (!RECUR (CLEANUP_BODY (t), any))
13654 : return false;
13655 2506395 : if (!CLEANUP_EH_ONLY (t) && !RECUR (CLEANUP_EXPR (t), any))
13656 : return false;
13657 : return true;
13658 :
13659 : case EMPTY_CLASS_EXPR:
13660 : return true;
13661 :
13662 128 : case GOTO_EXPR:
13663 128 : {
13664 128 : tree *target = &TREE_OPERAND (t, 0);
13665 : /* Gotos representing break, continue and cdtor return are OK. */
13666 128 : if (breaks (target) || continues (target) || returns (target))
13667 : {
13668 108 : *jump_target = *target;
13669 108 : return true;
13670 : }
13671 20 : if (TREE_CODE (*target) == LABEL_DECL && DECL_ARTIFICIAL (*target))
13672 : /* The user didn't write this goto, this isn't the problem. */
13673 : return true;
13674 16 : if (flags & tf_error)
13675 3 : constexpr_error (loc, fundef_p, "%<goto%> is not a constant "
13676 : "expression");
13677 : return false;
13678 : }
13679 :
13680 : case ASSERTION_STMT:
13681 : case PRECONDITION_STMT:
13682 : case POSTCONDITION_STMT:
13683 : /* Contracts are not supposed to alter this; we have to check that this
13684 : is not violated at a later time. */
13685 : return true;
13686 :
13687 228 : case LABEL_EXPR:
13688 228 : t = LABEL_EXPR_LABEL (t);
13689 228 : if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
13690 : return true;
13691 25 : else if (flags & tf_error)
13692 5 : constexpr_error (loc, fundef_p, "label definition in %<constexpr%> "
13693 : "function only available with %<-std=c++23%> or "
13694 : "%<-std=gnu++23%>");
13695 : return false;
13696 :
13697 10332 : case ANNOTATE_EXPR:
13698 10332 : return RECUR (TREE_OPERAND (t, 0), rval);
13699 :
13700 189003 : case BIT_CAST_EXPR:
13701 189003 : return RECUR (TREE_OPERAND (t, 0), rval);
13702 :
13703 : /* Coroutine await, yield and return expressions are not. */
13704 768 : case CO_AWAIT_EXPR:
13705 768 : case CO_YIELD_EXPR:
13706 768 : case CO_RETURN_EXPR:
13707 768 : case TEMPLATE_FOR_STMT:
13708 768 : if (flags & tf_error)
13709 3 : constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p,
13710 : "%qE is not a constant expression", t);
13711 : return false;
13712 :
13713 : /* Assume a TU-local entity is not constant, we'll error later when
13714 : instantiating. */
13715 : case TU_LOCAL_ENTITY:
13716 : return false;
13717 :
13718 : /* A splice expression is dependent, but will be constant after
13719 : substitution. */
13720 : case SPLICE_EXPR:
13721 : return true;
13722 :
13723 30 : case NONTYPE_ARGUMENT_PACK:
13724 30 : {
13725 30 : tree args = ARGUMENT_PACK_ARGS (t);
13726 30 : int len = TREE_VEC_LENGTH (args);
13727 90 : for (int i = 0; i < len; ++i)
13728 60 : if (!RECUR (TREE_VEC_ELT (args, i), any))
13729 : return false;
13730 : return true;
13731 : }
13732 :
13733 0 : default:
13734 0 : if (objc_non_constant_expr_p (t))
13735 : return false;
13736 :
13737 0 : sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
13738 0 : gcc_unreachable ();
13739 : return false;
13740 : }
13741 : #undef RECUR
13742 4983374608 : }
13743 :
13744 : bool
13745 1781799763 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
13746 : bool fundef_p, tsubst_flags_t flags)
13747 : {
13748 1781799763 : if (flags & tf_error)
13749 : {
13750 : /* Check potentiality quietly first, as that could be performed more
13751 : efficiently in some cases (currently only for TRUTH_*_EXPR). If
13752 : that fails, replay the check noisily to give errors. */
13753 11296702 : flags &= ~tf_error;
13754 11296702 : if (potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13755 : flags))
13756 : return true;
13757 1095 : flags |= tf_error;
13758 : }
13759 :
13760 1770504156 : tree target = NULL_TREE;
13761 1770504156 : return potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13762 1770504156 : flags, &target);
13763 : }
13764 :
13765 : /* The main entry point to the above. */
13766 :
13767 : bool
13768 450134614 : potential_constant_expression (tree t)
13769 : {
13770 450134614 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13771 : /*now*/false, /*fundef_p*/false,
13772 450134614 : tf_none);
13773 : }
13774 :
13775 : /* As above, but require a constant rvalue. */
13776 :
13777 : bool
13778 35834489 : potential_rvalue_constant_expression (tree t)
13779 : {
13780 35834489 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13781 : /*now*/false, /*fundef_p*/false,
13782 35834489 : tf_none);
13783 : }
13784 :
13785 : /* Like above, but complain about non-constant expressions. */
13786 :
13787 : bool
13788 88 : require_potential_constant_expression (tree t)
13789 : {
13790 88 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13791 : /*now*/false, /*fundef_p*/false,
13792 88 : tf_warning_or_error);
13793 : }
13794 :
13795 : /* Cross product of the above. */
13796 :
13797 : bool
13798 133301 : require_potential_rvalue_constant_expression (tree t)
13799 : {
13800 133301 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13801 : /*now*/false, /*fundef_p*/false,
13802 133301 : tf_warning_or_error);
13803 : }
13804 :
13805 : /* Like require_potential_rvalue_constant_expression, but fundef_p is true. */
13806 :
13807 : bool
13808 296 : require_potential_rvalue_constant_expression_fncheck (tree t)
13809 : {
13810 296 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13811 : /*now*/false, /*fundef_p*/true,
13812 296 : tf_warning_or_error);
13813 : }
13814 :
13815 : /* Like above, but don't consider PARM_DECL a potential_constant_expression. */
13816 :
13817 : bool
13818 1143 : require_rvalue_constant_expression (tree t)
13819 : {
13820 1143 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13821 : /*now*/true, /*fundef_p*/false,
13822 1143 : tf_warning_or_error);
13823 : }
13824 :
13825 : /* Like potential_constant_expression, but don't consider possible constexpr
13826 : substitution of the current function. That is, PARM_DECL qualifies under
13827 : potential_constant_expression, but not here.
13828 :
13829 : This is basically what you can check when any actual constant values might
13830 : be value-dependent. */
13831 :
13832 : bool
13833 938711146 : is_constant_expression (tree t)
13834 : {
13835 938711146 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13836 : /*now*/true, /*fundef_p*/false,
13837 938711146 : tf_none);
13838 : }
13839 :
13840 : /* As above, but expect an rvalue. */
13841 :
13842 : bool
13843 158169236 : is_rvalue_constant_expression (tree t)
13844 : {
13845 158169236 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13846 : /*now*/true, /*fundef_p*/false,
13847 158169236 : tf_none);
13848 : }
13849 :
13850 : /* Like above, but complain about non-constant expressions. */
13851 :
13852 : bool
13853 11161874 : require_constant_expression (tree t)
13854 : {
13855 11161874 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13856 : /*now*/true, /*fundef_p*/false,
13857 11161874 : tf_warning_or_error);
13858 : }
13859 :
13860 : /* Like is_constant_expression, but allow const variables that are not allowed
13861 : under constexpr rules. */
13862 :
13863 : bool
13864 176356874 : is_static_init_expression (tree t)
13865 : {
13866 176356874 : return potential_constant_expression_1 (t, /*want_rval*/false,
13867 : /*strict*/false, /*now*/true,
13868 176356874 : /*fundef_p*/false, tf_none);
13869 : }
13870 :
13871 : /* Returns true if T is a potential constant expression that is not
13872 : instantiation-dependent, and therefore a candidate for constant folding even
13873 : in a template. */
13874 :
13875 : bool
13876 906619803 : is_nondependent_constant_expression (tree t)
13877 : {
13878 906619803 : return (!type_unknown_p (t)
13879 906619753 : && is_constant_expression (t)
13880 1701564722 : && !instantiation_dependent_expression_p (t));
13881 : }
13882 :
13883 : /* Returns true if T is a potential static initializer expression that is not
13884 : instantiation-dependent. */
13885 :
13886 : bool
13887 176356874 : is_nondependent_static_init_expression (tree t)
13888 : {
13889 176356874 : return (!type_unknown_p (t)
13890 176356874 : && is_static_init_expression (t)
13891 318906668 : && !instantiation_dependent_expression_p (t));
13892 : }
13893 :
13894 : /* True iff FN is an implicitly constexpr function. */
13895 :
13896 : bool
13897 466289 : decl_implicit_constexpr_p (tree fn)
13898 : {
13899 466289 : if (!(flag_implicit_constexpr
13900 3 : && TREE_CODE (fn) == FUNCTION_DECL
13901 3 : && DECL_DECLARED_CONSTEXPR_P (fn)))
13902 : return false;
13903 :
13904 3 : if (DECL_CLONED_FUNCTION_P (fn))
13905 0 : fn = DECL_CLONED_FUNCTION (fn);
13906 :
13907 3 : return (DECL_LANG_SPECIFIC (fn)
13908 3 : && DECL_LANG_SPECIFIC (fn)->u.fn.implicit_constexpr);
13909 : }
13910 :
13911 : /* Finalize constexpr processing after parsing. */
13912 :
13913 : void
13914 99773 : fini_constexpr (void)
13915 : {
13916 : /* The contexpr call and fundef copies tables are no longer needed. */
13917 99773 : constexpr_call_table = NULL;
13918 99773 : fundef_copies_table = NULL;
13919 99773 : }
13920 :
13921 : #include "gt-cp-constexpr.h"
|