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 195703438 : is_instantiation_of_constexpr (tree fun)
62 : {
63 271107931 : return ((DECL_TEMPLOID_INSTANTIATION (fun)
64 120795107 : && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
65 290888135 : || (DECL_DEFAULTED_FN (fun)
66 0 : && DECL_DECLARED_CONSTEXPR_P (fun)));
67 : }
68 :
69 : /* Return true if T is a literal type. */
70 :
71 : bool
72 195255477 : literal_type_p (tree t)
73 : {
74 196913746 : if (SCALAR_TYPE_P (t)
75 92375945 : || VECTOR_TYPE_P (t)
76 92344292 : || TYPE_REF_P (t)
77 76553626 : || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
78 : return true;
79 73252860 : if (CLASS_TYPE_P (t))
80 : {
81 71594379 : t = complete_type (t);
82 71594379 : gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
83 71594379 : return CLASSTYPE_LITERAL_P (t);
84 : }
85 1658481 : if (TREE_CODE (t) == ARRAY_TYPE)
86 1658269 : 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 339903893 : ensure_literal_type_for_constexpr_object (tree decl)
96 : {
97 339903893 : tree type = TREE_TYPE (decl);
98 339903893 : if (VAR_P (decl)
99 128322615 : && (DECL_DECLARED_CONSTEXPR_P (decl)
100 89518204 : || var_in_constexpr_fn (decl))
101 398421125 : && !processing_template_decl)
102 : {
103 37979109 : tree stype = strip_array_types (type);
104 37979109 : 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 37979103 : else if (!literal_type_p (type))
108 : {
109 24251 : 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 24198 : else if (cxx_dialect < cxx23)
119 : {
120 18410 : 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 18410 : cp_function_chain->invalid_constexpr = true;
131 : }
132 : }
133 37954852 : else if (DECL_DECLARED_CONSTEXPR_P (decl)
134 37954852 : && 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 339903893 : 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 1044 : constexpr_error (location_t location, bool constexpr_fundef_p,
155 : const char *gmsgid, ...)
156 : {
157 1044 : diagnostics::diagnostic_info diagnostic;
158 1044 : va_list ap;
159 1044 : rich_location richloc (line_table, location);
160 1044 : va_start (ap, gmsgid);
161 1044 : bool ret;
162 1044 : if (!constexpr_fundef_p)
163 : {
164 : /* Report an error that cannot be suppressed. */
165 742 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
166 : diagnostics::kind::error);
167 742 : ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
168 : }
169 302 : 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 1044 : va_end (ap);
181 2088 : return ret;
182 1044 : }
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 993736864 : constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
201 : const constexpr_fundef *rhs)
202 : {
203 965814735 : 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 962568515 : constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
211 : {
212 962568515 : return DECL_UID (fundef->decl);
213 : }
214 :
215 : /* Return a previously saved definition of function FUN. */
216 :
217 : constexpr_fundef *
218 110731273 : retrieve_constexpr_fundef (tree fun)
219 : {
220 110731273 : if (constexpr_fundef_table == NULL)
221 : return NULL;
222 :
223 110727237 : constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
224 110727237 : 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 32016796 : is_valid_constexpr_fn (tree fun, bool complain)
232 : {
233 32016796 : bool ret = true;
234 :
235 64033592 : if (DECL_INHERITED_CTOR (fun)
236 3713215 : && 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 32016796 : for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
246 64670445 : parm != NULL_TREE; parm = TREE_CHAIN (parm))
247 32653649 : if (!literal_type_p (TREE_TYPE (parm)))
248 : {
249 13017 : ret = false;
250 13017 : 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 53093974 : 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 64033584 : 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 32016792 : else if (!DECL_CONSTRUCTOR_P (fun) && !DECL_DESTRUCTOR_P (fun))
278 : {
279 27622837 : tree rettype = TREE_TYPE (TREE_TYPE (fun));
280 27622837 : if (!literal_type_p (rettype))
281 : {
282 50918 : ret = false;
283 50918 : 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 27622837 : if (cxx_dialect < cxx14
295 32976 : && DECL_IOBJ_MEMBER_FUNCTION_P (fun)
296 27623960 : && !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 4393955 : 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 32016796 : 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 4571 : 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 4571 : auto_vec<tree, 2> fields;
344 9238 : do
345 : {
346 9238 : fields.safe_push (TREE_OPERAND (member, 1));
347 9238 : member = TREE_OPERAND (member, 0);
348 : }
349 9238 : while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
350 18482 : && 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 9238 : while (field = fields.pop(),
357 9238 : ANON_AGGR_TYPE_P (TREE_TYPE (field)))
358 : {
359 4667 : tree ctor;
360 : /* If there is already an outer constructor entry for the anonymous
361 : aggregate FIELD, use it; otherwise, insert one. */
362 4667 : if (vec_safe_is_empty (*vec)
363 198 : || (*vec)->last().index != field)
364 : {
365 4565 : ctor = build_constructor (TREE_TYPE (field), NULL);
366 4565 : CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
367 : }
368 : else
369 102 : ctor = (*vec)->last().value;
370 4667 : 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 4571 : gcc_assert (fields.is_empty());
376 4571 : CONSTRUCTOR_APPEND_ELT (*vec, field, init);
377 :
378 4571 : return true;
379 4571 : }
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 6142078 : build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
389 : {
390 6857000 : tree member, init;
391 6857000 : if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
392 3127638 : t = TREE_OPERAND (t, 0);
393 6857000 : if (TREE_CODE (t) == EXPR_STMT)
394 3126424 : t = TREE_OPERAND (t, 0);
395 6857000 : if (t == error_mark_node)
396 : return false;
397 6856991 : if (TREE_CODE (t) == STATEMENT_LIST)
398 : {
399 1619255 : for (tree stmt : tsi_range (t))
400 909229 : if (! build_data_member_initialization (stmt, vec))
401 6142078 : return false;
402 : return true;
403 : }
404 6146965 : 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 680686 : return build_data_member_initialization (CLEANUP_BODY (t), vec);
412 : }
413 5466279 : if (TREE_CODE (t) == CONVERT_EXPR)
414 3050538 : t = TREE_OPERAND (t, 0);
415 5466279 : if (TREE_CODE (t) == INIT_EXPR)
416 : {
417 2904171 : member = TREE_OPERAND (t, 0);
418 2904171 : init = break_out_target_exprs (TREE_OPERAND (t, 1));
419 : }
420 2562108 : else if (TREE_CODE (t) == CALL_EXPR)
421 : {
422 2083663 : tree fn = get_callee_fndecl (t);
423 4167326 : if (!fn || !DECL_CONSTRUCTOR_P (fn))
424 : /* We're only interested in calls to subobject constructors. */
425 : return true;
426 1670025 : 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 1670025 : init = break_out_target_exprs (t);
431 : }
432 478445 : else if (TREE_CODE (t) == BIND_EXPR)
433 34236 : 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 4574196 : if (INDIRECT_REF_P (member))
438 61848 : member = TREE_OPERAND (member, 0);
439 4574196 : if (TREE_CODE (member) == NOP_EXPR)
440 : {
441 565104 : tree op = member;
442 565104 : STRIP_NOPS (op);
443 565104 : if (TREE_CODE (op) == ADDR_EXPR)
444 : {
445 688 : 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 564416 : else if (op == current_class_ptr
453 1128681 : && (same_type_ignoring_top_level_qualifiers_p
454 564265 : (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 486578 : gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
463 : }
464 : }
465 4574196 : if (TREE_CODE (member) == ADDR_EXPR)
466 1167457 : member = TREE_OPERAND (member, 0);
467 4574196 : if (TREE_CODE (member) == COMPONENT_REF)
468 : {
469 3983895 : tree aggr = TREE_OPERAND (member, 0);
470 3983895 : if (TREE_CODE (aggr) == VAR_DECL)
471 : /* Initializing a local variable, don't add anything. */
472 : return true;
473 3983893 : if (TREE_CODE (aggr) != COMPONENT_REF)
474 : /* Normal member initialization. */
475 3979319 : member = TREE_OPERAND (member, 1);
476 4574 : else if (VAR_P (get_base_address (aggr)))
477 : /* Initializing a local variable, don't add anything. */
478 : return true;
479 4571 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
480 : /* Initializing a member of an anonymous union. */
481 4571 : 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 5704732 : if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
491 80 : (*vec)->last().value = init;
492 : else
493 4569540 : 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 2402 : check_constexpr_bind_expr_vars (tree t)
503 : {
504 2402 : gcc_assert (TREE_CODE (t) == BIND_EXPR);
505 :
506 3240 : 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 4137 : check_constexpr_ctor_body_1 (tree last, tree list)
518 : {
519 4137 : 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 2059 : case BIND_EXPR:
532 2059 : if (!check_constexpr_bind_expr_vars (list)
533 2059 : || !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 6078297 : 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 6078297 : if (cxx_dialect >= cxx14)
556 : return true;
557 :
558 13845 : bool ok = true;
559 13845 : if (TREE_CODE (list) == STATEMENT_LIST)
560 : {
561 13817 : tree_stmt_iterator i = tsi_last (list);
562 17855 : for (; !tsi_end_p (i); tsi_prev (&i))
563 : {
564 15727 : tree t = tsi_stmt (i);
565 15727 : if (t == last)
566 : break;
567 4109 : if (!check_constexpr_ctor_body_1 (last, t))
568 : {
569 : ok = false;
570 : break;
571 : }
572 : }
573 : }
574 28 : else if (list != last
575 28 : && !check_constexpr_ctor_body_1 (last, list))
576 : ok = false;
577 13845 : 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 3634557 : sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
594 : {
595 3634557 : tree pri = CLASSTYPE_PRIMARY_BINFO (type);
596 3634557 : tree field_type;
597 3634557 : unsigned i;
598 3634557 : constructor_elt *ce;
599 :
600 3634557 : if (pri)
601 89717 : field_type = BINFO_TYPE (pri);
602 3544840 : else if (TYPE_CONTAINS_VPTR_P (type))
603 37816 : 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 169403 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
610 131463 : if (TREE_TYPE (ce->index) == field_type)
611 : break;
612 :
613 149878 : if (i > 0 && i < vec_safe_length (v))
614 : {
615 28 : vec<constructor_elt, va_gc> &vref = *v;
616 28 : constructor_elt elt = vref[i];
617 56 : for (; i > 0; --i)
618 28 : vref[i] = vref[i-1];
619 28 : 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 3712352 : build_constexpr_constructor_member_initializers (tree type, tree body)
630 : {
631 3712352 : vec<constructor_elt, va_gc> *vec = NULL;
632 3712352 : bool ok = true;
633 5791806 : while (true)
634 5791806 : switch (TREE_CODE (body))
635 : {
636 2079375 : case MUST_NOT_THROW_EXPR:
637 2079375 : case EH_SPEC_BLOCK:
638 2079375 : case TRY_FINALLY_EXPR: // For C++26 postconditions.
639 2079375 : body = TREE_OPERAND (body, 0);
640 2079375 : break;
641 :
642 79 : case STATEMENT_LIST:
643 2079639 : 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 3712352 : case BIND_EXPR:
652 3712352 : body = BIND_EXPR_BODY (body);
653 3712352 : goto found;
654 :
655 0 : default:
656 0 : gcc_unreachable ();
657 : }
658 3712352 : found:
659 3712352 : 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 3712352 : if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
666 : {
667 2007508 : body = TREE_OPERAND (body, 0);
668 2007508 : if (TREE_CODE (body) == EXPR_STMT)
669 2007472 : body = TREE_OPERAND (body, 0);
670 2007508 : if (TREE_CODE (body) == INIT_EXPR
671 2007508 : && (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 2007508 : ok = build_data_member_initialization (body, &vec);
679 : }
680 1704844 : else if (TREE_CODE (body) == STATEMENT_LIST)
681 : {
682 4919296 : for (tree stmt : tsi_range (body))
683 : {
684 3219897 : ok = build_data_member_initialization (stmt, &vec);
685 3219897 : if (!ok)
686 : break;
687 : }
688 : }
689 5444 : else if (EXPR_P (body))
690 5444 : ok = build_data_member_initialization (body, &vec);
691 : else
692 0 : gcc_assert (errorcount > 0);
693 3712352 : if (ok)
694 : {
695 3712343 : if (vec_safe_length (vec) > 0)
696 : {
697 : /* In a delegating constructor, return the target. */
698 3438953 : constructor_elt *ce = &(*vec)[0];
699 3438953 : if (ce->index == current_class_ptr)
700 : {
701 77786 : body = ce->value;
702 77786 : vec_free (vec);
703 77786 : return body;
704 : }
705 : }
706 3634557 : vec = sort_constexpr_mem_initializers (type, vec);
707 3634557 : 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 567618407 : get_function_named_in_call (tree t)
719 : {
720 567618407 : tree callee = cp_get_callee (t);
721 567618407 : tree fun = cp_get_fndecl_from_callee (callee, /*fold*/false);
722 567618407 : 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 70609 : constexpr_fn_retval (tree body)
732 : {
733 77425 : 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 33030 : case RETURN_EXPR:
755 33030 : 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 31302833 : massage_constexpr_body (tree fun, tree body)
799 : {
800 62605666 : if (DECL_CONSTRUCTOR_P (fun))
801 3712352 : body = build_constexpr_constructor_member_initializers
802 3712352 : (DECL_CONTEXT (fun), body);
803 27590481 : else if (cxx_dialect < cxx14)
804 : {
805 32845 : if (TREE_CODE (body) == EH_SPEC_BLOCK)
806 1 : body = EH_SPEC_STMTS (body);
807 32845 : if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
808 21455 : body = TREE_OPERAND (body, 0);
809 32845 : body = constexpr_fn_retval (body);
810 : }
811 31302833 : 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 3363958 : cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
819 : {
820 : /* We allow uninitialized bases/fields in C++20. */
821 3363958 : if (cxx_dialect >= cxx20)
822 : return false;
823 :
824 13698 : unsigned nelts = 0;
825 :
826 13698 : if (body)
827 : {
828 13694 : if (TREE_CODE (body) != CONSTRUCTOR)
829 : return false;
830 13641 : nelts = CONSTRUCTOR_NELTS (body);
831 : }
832 13645 : tree field = TYPE_FIELDS (ctype);
833 :
834 13645 : 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 28790 : for (unsigned i = 0; i <= nelts; ++i)
850 : {
851 28790 : tree index = NULL_TREE;
852 28790 : if (i < nelts)
853 : {
854 15255 : index = CONSTRUCTOR_ELT (body, i)->index;
855 : /* Skip vptr adjustment represented with a COMPONENT_REF. */
856 15255 : if (TREE_CODE (index) != FIELD_DECL)
857 627 : continue;
858 : }
859 :
860 497916 : for (; field != index; field = DECL_CHAIN (field))
861 : {
862 469759 : tree ftype;
863 469759 : if (TREE_CODE (field) != FIELD_DECL)
864 469731 : 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 28157 : if (field == NULL_TREE)
906 : break;
907 :
908 14628 : 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 14628 : 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 168707711 : maybe_save_constexpr_fundef (tree fun)
928 : {
929 168707711 : if (processing_template_decl
930 69777739 : || cp_function_chain->invalid_constexpr
931 238467149 : || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
932 137405172 : 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 53346698 : bool implicit = false;
937 53346698 : 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 53346698 : if (!DECL_DECLARED_CONSTEXPR_P (fun) && !implicit)
952 : return;
953 :
954 31358461 : bool complain = !DECL_GENERATED_P (fun) && !implicit;
955 :
956 31358461 : if (!is_valid_constexpr_fn (fun, complain))
957 : return;
958 :
959 31302753 : tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
960 31302753 : 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 31302717 : bool potential = potential_rvalue_constant_expression (massaged);
969 31302717 : if (!potential && complain)
970 258 : require_potential_rvalue_constant_expression_fncheck (massaged);
971 :
972 35015046 : if (DECL_CONSTRUCTOR_P (fun) && potential
973 35010988 : && !DECL_DEFAULTED_FN (fun))
974 : {
975 3363902 : if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
976 : massaged, complain))
977 : potential = false;
978 3363876 : 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 3359045 : massaged = DECL_SAVED_TREE (fun);
983 3359045 : potential = potential_rvalue_constant_expression (massaged);
984 3359045 : if (!potential && complain)
985 20 : require_potential_rvalue_constant_expression_fncheck (massaged);
986 : }
987 : }
988 :
989 31302717 : 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 298 : && warn_invalid_constexpr != 0)
995 : return;
996 :
997 31302550 : 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 31302539 : constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
1013 31302539 : bool clear_ctx = false;
1014 31302539 : if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
1015 : {
1016 31302539 : clear_ctx = true;
1017 31302539 : DECL_CONTEXT (DECL_RESULT (fun)) = fun;
1018 : }
1019 31302539 : tree saved_fn = current_function_decl;
1020 31302539 : current_function_decl = fun;
1021 31302539 : entry.body = copy_fn (entry.decl, entry.parms, entry.result);
1022 31302539 : current_function_decl = saved_fn;
1023 31302539 : if (clear_ctx)
1024 31302539 : DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
1025 31302539 : 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 61049 : entry.result = error_mark_node;
1030 :
1031 31302539 : 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 31340865 : register_constexpr_fundef (const constexpr_fundef &value)
1039 : {
1040 : /* Create the constexpr function table if necessary. */
1041 31340865 : if (constexpr_fundef_table == NULL)
1042 27792 : constexpr_fundef_table
1043 27792 : = hash_table<constexpr_fundef_hasher>::create_ggc (101);
1044 :
1045 31340865 : constexpr_fundef **slot = constexpr_fundef_table->find_slot
1046 31340865 : (const_cast<constexpr_fundef *> (&value), INSERT);
1047 :
1048 31340865 : gcc_assert (*slot == NULL);
1049 31340865 : *slot = ggc_alloc<constexpr_fundef> ();
1050 31340865 : **slot = value;
1051 31340865 : }
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 65160434 : 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 578608694 : constexpr_global_ctx ()
1238 578608694 : : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
1239 578608694 : consteval_block (NULL_TREE), heap_dealloc_count (0),
1240 578608694 : uncaught_exceptions (0), contract_statement (NULL_TREE),
1241 578608694 : contract_condition_non_const (false), state_dependent (false) {}
1242 :
1243 464856333 : bool is_outside_lifetime (tree t)
1244 : {
1245 464856333 : if (tree *p = values.get (t))
1246 209226804 : if (*p == void_node || *p == void_list_node)
1247 268 : return true;
1248 : return false;
1249 : }
1250 588075610 : tree get_value (tree t)
1251 : {
1252 588075610 : if (tree *p = values.get (t))
1253 307791354 : if (*p != void_node && *p != void_list_node)
1254 299586122 : return *p;
1255 : return NULL_TREE;
1256 : }
1257 4326 : tree *get_raw_value_ptr (tree t)
1258 : {
1259 4326 : return values.get (t);
1260 : }
1261 125185547 : tree *get_value_ptr (tree t, bool initializing)
1262 : {
1263 125185547 : if (modifiable && !modifiable->contains (t))
1264 : return nullptr;
1265 125185536 : if (tree *p = values.get (t))
1266 : {
1267 125176009 : 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 302303150 : void put_value (tree t, tree v)
1278 : {
1279 302303150 : bool already_in_map = values.put (t, v);
1280 302303150 : if (!already_in_map && modifiable)
1281 30 : modifiable->add (t);
1282 302303150 : }
1283 242185419 : void destroy_value (tree t, bool past_storage_end = true)
1284 : {
1285 242185419 : if (TREE_CODE (t) == VAR_DECL
1286 242185419 : || TREE_CODE (t) == PARM_DECL
1287 : || TREE_CODE (t) == RESULT_DECL)
1288 242479969 : values.put (t, past_storage_end ? void_list_node : void_node);
1289 : else
1290 9261 : values.remove (t);
1291 242185419 : }
1292 19298716 : void clear_value (tree t)
1293 : {
1294 38597432 : values.remove (t);
1295 : }
1296 : };
1297 :
1298 : /* Helper class for constexpr_global_ctx. In some cases we want to avoid
1299 : side-effects from evaluation of a particular subexpression of a
1300 : constant-expression. In such cases we use modifiable_tracker to prevent
1301 : modification of variables created outside of that subexpression.
1302 :
1303 : ??? We could change the hash_set to a hash_map, allow and track external
1304 : modifications, and roll them back in the destructor. It's not clear to me
1305 : that this would be worthwhile. */
1306 :
1307 : class modifiable_tracker
1308 : {
1309 : hash_set<tree> set;
1310 : constexpr_global_ctx *global;
1311 : public:
1312 173601 : modifiable_tracker (constexpr_global_ctx *g): global(g)
1313 : {
1314 173601 : global->modifiable = &set;
1315 173601 : }
1316 173601 : ~modifiable_tracker ()
1317 : {
1318 173631 : for (tree t: set)
1319 30 : global->clear_value (t);
1320 173601 : global->modifiable = nullptr;
1321 173601 : }
1322 : };
1323 :
1324 : /* The constexpr expansion context. CALL is the current function
1325 : expansion, CTOR is the current aggregate initializer, OBJECT is the
1326 : object being initialized by CTOR, either a VAR_DECL or a _REF. */
1327 :
1328 : struct constexpr_ctx {
1329 : /* The part of the context that needs to be unique to the whole
1330 : cxx_eval_outermost_constant_expr invocation. */
1331 : constexpr_global_ctx *global;
1332 : /* The innermost call we're evaluating. */
1333 : constexpr_call *call;
1334 : /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen
1335 : within the current LOOP_EXPR. NULL if we aren't inside a loop. */
1336 : vec<tree> *save_exprs;
1337 : /* The CONSTRUCTOR we're currently building up for an aggregate
1338 : initializer. */
1339 : tree ctor;
1340 : /* The object we're building the CONSTRUCTOR for. */
1341 : tree object;
1342 : /* If inside SWITCH_EXPR. */
1343 : constexpr_switch_state *css_state;
1344 : /* The aggregate initialization context inside which this one is nested. This
1345 : is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs. */
1346 : const constexpr_ctx *parent;
1347 :
1348 : /* Whether we should error on a non-constant expression or fail quietly.
1349 : This flag needs to be here, but some of the others could move to global
1350 : if they get larger than a word. */
1351 : bool quiet;
1352 : /* Whether we are strictly conforming to constant expression rules or
1353 : trying harder to get a constant value. */
1354 : bool strict;
1355 : /* Whether __builtin_is_constant_evaluated () should be true. */
1356 : mce_value manifestly_const_eval;
1357 : };
1358 :
1359 : /* Return ctx->quiet. For use in reflect.cc. */
1360 :
1361 : bool
1362 1376 : cxx_constexpr_quiet_p (const constexpr_ctx *ctx)
1363 : {
1364 1376 : return ctx->quiet;
1365 : }
1366 :
1367 : /* Return ctx->manifestly_const_eval. For use in reflect.cc. */
1368 :
1369 : mce_value
1370 400 : cxx_constexpr_manifestly_const_eval (const constexpr_ctx *ctx)
1371 : {
1372 400 : return ctx->manifestly_const_eval;
1373 : }
1374 :
1375 : /* Return ctx->call->fundef->decl or NULL_TREE. For use in
1376 : reflect.cc. */
1377 :
1378 : tree
1379 2128 : cxx_constexpr_caller (const constexpr_ctx *ctx)
1380 : {
1381 2128 : if (ctx->call)
1382 958 : return ctx->call->fundef->decl;
1383 : else
1384 : return NULL_TREE;
1385 : }
1386 :
1387 : /* Return ctx->global->consteval_block. For use in reflect.cc. */
1388 :
1389 : tree
1390 158 : cxx_constexpr_consteval_block (const constexpr_ctx *ctx)
1391 : {
1392 158 : return ctx->global->consteval_block;
1393 : }
1394 :
1395 : /* Predicates for the meaning of *jump_target. */
1396 :
1397 : static bool
1398 110837068 : returns (tree *jump_target)
1399 : {
1400 19440511 : return *jump_target && TREE_CODE (*jump_target) == RETURN_EXPR;
1401 : }
1402 :
1403 : static bool
1404 105239982 : breaks (tree *jump_target)
1405 : {
1406 105239982 : return (*jump_target
1407 105239982 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1408 339 : && LABEL_DECL_BREAK (*jump_target))
1409 1378512 : || TREE_CODE (*jump_target) == BREAK_STMT
1410 1239849 : || TREE_CODE (*jump_target) == EXIT_EXPR));
1411 : }
1412 :
1413 : static bool
1414 142204532 : continues (tree *jump_target)
1415 : {
1416 142204532 : return (*jump_target
1417 142204532 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1418 339 : && LABEL_DECL_CONTINUE (*jump_target))
1419 1255320 : || TREE_CODE (*jump_target) == CONTINUE_STMT));
1420 : }
1421 :
1422 : static bool
1423 12831777 : switches (tree *jump_target)
1424 : {
1425 78155 : return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST;
1426 : }
1427 :
1428 : static bool
1429 1921696652 : throws (tree *jump_target)
1430 : {
1431 : /* void_node is for use in potential_constant_expression_1, otherwise
1432 : it should an artificial VAR_DECL created by constant evaluation
1433 : of __cxa_allocate_exception (). */
1434 213138306 : return (*jump_target && (VAR_P (*jump_target) || *jump_target == void_node));
1435 : }
1436 :
1437 : /* True if the constexpr relaxations afforded by P2280R4 for unknown
1438 : references and objects are in effect. */
1439 :
1440 : static bool
1441 271198965 : p2280_active_p (const constexpr_ctx *ctx)
1442 : {
1443 34581288 : if (ctx->manifestly_const_eval != mce_true)
1444 : /* Disable these relaxations during speculative constexpr folding,
1445 : as it can significantly increase compile time/memory use
1446 : (PR119387). */
1447 : return false;
1448 :
1449 : /* P2280R4 was accepted as a DR against C++11. */
1450 0 : return cxx_dialect >= cxx11;
1451 : }
1452 :
1453 : /* Remove T from the global values map, checking for attempts to destroy
1454 : a value that has already finished its lifetime. */
1455 :
1456 : static void
1457 241797433 : destroy_value_checked (const constexpr_ctx* ctx, tree t, bool *non_constant_p)
1458 : {
1459 241797433 : if (t == error_mark_node || TREE_TYPE (t) == error_mark_node)
1460 : return;
1461 :
1462 : /* Don't error again here if we've already reported a problem. */
1463 241797372 : if (!*non_constant_p
1464 210434582 : && DECL_P (t)
1465 : /* Non-trivial destructors have their lifetimes ended explicitly
1466 : with a clobber, so don't worry about it here. */
1467 210425519 : && (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (t))
1468 : /* ...except parameters are remapped in cxx_eval_call_expression,
1469 : and the destructor call during cleanup won't be able to tell that
1470 : this value has already been destroyed, so complain now. This is
1471 : not quite unobservable, but is extremely unlikely to crop up in
1472 : practice; see g++.dg/cpp2a/constexpr-lifetime2.C. */
1473 774710 : || TREE_CODE (t) == PARM_DECL)
1474 451449716 : && ctx->global->is_outside_lifetime (t))
1475 : {
1476 54 : if (!ctx->quiet)
1477 : {
1478 18 : auto_diagnostic_group d;
1479 18 : error ("destroying %qE outside its lifetime", t);
1480 18 : inform (DECL_SOURCE_LOCATION (t), "declared here");
1481 18 : }
1482 54 : *non_constant_p = true;
1483 : }
1484 241797372 : ctx->global->destroy_value (t);
1485 : }
1486 :
1487 : /* This internal flag controls whether we should avoid doing anything during
1488 : constexpr evaluation that would cause extra DECL_UID generation, such as
1489 : template instantiation and function body copying. */
1490 :
1491 : static bool uid_sensitive_constexpr_evaluation_value;
1492 :
1493 : /* An internal counter that keeps track of the number of times
1494 : uid_sensitive_constexpr_evaluation_p returned true. */
1495 :
1496 : static unsigned uid_sensitive_constexpr_evaluation_true_counter;
1497 :
1498 : /* The accessor for uid_sensitive_constexpr_evaluation_value which also
1499 : increments the corresponding counter. */
1500 :
1501 : static bool
1502 9094980 : uid_sensitive_constexpr_evaluation_p ()
1503 : {
1504 9007600 : if (uid_sensitive_constexpr_evaluation_value)
1505 : {
1506 244089 : ++uid_sensitive_constexpr_evaluation_true_counter;
1507 244080 : return true;
1508 : }
1509 : else
1510 : return false;
1511 : }
1512 :
1513 : /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel
1514 : enables the internal flag for uid_sensitive_constexpr_evaluation_p
1515 : during the lifetime of the sentinel object. Upon its destruction, the
1516 : previous value of uid_sensitive_constexpr_evaluation_p is restored. */
1517 :
1518 81518177 : uid_sensitive_constexpr_evaluation_sentinel
1519 : ::uid_sensitive_constexpr_evaluation_sentinel ()
1520 81518177 : : ovr (uid_sensitive_constexpr_evaluation_value, true)
1521 : {
1522 81518177 : }
1523 :
1524 : /* The default constructor for uid_sensitive_constexpr_evaluation_checker
1525 : records the current number of times that uid_sensitive_constexpr_evaluation_p
1526 : has been called and returned true. */
1527 :
1528 3877033947 : uid_sensitive_constexpr_evaluation_checker
1529 : ::uid_sensitive_constexpr_evaluation_checker ()
1530 3877033947 : : saved_counter (uid_sensitive_constexpr_evaluation_true_counter)
1531 : {
1532 3877033947 : }
1533 :
1534 : /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and
1535 : some constexpr evaluation was restricted due to u_s_c_e_p being called
1536 : and returning true during the lifetime of this checker object. */
1537 :
1538 : bool
1539 2571570293 : uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const
1540 : {
1541 2571570293 : return (uid_sensitive_constexpr_evaluation_value
1542 2571570293 : && saved_counter != uid_sensitive_constexpr_evaluation_true_counter);
1543 : }
1544 :
1545 :
1546 : /* A table of all constexpr calls that have been evaluated by the
1547 : compiler in this translation unit. */
1548 :
1549 : static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
1550 :
1551 : /* Compute a hash value for a constexpr call representation. */
1552 :
1553 : inline hashval_t
1554 225615553 : constexpr_call_hasher::hash (constexpr_call *info)
1555 : {
1556 225615553 : return info->hash;
1557 : }
1558 :
1559 : /* Return true if the objects pointed to by P and Q represent calls
1560 : to the same constexpr function with the same arguments.
1561 : Otherwise, return false. */
1562 :
1563 : bool
1564 234295023 : constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
1565 : {
1566 234295023 : if (lhs == rhs)
1567 : return true;
1568 234295023 : if (lhs->hash != rhs->hash)
1569 : return false;
1570 27922129 : if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
1571 : return false;
1572 27922129 : return cp_tree_equal (lhs->bindings, rhs->bindings);
1573 : }
1574 :
1575 : /* Initialize the constexpr call table, if needed. */
1576 :
1577 : static void
1578 36959086 : maybe_initialize_constexpr_call_table (void)
1579 : {
1580 36959086 : if (constexpr_call_table == NULL)
1581 18748 : constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
1582 36959086 : }
1583 :
1584 : /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
1585 : a function happens to get called recursively, we unshare the callee
1586 : function's body and evaluate this unshared copy instead of evaluating the
1587 : original body.
1588 :
1589 : FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function
1590 : copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map
1591 : that's keyed off of the original FUNCTION_DECL and whose value is a
1592 : TREE_LIST of this function's unused copies awaiting reuse.
1593 :
1594 : This is not GC-deletable to avoid GC affecting UID generation. */
1595 :
1596 : static GTY(()) decl_tree_map *fundef_copies_table;
1597 :
1598 : /* Reuse a copy or create a new unshared copy of the function FUN.
1599 : Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE
1600 : is parms, TYPE is result. */
1601 :
1602 : static tree
1603 86767136 : get_fundef_copy (constexpr_fundef *fundef)
1604 : {
1605 86767136 : tree copy;
1606 86767136 : bool existed;
1607 86767136 : tree *slot = &(hash_map_safe_get_or_insert<hm_ggc>
1608 86767136 : (fundef_copies_table, fundef->decl, &existed, 127));
1609 :
1610 86767136 : if (!existed)
1611 : {
1612 : /* There is no cached function available, or in use. We can use
1613 : the function directly. That the slot is now created records
1614 : that this function is now in use. */
1615 7634079 : copy = build_tree_list (fundef->body, fundef->parms);
1616 7634079 : TREE_TYPE (copy) = fundef->result;
1617 : }
1618 79133057 : else if (*slot == NULL_TREE)
1619 : {
1620 4438 : if (uid_sensitive_constexpr_evaluation_p ())
1621 9 : return NULL_TREE;
1622 :
1623 : /* We've already used the function itself, so make a copy. */
1624 4429 : copy = build_tree_list (NULL, NULL);
1625 4429 : tree saved_body = DECL_SAVED_TREE (fundef->decl);
1626 4429 : tree saved_parms = DECL_ARGUMENTS (fundef->decl);
1627 4429 : tree saved_result = DECL_RESULT (fundef->decl);
1628 4429 : tree saved_fn = current_function_decl;
1629 4429 : DECL_SAVED_TREE (fundef->decl) = fundef->body;
1630 4429 : DECL_ARGUMENTS (fundef->decl) = fundef->parms;
1631 4429 : DECL_RESULT (fundef->decl) = fundef->result;
1632 4429 : current_function_decl = fundef->decl;
1633 4429 : TREE_PURPOSE (copy) = copy_fn (fundef->decl, TREE_VALUE (copy),
1634 4429 : TREE_TYPE (copy));
1635 4429 : current_function_decl = saved_fn;
1636 4429 : DECL_RESULT (fundef->decl) = saved_result;
1637 4429 : DECL_ARGUMENTS (fundef->decl) = saved_parms;
1638 4429 : DECL_SAVED_TREE (fundef->decl) = saved_body;
1639 : }
1640 : else
1641 : {
1642 : /* We have a cached function available. */
1643 79128619 : copy = *slot;
1644 79128619 : *slot = TREE_CHAIN (copy);
1645 : }
1646 :
1647 : return copy;
1648 : }
1649 :
1650 : /* Save the copy COPY of function FUN for later reuse by
1651 : get_fundef_copy(). By construction, there will always be an entry
1652 : to find. */
1653 :
1654 : static void
1655 86767123 : save_fundef_copy (tree fun, tree copy)
1656 : {
1657 86767123 : tree *slot = fundef_copies_table->get (fun);
1658 86767123 : TREE_CHAIN (copy) = *slot;
1659 86767123 : *slot = copy;
1660 86767123 : }
1661 :
1662 : static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree,
1663 : value_cat, bool *, bool *, tree *);
1664 : static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree,
1665 : bool *, tree *);
1666 : static tree find_heap_var_refs (tree *, int *, void *);
1667 :
1668 : /* For exception object EXC if it has class type and usable what () method
1669 : which returns cv char * return the xmalloced string literal which it returns
1670 : if possible, otherwise return NULL. */
1671 :
1672 : static char *
1673 396 : exception_what_str (const constexpr_ctx *ctx, tree exc)
1674 : {
1675 396 : tree type = strip_array_types (TREE_TYPE (exc));
1676 396 : if (!CLASS_TYPE_P (type))
1677 : return NULL;
1678 340 : tree std_exception = lookup_qualified_name (std_node, "exception",
1679 : LOOK_want::NORMAL, false);
1680 340 : if (TREE_CODE (std_exception) != TYPE_DECL)
1681 : return NULL;
1682 334 : if (!CLASS_TYPE_P (TREE_TYPE (std_exception)))
1683 : return NULL;
1684 334 : base_kind b_kind;
1685 334 : tree binfo = lookup_base (type, TREE_TYPE (std_exception), ba_check, &b_kind,
1686 : tf_none);
1687 334 : if (binfo == NULL_TREE || binfo == error_mark_node)
1688 : return NULL;
1689 326 : if (type != TREE_TYPE (exc))
1690 288 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1691 326 : tree call
1692 326 : = finish_class_member_access_expr (exc, get_identifier ("what"), false,
1693 : tf_none);
1694 326 : if (call == error_mark_node)
1695 : return NULL;
1696 326 : releasing_vec what_args;
1697 326 : call = finish_call_expr (call, &what_args, false, false, tf_none);
1698 326 : if (call == error_mark_node)
1699 : return NULL;
1700 326 : if (TREE_CODE (TREE_TYPE (call)) != POINTER_TYPE
1701 326 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1702 326 : || !COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1703 326 : || !tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (call))),
1704 326 : TYPE_SIZE_UNIT (char_type_node))
1705 652 : || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (call))) != BITS_PER_UNIT)
1706 : return NULL;
1707 326 : if (!potential_constant_expression (call))
1708 : return NULL;
1709 326 : bool non_constant_p = false, overflow_p = false;
1710 326 : tree jmp_target = NULL;
1711 326 : tree ptr = cxx_eval_constant_expression (ctx, call, vc_prvalue,
1712 : &non_constant_p, &overflow_p,
1713 : &jmp_target);
1714 652 : if (throws (&jmp_target) || non_constant_p)
1715 : return NULL;
1716 326 : if (reduced_constant_expression_p (ptr))
1717 42 : if (const char *msg = c_getstr (ptr))
1718 42 : return xstrdup (msg);
1719 284 : auto_vec <char, 32> v;
1720 11754 : for (unsigned i = 0; i < INT_MAX; ++i)
1721 : {
1722 11754 : tree t = call;
1723 11754 : if (i)
1724 11470 : t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, size_int (i));
1725 11754 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
1726 11754 : non_constant_p = false;
1727 11754 : overflow_p = false;
1728 11754 : jmp_target = NULL;
1729 11754 : tree t2 = cxx_eval_constant_expression (ctx, t, vc_prvalue,
1730 : &non_constant_p, &overflow_p,
1731 : &jmp_target);
1732 11754 : if (throws (&jmp_target)
1733 11754 : || non_constant_p
1734 11754 : || !tree_fits_shwi_p (t2))
1735 0 : return NULL;
1736 11754 : char c = tree_to_shwi (t2);
1737 11754 : v.safe_push (c);
1738 11754 : if (c == '\0')
1739 : break;
1740 : }
1741 568 : return xstrdup (v.address ());
1742 610 : }
1743 :
1744 : /* Diagnose constant expression evaluation encountering call to
1745 : std::terminate due to exception EXC. */
1746 :
1747 : static void
1748 22 : diagnose_std_terminate (location_t loc, const constexpr_ctx *ctx, tree exc)
1749 : {
1750 22 : tree type = strip_array_types (TREE_TYPE (exc));
1751 22 : if (char *str = exception_what_str (ctx, exc))
1752 : {
1753 4 : error_at (loc, "%qs called after throwing an exception of type %qT; "
1754 : "%<what()%>: %qs", "std::terminate", type, str);
1755 4 : free (str);
1756 : }
1757 : else
1758 : {
1759 18 : if (type != TREE_TYPE (exc))
1760 18 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1761 18 : bool non_constant_p = false, overflow_p = false;
1762 18 : tree jmp_target = NULL;
1763 18 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1764 : &non_constant_p, &overflow_p,
1765 : &jmp_target);
1766 18 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1767 18 : if (reduced_constant_expression_p (val))
1768 18 : error_at (loc, "%qs called after throwing an exception %qE",
1769 : "std::terminate", val);
1770 : else
1771 0 : error_at (loc, "%qs called after throwing an exception of type %qT",
1772 : "std::terminate", type);
1773 : }
1774 22 : }
1775 :
1776 : /* Diagnose constant expression evaluation encountering call to
1777 : uncaught exception EXC. */
1778 :
1779 : static void
1780 374 : diagnose_uncaught_exception (location_t loc, const constexpr_ctx *ctx, tree exc)
1781 : {
1782 374 : tree type = strip_array_types (TREE_TYPE (exc));
1783 374 : if (char *str = exception_what_str (ctx, exc))
1784 : {
1785 322 : error_at (loc, "uncaught exception of type %qT; %<what()%>: %qs", type, str);
1786 322 : free (str);
1787 : }
1788 : else
1789 : {
1790 52 : if (type != TREE_TYPE (exc))
1791 52 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1792 52 : bool non_constant_p = false, overflow_p = false;
1793 52 : tree jmp_target = NULL;
1794 52 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1795 : &non_constant_p, &overflow_p,
1796 : &jmp_target);
1797 52 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1798 52 : if (reduced_constant_expression_p (val))
1799 50 : error_at (loc, "uncaught exception %qE", val);
1800 : else
1801 2 : error_at (loc, "uncaught exception of type %qT", type);
1802 : }
1803 374 : }
1804 :
1805 : /* Kinds of __cxa_* functions (and a few other EH related ones) we handle as
1806 : magic constexpr functions for C++26. */
1807 :
1808 : enum cxa_builtin {
1809 : CXA_NONE = 0,
1810 : CXA_ALLOCATE_EXCEPTION = 1,
1811 : CXA_FREE_EXCEPTION = 2,
1812 : CXA_THROW = 3,
1813 : CXA_BEGIN_CATCH = 4,
1814 : CXA_END_CATCH = 5,
1815 : CXA_RETHROW = 6,
1816 : CXA_GET_EXCEPTION_PTR = 7,
1817 : CXA_BAD_CAST = 8,
1818 : CXA_BAD_TYPEID = 9,
1819 : CXA_THROW_BAD_ARRAY_NEW_LENGTH = 10,
1820 : STD_RETHROW_EXCEPTION = 11,
1821 : BUILTIN_EH_PTR_ADJUST_REF = 12,
1822 : BUILTIN_UNCAUGHT_EXCEPTIONS = 13,
1823 : BUILTIN_CURRENT_EXCEPTION = 14
1824 : };
1825 :
1826 : /* Return cxa_builtin if FNDECL is a __cxa_* function handled as
1827 : magic constexpr function for C++26. Return CXA_NONE otherwise. */
1828 :
1829 : static enum cxa_builtin
1830 36922134 : cxx_cxa_builtin_fn_p (tree fndecl)
1831 : {
1832 36922134 : if (cxx_dialect < cxx26)
1833 : return CXA_NONE;
1834 3662375 : if (DECL_LANGUAGE (fndecl) != lang_c)
1835 : {
1836 3055422 : if (!decl_in_std_namespace_p (fndecl))
1837 : return CXA_NONE;
1838 1290489 : if (id_equal (DECL_NAME (fndecl), "rethrow_exception"))
1839 : return STD_RETHROW_EXCEPTION;
1840 1290447 : return CXA_NONE;
1841 : }
1842 606953 : if (!startswith (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__cxa_"))
1843 : return CXA_NONE;
1844 81315 : if (id_equal (DECL_NAME (fndecl), "__cxa_allocate_exception"))
1845 : return CXA_ALLOCATE_EXCEPTION;
1846 25415 : if (id_equal (DECL_NAME (fndecl), "__cxa_free_exception"))
1847 : return CXA_FREE_EXCEPTION;
1848 25413 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw"))
1849 : return CXA_THROW;
1850 16088 : if (id_equal (DECL_NAME (fndecl), "__cxa_begin_catch"))
1851 : return CXA_BEGIN_CATCH;
1852 4823 : if (id_equal (DECL_NAME (fndecl), "__cxa_end_catch"))
1853 : return CXA_END_CATCH;
1854 1080 : if (id_equal (DECL_NAME (fndecl), "__cxa_rethrow"))
1855 : return CXA_RETHROW;
1856 974 : if (id_equal (DECL_NAME (fndecl), "__cxa_get_exception_ptr"))
1857 : return CXA_GET_EXCEPTION_PTR;
1858 930 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_cast"))
1859 : return CXA_BAD_CAST;
1860 634 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_typeid"))
1861 : return CXA_BAD_TYPEID;
1862 621 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw_bad_array_new_length"))
1863 33 : return CXA_THROW_BAD_ARRAY_NEW_LENGTH;
1864 : return CXA_NONE;
1865 : }
1866 :
1867 : /* Helper function for cxx_eval_cxa_builtin_fn.
1868 : Check if ARG is a valid first argument of __cxa_throw or
1869 : __cxa_free_exception or __builtin_eh_ptr_adjust_ref. Return NULL_TREE if
1870 : not, otherwise return the artificial __cxa_allocate_exception allocated
1871 : VAR_DECL. FREE_EXC is true for __cxa_free_exception, false otherwise. */
1872 :
1873 : static tree
1874 1916 : cxa_check_throw_arg (tree arg, bool free_exc)
1875 : {
1876 1916 : STRIP_NOPS (arg);
1877 1916 : if (TREE_CODE (arg) != ADDR_EXPR)
1878 : return NULL_TREE;
1879 1916 : arg = TREE_OPERAND (arg, 0);
1880 1916 : if (!VAR_P (arg)
1881 1916 : || !DECL_ARTIFICIAL (arg)
1882 1916 : || ((!free_exc || DECL_NAME (arg) != heap_uninit_identifier)
1883 1916 : && DECL_NAME (arg) != heap_identifier)
1884 3832 : || !DECL_LANG_SPECIFIC (arg))
1885 0 : return NULL_TREE;
1886 : return arg;
1887 : }
1888 :
1889 : /* Helper function for cxx_eval_cxa_builtin_fn.
1890 : "Allocate" on the constexpr heap an exception object of TYPE
1891 : with REFCOUNT. */
1892 :
1893 : static tree
1894 17900 : cxa_allocate_exception (location_t loc, const constexpr_ctx *ctx, tree type,
1895 : tree refcount)
1896 : {
1897 17900 : tree var = build_decl (loc, VAR_DECL, heap_uninit_identifier, type);
1898 17900 : DECL_ARTIFICIAL (var) = 1;
1899 17900 : retrofit_lang_decl (var);
1900 17900 : DECL_EXCEPTION_REFCOUNT (var) = refcount;
1901 17900 : ctx->global->heap_vars.safe_push (var);
1902 17900 : return var;
1903 : }
1904 :
1905 : /* Evaluate various __cxa_* calls as magic constexpr builtins for
1906 : C++26 constexpr exception support (P3068R5). */
1907 :
1908 : static tree
1909 30350 : cxx_eval_cxa_builtin_fn (const constexpr_ctx *ctx, tree call,
1910 : enum cxa_builtin kind, tree fndecl,
1911 : bool *non_constant_p, bool *overflow_p,
1912 : tree *jump_target)
1913 : {
1914 30350 : int nargs = call_expr_nargs (call);
1915 30350 : location_t loc = cp_expr_loc_or_input_loc (call);
1916 30350 : tree args[4], arg;
1917 30350 : if (nargs > 4)
1918 : {
1919 0 : invalid_nargs:
1920 0 : if (!ctx->quiet)
1921 0 : error_at (loc, "call to %qD function with incorrect "
1922 : "number of arguments", fndecl);
1923 0 : *non_constant_p = true;
1924 0 : return call;
1925 : }
1926 30350 : if ((kind == CXA_BEGIN_CATCH || kind == CXA_GET_EXCEPTION_PTR)
1927 7542 : && nargs == 1
1928 7542 : && (arg = CALL_EXPR_ARG (call, 0))
1929 7542 : && TREE_CODE (arg) == CALL_EXPR
1930 7542 : && call_expr_nargs (arg) == 1
1931 37892 : && integer_zerop (CALL_EXPR_ARG (arg, 0)))
1932 7542 : if (tree fun = get_function_named_in_call (arg))
1933 7542 : if (fndecl_built_in_p (fun, BUILT_IN_EH_POINTER))
1934 : {
1935 7542 : if (ctx->global->caught_exceptions.length () < 2)
1936 : {
1937 3767 : no_caught_exceptions:
1938 3767 : if (!ctx->quiet)
1939 0 : error_at (loc, "%qD called with no caught exceptions pending",
1940 : fndecl);
1941 3767 : *non_constant_p = true;
1942 3767 : return call;
1943 : }
1944 : /* Both __cxa_get_exception_ptr (__builtin_eh_pointer (0))
1945 : and __cxa_begin_catch (__builtin_eh_pointer (0)) calls expect
1946 : ctx->global->caught_exceptions vector to end with
1947 : __cxa_allocate_exception created artificial VAR_DECL (the
1948 : exception object) followed by handler type, pushed by TRY_BLOCK
1949 : evaluation. The only difference between the functions is that
1950 : __cxa_begin_catch pops the handler type from the vector and keeps
1951 : the VAR_DECL last and decreases uncaught_exceptions. The
1952 : VAR_DECL after __cxa_begin_catch serves as the current exception
1953 : and is then popped in __cxa_end_catch evaluation. */
1954 3775 : tree handler_type = ctx->global->caught_exceptions.last ();
1955 3775 : if (handler_type && (VAR_P (handler_type)
1956 3693 : || TREE_CODE (handler_type) == TREE_LIST))
1957 0 : goto no_caught_exceptions;
1958 3775 : unsigned idx = ctx->global->caught_exceptions.length () - 2;
1959 3775 : arg = ctx->global->caught_exceptions[idx];
1960 3775 : if (TREE_CODE (arg) == TREE_LIST)
1961 0 : arg = TREE_VALUE (arg);
1962 3775 : gcc_assert (VAR_P (arg));
1963 3775 : if (kind == CXA_BEGIN_CATCH)
1964 : {
1965 3747 : ctx->global->caught_exceptions.pop ();
1966 3747 : --ctx->global->uncaught_exceptions;
1967 : }
1968 3775 : if (handler_type == NULL_TREE)
1969 : /* Used for catch (...). Just return void. */
1970 82 : return void_node;
1971 3693 : else if (POINTER_TYPE_P (handler_type))
1972 : {
1973 : /* Used for catch of a pointer. */
1974 66 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
1975 66 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
1976 : size_zero_node, NULL_TREE, NULL_TREE);
1977 66 : arg = cp_convert (handler_type, arg,
1978 66 : ctx->quiet ? tf_none : tf_warning_or_error);
1979 66 : if (arg == error_mark_node)
1980 : {
1981 0 : *non_constant_p = true;
1982 0 : return call;
1983 : }
1984 : }
1985 : else
1986 : {
1987 : /* Used for catch of a non-pointer type. */
1988 3627 : tree exc_type = strip_array_types (TREE_TYPE (arg));
1989 3607 : if (TYPE_PTRMEM_P (handler_type)
1990 3673 : && !same_type_ignoring_top_level_qualifiers_p
1991 46 : (handler_type, exc_type))
1992 : {
1993 46 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
1994 46 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
1995 : size_zero_node, NULL_TREE, NULL_TREE);
1996 46 : arg = cp_convert (handler_type, arg,
1997 46 : ctx->quiet ? tf_none
1998 : : tf_warning_or_error);
1999 46 : if (arg == error_mark_node)
2000 : {
2001 0 : *non_constant_p = true;
2002 0 : return call;
2003 : }
2004 46 : tree var = build_decl (loc, VAR_DECL, heap_identifier,
2005 46 : handler_type);
2006 46 : DECL_ARTIFICIAL (var) = 1;
2007 46 : ctx->global->heap_vars.safe_push (var);
2008 46 : ctx->global->put_value (var, NULL_TREE);
2009 46 : tree init = build2_loc (loc, INIT_EXPR, handler_type,
2010 : var, arg);
2011 46 : arg = ctx->global->caught_exceptions[idx];
2012 46 : if (TREE_CODE (arg) == TREE_LIST)
2013 : {
2014 0 : DECL_CHAIN (var) = TREE_PURPOSE (arg);
2015 0 : TREE_PURPOSE (arg) = var;
2016 : }
2017 : else
2018 46 : ctx->global->caught_exceptions[idx]
2019 92 : = build_tree_list (var, arg);
2020 46 : arg = cp_build_addr_expr (var, tf_none);
2021 46 : arg = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (arg),
2022 : init, arg);
2023 : }
2024 : else
2025 : {
2026 3581 : tree exc_ptr_type = build_pointer_type (exc_type);
2027 3581 : arg = build_fold_addr_expr_with_type (arg, exc_ptr_type);
2028 3581 : if (CLASS_TYPE_P (handler_type))
2029 : {
2030 3491 : tree ptr_type = build_pointer_type (handler_type);
2031 3491 : arg = cp_convert (ptr_type, arg,
2032 3491 : ctx->quiet ? tf_none
2033 : : tf_warning_or_error);
2034 3491 : if (arg == error_mark_node)
2035 : {
2036 0 : *non_constant_p = true;
2037 0 : return call;
2038 : }
2039 : }
2040 : }
2041 : }
2042 3693 : return cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2043 : non_constant_p, overflow_p,
2044 3693 : jump_target);
2045 : }
2046 42947 : for (int i = 0; i < nargs; ++i)
2047 : {
2048 20139 : args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (call, i),
2049 : vc_prvalue, non_constant_p,
2050 : overflow_p, jump_target);
2051 20139 : if (*non_constant_p)
2052 : return call;
2053 20139 : if (*jump_target)
2054 : return NULL_TREE;
2055 : }
2056 22808 : switch (kind)
2057 : {
2058 14601 : case CXA_ALLOCATE_EXCEPTION:
2059 14601 : if (nargs != 1)
2060 0 : goto invalid_nargs;
2061 14601 : if (!tree_fits_uhwi_p (args[0]))
2062 : {
2063 0 : if (!ctx->quiet)
2064 0 : error_at (loc, "cannot allocate exception: size not constant");
2065 0 : *non_constant_p = true;
2066 0 : return call;
2067 : }
2068 : else
2069 : {
2070 29202 : tree type = build_array_type_nelts (char_type_node,
2071 14601 : tree_to_uhwi (args[0]));
2072 14601 : tree var = cxa_allocate_exception (loc, ctx, type, size_zero_node);
2073 14601 : ctx->global->put_value (var, NULL_TREE);
2074 14601 : return fold_convert (ptr_type_node, build_address (var));
2075 : }
2076 2 : case CXA_FREE_EXCEPTION:
2077 2 : if (nargs != 1)
2078 0 : goto invalid_nargs;
2079 2 : arg = cxa_check_throw_arg (args[0], true);
2080 2 : if (arg == NULL_TREE)
2081 : {
2082 0 : invalid_ptr:
2083 0 : if (!ctx->quiet)
2084 0 : error_at (loc, "first argument to %qD function not result of "
2085 : "%<__cxa_allocate_exception%>", fndecl);
2086 0 : *non_constant_p = true;
2087 0 : return call;
2088 : }
2089 2 : DECL_NAME (arg) = heap_deleted_identifier;
2090 2 : ctx->global->destroy_value (arg);
2091 2 : ctx->global->heap_dealloc_count++;
2092 2 : return void_node;
2093 1748 : case CXA_THROW:
2094 1748 : if (nargs != 3)
2095 0 : goto invalid_nargs;
2096 1748 : arg = cxa_check_throw_arg (args[0], false);
2097 1748 : if (arg == NULL_TREE)
2098 0 : goto invalid_ptr;
2099 1748 : DECL_EXCEPTION_REFCOUNT (arg)
2100 1748 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2101 : size_one_node);
2102 1748 : ++ctx->global->uncaught_exceptions;
2103 1748 : *jump_target = arg;
2104 1748 : return void_node;
2105 0 : case CXA_BEGIN_CATCH:
2106 0 : case CXA_GET_EXCEPTION_PTR:
2107 0 : goto invalid_nargs;
2108 3743 : case CXA_END_CATCH:
2109 3743 : if (nargs != 0)
2110 0 : goto invalid_nargs;
2111 3743 : if (ctx->global->caught_exceptions.is_empty ())
2112 : {
2113 0 : no_active_exc:
2114 0 : if (!ctx->quiet)
2115 0 : error_at (loc, "%qD called with no caught exceptions active",
2116 : fndecl);
2117 0 : *non_constant_p = true;
2118 0 : return call;
2119 : }
2120 : else
2121 : {
2122 3743 : arg = ctx->global->caught_exceptions.pop ();
2123 3743 : if (arg == NULL_TREE
2124 3743 : || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2125 0 : goto no_active_exc;
2126 3743 : if (TREE_CODE (arg) == TREE_LIST)
2127 : {
2128 92 : for (tree aux = TREE_PURPOSE (arg); aux; aux = DECL_CHAIN (aux))
2129 : {
2130 46 : DECL_NAME (aux) = heap_deleted_identifier;
2131 46 : ctx->global->destroy_value (aux);
2132 46 : ctx->global->heap_dealloc_count++;
2133 : }
2134 46 : arg = TREE_VALUE (arg);
2135 : }
2136 3743 : DECL_CHAIN (arg) = NULL_TREE;
2137 3821 : free_except:
2138 3821 : DECL_EXCEPTION_REFCOUNT (arg)
2139 3821 : = size_binop (MINUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2140 : size_one_node);
2141 3821 : if (integer_zerop (DECL_EXCEPTION_REFCOUNT (arg)))
2142 : {
2143 3611 : if (type_build_dtor_call (TREE_TYPE (arg)))
2144 : {
2145 : /* So that we don't complain about out-of-consteval use. */
2146 3393 : temp_override<tree> ovr (current_function_decl);
2147 3393 : if (ctx->call && ctx->call->fundef)
2148 3393 : current_function_decl = ctx->call->fundef->decl;
2149 3393 : tree cleanup
2150 3415 : = cxx_maybe_build_cleanup (arg, (ctx->quiet ? tf_none
2151 : : tf_warning_or_error));
2152 3393 : if (cleanup == error_mark_node)
2153 0 : *non_constant_p = true;
2154 3393 : tree jmp_target = NULL_TREE;
2155 3393 : cxx_eval_constant_expression (ctx, cleanup, vc_discard,
2156 : non_constant_p, overflow_p,
2157 : &jmp_target);
2158 3393 : if (throws (&jmp_target))
2159 0 : *jump_target = jmp_target;
2160 3393 : }
2161 3611 : DECL_NAME (arg) = heap_deleted_identifier;
2162 3611 : ctx->global->destroy_value (arg);
2163 3611 : ctx->global->heap_dealloc_count++;
2164 : }
2165 : }
2166 3821 : return void_node;
2167 98 : case CXA_RETHROW:
2168 98 : if (nargs != 0)
2169 0 : goto invalid_nargs;
2170 98 : unsigned idx;
2171 196 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2172 82 : if (arg == NULL_TREE || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2173 0 : --idx;
2174 : else
2175 : break;
2176 98 : if (arg == NULL_TREE)
2177 : {
2178 16 : if (!ctx->quiet)
2179 4 : error_at (loc, "%qD called with no caught exceptions active",
2180 : fndecl);
2181 16 : *non_constant_p = true;
2182 16 : return call;
2183 : }
2184 82 : if (TREE_CODE (arg) == TREE_LIST)
2185 0 : arg = TREE_VALUE (arg);
2186 82 : DECL_EXCEPTION_REFCOUNT (arg)
2187 82 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2188 82 : ++ctx->global->uncaught_exceptions;
2189 : /* Don't cache calls which rethrow, they depend on the current
2190 : exception which might be caught in the caller. */
2191 82 : ctx->global->state_dependent = true;
2192 82 : *jump_target = arg;
2193 82 : return void_node;
2194 163 : case CXA_BAD_CAST:
2195 163 : case CXA_BAD_TYPEID:
2196 163 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2197 163 : if (nargs != 0)
2198 0 : goto invalid_nargs;
2199 : else
2200 : {
2201 163 : tree name;
2202 163 : switch (kind)
2203 : {
2204 123 : case CXA_BAD_CAST:
2205 123 : name = get_identifier ("bad_cast");
2206 123 : break;
2207 7 : case CXA_BAD_TYPEID:
2208 7 : name = get_identifier ("bad_typeid");
2209 7 : break;
2210 33 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2211 33 : name = get_identifier ("bad_array_new_length");
2212 33 : break;
2213 : default:
2214 : gcc_unreachable ();
2215 : }
2216 163 : tree decl = lookup_qualified_name (std_node, name);
2217 163 : if (TREE_CODE (decl) != TYPE_DECL
2218 135 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2219 298 : || !type_build_ctor_call (TREE_TYPE (decl)))
2220 : {
2221 28 : if (!ctx->quiet)
2222 8 : error_at (loc, "%qD called without %<std::%D%> being defined",
2223 : fndecl, name);
2224 28 : *non_constant_p = true;
2225 28 : return call;
2226 : }
2227 135 : tree type = TREE_TYPE (decl);
2228 135 : tree var = cxa_allocate_exception (loc, ctx, type, size_one_node);
2229 135 : tree ctor
2230 135 : = build_special_member_call (var, complete_ctor_identifier,
2231 : NULL, type, LOOKUP_NORMAL,
2232 135 : ctx->quiet ? tf_none
2233 : : tf_warning_or_error);
2234 135 : if (ctor == error_mark_node)
2235 : {
2236 0 : *non_constant_p = true;
2237 0 : return call;
2238 : }
2239 135 : if (TREE_CONSTANT (ctor))
2240 0 : ctx->global->put_value (var, ctor);
2241 : else
2242 : {
2243 135 : ctx->global->put_value (var, NULL_TREE);
2244 135 : cxx_eval_constant_expression (ctx, ctor, vc_discard,
2245 : non_constant_p, overflow_p,
2246 : jump_target);
2247 135 : if (*non_constant_p)
2248 : return call;
2249 135 : if (throws (jump_target))
2250 : return NULL_TREE;
2251 : }
2252 135 : ++ctx->global->uncaught_exceptions;
2253 135 : *jump_target = var;
2254 : }
2255 135 : return void_node;
2256 82 : case BUILTIN_UNCAUGHT_EXCEPTIONS:
2257 82 : if (nargs != 0)
2258 0 : goto invalid_nargs;
2259 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2260 : want to give a definite answer during mce_unknown evaluation,
2261 : because that might prevent evaluation later on when some
2262 : exceptions might be uncaught. But unlike that, we don't
2263 : want to constant fold it even during cp_fold, because at runtime
2264 : std::uncaught_exceptions () might still be non-zero. */
2265 82 : if (ctx->manifestly_const_eval != mce_true)
2266 : {
2267 46 : *non_constant_p = true;
2268 46 : return call;
2269 : }
2270 : /* Don't cache calls which call __builtin_uncaught_exceptions (),
2271 : they depend on the current uncaught exceptions which might
2272 : be the state from their caller. */
2273 36 : ctx->global->state_dependent = true;
2274 36 : return build_int_cst (integer_type_node,
2275 36 : ctx->global->uncaught_exceptions);
2276 2205 : case BUILTIN_CURRENT_EXCEPTION:
2277 2205 : if (nargs != 0)
2278 0 : goto invalid_nargs;
2279 : else
2280 : {
2281 2205 : tree name = get_identifier ("exception_ptr");
2282 2205 : tree decl = lookup_qualified_name (std_node, name);
2283 2205 : tree fld;
2284 2205 : if (TREE_CODE (decl) != TYPE_DECL
2285 2205 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2286 2205 : || !COMPLETE_TYPE_P (TREE_TYPE (decl))
2287 2205 : || !(fld = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (decl))))
2288 2205 : || DECL_ARTIFICIAL (fld)
2289 2205 : || TREE_CODE (TREE_TYPE (fld)) != POINTER_TYPE
2290 2205 : || next_aggregate_field (DECL_CHAIN (fld))
2291 4410 : || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (decl)),
2292 2205 : TYPE_SIZE (TREE_TYPE (fld))))
2293 : {
2294 0 : if (!ctx->quiet)
2295 0 : error_at (loc, "%qD called without supportable %qs",
2296 : fndecl, "std::exception_ptr");
2297 0 : *non_constant_p = true;
2298 0 : return call;
2299 : }
2300 4410 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2301 42 : if (arg == NULL_TREE
2302 42 : || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
2303 0 : --idx;
2304 : else
2305 : break;
2306 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2307 : want to give a definite answer during mce_unknown evaluation,
2308 : because that might prevent evaluation later on when some
2309 : exceptions might be current. But unlike that, we don't
2310 : want to constant fold it to null even during cp_fold, because
2311 : at runtime std::current_exception () might still be non-null. */
2312 2205 : if (ctx->manifestly_const_eval != mce_true && arg == NULL_TREE)
2313 : {
2314 2151 : *non_constant_p = true;
2315 2151 : return call;
2316 : }
2317 54 : if (arg == NULL_TREE)
2318 12 : arg = build_zero_cst (TREE_TYPE (fld));
2319 : else
2320 : {
2321 42 : if (TREE_CODE (arg) == TREE_LIST)
2322 0 : arg = TREE_VALUE (arg);
2323 42 : DECL_EXCEPTION_REFCOUNT (arg)
2324 42 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2325 : size_one_node);
2326 42 : arg = fold_convert (ptr_type_node, build_address (arg));
2327 : }
2328 : /* Don't cache calls which call __builtin_current_exception (),
2329 : they depend on the current exception which might be caught
2330 : in the caller. */
2331 54 : ctx->global->state_dependent = true;
2332 54 : return build_constructor_single (TREE_TYPE (decl), fld, arg);
2333 : }
2334 40 : case STD_RETHROW_EXCEPTION:
2335 40 : if (nargs != 1)
2336 0 : goto invalid_nargs;
2337 40 : if (TYPE_REF_P (TREE_TYPE (args[0])))
2338 : {
2339 40 : arg = args[0];
2340 40 : STRIP_NOPS (arg);
2341 40 : if (TREE_CODE (arg) == ADDR_EXPR)
2342 : {
2343 40 : args[0]
2344 40 : = cxx_eval_constant_expression (ctx, TREE_OPERAND (arg, 0),
2345 : vc_prvalue, non_constant_p,
2346 : overflow_p, jump_target);
2347 40 : if (*non_constant_p)
2348 : return call;
2349 40 : if (*jump_target)
2350 : return NULL_TREE;
2351 : }
2352 : }
2353 40 : if (TREE_CODE (args[0]) != CONSTRUCTOR
2354 40 : || CONSTRUCTOR_NELTS (args[0]) != 1)
2355 : {
2356 0 : invalid_std_rethrow:
2357 0 : if (!ctx->quiet)
2358 0 : error_at (loc, "%qD called with unexpected %qs argument",
2359 : fndecl, "std::exception_ptr");
2360 0 : *non_constant_p = true;
2361 0 : return void_node;
2362 : }
2363 40 : arg = cxa_check_throw_arg (CONSTRUCTOR_ELT (args[0], 0)->value, false);
2364 40 : if (arg == NULL_TREE)
2365 0 : goto invalid_std_rethrow;
2366 40 : DECL_EXCEPTION_REFCOUNT (arg)
2367 40 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2368 40 : ++ctx->global->uncaught_exceptions;
2369 40 : *jump_target = arg;
2370 40 : return void_node;
2371 126 : case BUILTIN_EH_PTR_ADJUST_REF:
2372 126 : if (nargs != 2)
2373 0 : goto invalid_nargs;
2374 126 : arg = cxa_check_throw_arg (args[0], false);
2375 126 : if (arg == NULL_TREE)
2376 0 : goto invalid_ptr;
2377 126 : if (integer_onep (args[1]))
2378 48 : DECL_EXCEPTION_REFCOUNT (arg)
2379 96 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2380 : size_one_node);
2381 78 : else if (integer_minus_onep (args[1]))
2382 78 : goto free_except;
2383 : else
2384 : {
2385 0 : if (!ctx->quiet)
2386 0 : error_at (loc, "%qD called with second argument "
2387 : "other than 1 or -1", fndecl);
2388 0 : *non_constant_p = true;
2389 : }
2390 48 : return void_node;
2391 0 : default:
2392 0 : gcc_unreachable ();
2393 : }
2394 : }
2395 :
2396 : /* Variables and functions to manage constexpr call expansion context.
2397 : These do not need to be marked for PCH or GC. */
2398 :
2399 : /* FIXME remember and print actual constant arguments. */
2400 : static vec<tree> call_stack;
2401 : static int call_stack_tick;
2402 : static int last_cx_error_tick;
2403 :
2404 : /* Attempt to evaluate T which represents a call to __builtin_constexpr_diag.
2405 : The arguments should be an integer (0 for inform, 1 for warning, 2 for
2406 : error) optionally with 16 ored in if it should use caller's caller location
2407 : instead of caller's location and 2 messages which are either a pointer to
2408 : a STRING_CST or class with data () and size () member functions like
2409 : string_view or u8string_view. The first message is a tag, with "" passed
2410 : for no tag, data () should return const char *, the tag should only contain
2411 : alphanumeric letters or underscores. The second message is the diagnostic
2412 : message, data () can be either const char * or const char8_t *. size ()
2413 : should return the corresponding length of the strings in bytes as an
2414 : integer. */
2415 :
2416 : static tree
2417 210 : cxx_eval_constexpr_diag (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
2418 : bool *overflow_p, tree *jump_target)
2419 : {
2420 210 : location_t loc = EXPR_LOCATION (t);
2421 210 : if (call_expr_nargs (t) != 3)
2422 : {
2423 12 : if (!ctx->quiet)
2424 12 : error_at (loc, "wrong number of arguments to %qs call",
2425 : "__builtin_constexpr_diag");
2426 12 : *non_constant_p = true;
2427 12 : return t;
2428 : }
2429 : tree args[3];
2430 792 : for (int i = 0; i < 3; ++i)
2431 : {
2432 594 : tree arg = convert_from_reference (CALL_EXPR_ARG (t, i));
2433 594 : arg = cxx_eval_constant_expression (ctx, arg,
2434 : (i == 0
2435 534 : || POINTER_TYPE_P (TREE_TYPE (arg)))
2436 990 : ? vc_prvalue : vc_glvalue,
2437 : non_constant_p, overflow_p,
2438 : jump_target);
2439 594 : if (*jump_target)
2440 : return NULL_TREE;
2441 594 : if (*non_constant_p)
2442 : return t;
2443 594 : args[i] = arg;
2444 : }
2445 396 : if (TREE_CODE (args[0]) != INTEGER_CST
2446 198 : || wi::to_widest (args[0]) < 0
2447 194 : || wi::to_widest (args[0]) > 18
2448 396 : || (wi::to_widest (args[0]) & 15) > 2)
2449 : {
2450 8 : if (!ctx->quiet)
2451 8 : error_at (loc, "first %qs call argument should be 0, 1, 2, 16, 17 or "
2452 : "18", "__builtin_constexpr_diag");
2453 8 : *non_constant_p = true;
2454 8 : return t;
2455 : }
2456 190 : const char *msgs[2] = {};
2457 190 : int lens[3] = {};
2458 950 : cexpr_str cstrs[2];
2459 478 : diagnostics::kind kind = diagnostics::kind::error;
2460 478 : for (int i = 1; i < 3; ++i)
2461 : {
2462 344 : tree arg = args[i];
2463 344 : if (POINTER_TYPE_P (TREE_TYPE (arg)))
2464 : {
2465 206 : tree str = arg;
2466 206 : STRIP_NOPS (str);
2467 206 : if (TREE_CODE (str) == ADDR_EXPR
2468 206 : && TREE_CODE (TREE_OPERAND (str, 0)) == STRING_CST)
2469 : {
2470 206 : str = TREE_OPERAND (str, 0);
2471 206 : tree eltype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)));
2472 206 : if (eltype == char_type_node
2473 24 : || (i == 2 && eltype == char8_type_node))
2474 344 : arg = str;
2475 : }
2476 : }
2477 344 : cstrs[i - 1].message = arg;
2478 344 : if (!cstrs[i - 1].type_check (loc, i == 2))
2479 : {
2480 40 : *non_constant_p = true;
2481 40 : return t;
2482 : }
2483 304 : if (!cstrs[i - 1].extract (loc, msgs[i - 1], lens[i - 1], ctx,
2484 : non_constant_p, overflow_p, jump_target))
2485 : {
2486 16 : if (*jump_target)
2487 : return NULL_TREE;
2488 16 : *non_constant_p = true;
2489 16 : return t;
2490 : }
2491 : }
2492 134 : if (msgs[0])
2493 : {
2494 726 : for (int i = 0; i < lens[0]; ++i)
2495 596 : if (!ISALNUM (msgs[0][i]) && msgs[0][i] != '_')
2496 : {
2497 4 : if (!ctx->quiet)
2498 4 : error_at (loc, "%qs tag string contains %qc character other than"
2499 : " letters, digits or %<_%>",
2500 : "__builtin_constexpr_diag", msgs[0][i]);
2501 4 : *non_constant_p = true;
2502 4 : return t;
2503 : }
2504 : }
2505 130 : if (ctx->manifestly_const_eval == mce_unknown)
2506 : {
2507 0 : *non_constant_p = true;
2508 0 : return t;
2509 : }
2510 130 : int arg0 = tree_to_uhwi (args[0]);
2511 130 : if (arg0 & 16)
2512 : {
2513 32 : arg0 &= 15;
2514 32 : if (!call_stack.is_empty ())
2515 : {
2516 32 : tree call = call_stack.last ();
2517 32 : if (EXPR_HAS_LOCATION (call))
2518 32 : loc = EXPR_LOCATION (call);
2519 : }
2520 : }
2521 130 : if (arg0 == 0)
2522 : kind = diagnostics::kind::note;
2523 82 : else if (arg0 == 1)
2524 36 : kind = diagnostics::kind::warning;
2525 130 : if (lens[0])
2526 : {
2527 88 : const char *color = "error";
2528 88 : if (kind == diagnostics::kind::note)
2529 : color = "note";
2530 60 : else if (kind == diagnostics::kind::warning)
2531 32 : color = "warning";
2532 88 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s [%r%.*s%R]",
2533 : lens[1], msgs[1], color, lens[0], msgs[0]);
2534 : }
2535 : else
2536 42 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s",
2537 : lens[1], msgs[1]);
2538 130 : return void_node;
2539 570 : }
2540 :
2541 : static tree eval_and_check_array_index (const constexpr_ctx *, tree, bool,
2542 : bool *, bool *, tree *);
2543 :
2544 : /* Helper function for cxx_eval_is_within_lifetime and
2545 : cxx_eval_start_lifetime. Check if ARG is within lifetime. */
2546 :
2547 : static tree
2548 4368 : is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun,
2549 : tree arg, bool *non_constant_p, bool *overflow_p,
2550 : tree *jump_target)
2551 : {
2552 4368 : auto_vec <tree, 4> refs;
2553 4368 : tree obj;
2554 9889 : for (obj = arg; ; obj = TREE_OPERAND (obj, 0))
2555 : {
2556 9889 : switch (TREE_CODE (obj))
2557 : {
2558 5521 : case COMPONENT_REF:
2559 5521 : case ARRAY_REF:
2560 5521 : case REALPART_EXPR:
2561 5521 : case IMAGPART_EXPR:
2562 5521 : refs.safe_push (obj);
2563 5521 : continue;
2564 4368 : default:
2565 4368 : break;
2566 : }
2567 4368 : break;
2568 : }
2569 4368 : tree *valp = nullptr;
2570 4368 : bool check_mutable = false;
2571 4368 : if (DECL_P (obj))
2572 : {
2573 4326 : valp = ctx->global->get_raw_value_ptr (obj);
2574 4326 : if (!valp
2575 858 : && VAR_P (obj)
2576 858 : && TREE_STATIC (obj)
2577 4596 : && decl_constant_var_p (obj))
2578 : {
2579 258 : valp = &DECL_INITIAL (obj);
2580 258 : check_mutable = true;
2581 : }
2582 : }
2583 4326 : if (!valp || *valp == void_list_node)
2584 : {
2585 828 : if (!ctx->quiet)
2586 : {
2587 57 : auto_diagnostic_group d;
2588 57 : if (DECL_P (obj) && DECL_NAME (obj) == heap_deleted_identifier)
2589 : {
2590 3 : error_at (loc, "%qE on allocated storage after deallocation "
2591 3 : "is not a constant expression", DECL_NAME (fun));
2592 3 : inform (DECL_SOURCE_LOCATION (obj), "allocated here");
2593 : }
2594 54 : else if (DECL_P (obj) && ctx->global->is_outside_lifetime (obj))
2595 : {
2596 45 : error_at (loc, "%qE on %qE after its storage has been released "
2597 45 : "is not a constant expression", DECL_NAME (fun), obj);
2598 45 : inform (DECL_SOURCE_LOCATION (obj), "declared here");
2599 : }
2600 : else
2601 9 : error_at (loc, "%qE on %qE from outside current evaluation "
2602 9 : "is not a constant expression", DECL_NAME (fun), obj);
2603 57 : }
2604 828 : *non_constant_p = true;
2605 828 : return t;
2606 : }
2607 3540 : tree val = *valp;
2608 3540 : if (val == void_node)
2609 15 : return boolean_false_node;
2610 3525 : unsigned i;
2611 3525 : tree ref;
2612 : /* Magic value used for val when inside the following loop when
2613 : inside of an omitted part of initializer due to it being
2614 : uninitialized. In this case return boolean_true_node unless
2615 : there is some union member access, in unitialized union
2616 : no member is within lifetime. */
2617 3525 : const tree val_uninit = global_namespace;
2618 : /* Magic value used for val when inside the following loop when
2619 : inside of an omitted part of initializer due to it being
2620 : zero initialized. In this case return boolean_true_node unless
2621 : there is some union member access except for the first member. */
2622 3525 : const tree val_zero_init = std_node;
2623 3525 : if (val == NULL_TREE)
2624 141 : val = val_uninit;
2625 10631 : FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
2626 4240 : switch (TREE_CODE (ref))
2627 : {
2628 18 : case REALPART_EXPR:
2629 18 : case IMAGPART_EXPR:
2630 18 : if (TREE_CODE (val) == COMPLEX_EXPR
2631 18 : && (TREE_OPERAND (val, TREE_CODE (ref) == IMAGPART_EXPR)
2632 12 : == void_node))
2633 6 : return boolean_false_node;
2634 12 : return boolean_true_node;
2635 3477 : case COMPONENT_REF:
2636 3477 : if (check_mutable && DECL_MUTABLE_P (TREE_OPERAND (ref, 1)))
2637 : {
2638 12 : if (!ctx->quiet)
2639 3 : error_at (loc, "%qE on %<mutable%> sub-object %qD",
2640 3 : DECL_NAME (fun), TREE_OPERAND (ref, 1));
2641 12 : *non_constant_p = true;
2642 12 : return t;
2643 : }
2644 3465 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
2645 : {
2646 1202 : tree union_type = TREE_TYPE (TREE_OPERAND (ref, 0));
2647 1202 : if (val == val_zero_init)
2648 : {
2649 48 : if (TREE_OPERAND (ref, 1)
2650 24 : != next_aggregate_field (TYPE_FIELDS (union_type)))
2651 15 : return boolean_false_node;
2652 9 : continue;
2653 : }
2654 1178 : else if (val == val_uninit)
2655 93 : return boolean_false_node;
2656 : else
2657 : {
2658 1085 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2659 1085 : if (CONSTRUCTOR_NELTS (val) == 0)
2660 : {
2661 129 : if (CONSTRUCTOR_NO_CLEARING (val))
2662 117 : return boolean_false_node;
2663 12 : tree first
2664 12 : = next_aggregate_field (TYPE_FIELDS (union_type));
2665 12 : if (first != TREE_OPERAND (ref, 1))
2666 3 : return boolean_false_node;
2667 9 : val = val_zero_init;
2668 9 : continue;
2669 9 : }
2670 : else
2671 : {
2672 956 : if (CONSTRUCTOR_ELT (val, 0)->index
2673 956 : != TREE_OPERAND (ref, 1))
2674 272 : return boolean_false_node;
2675 684 : val = CONSTRUCTOR_ELT (val, 0)->value;
2676 684 : if (val == void_node)
2677 0 : return boolean_false_node;
2678 684 : continue;
2679 : }
2680 : }
2681 : }
2682 2263 : if (val == val_zero_init || val == val_uninit)
2683 36 : continue;
2684 2227 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2685 : unsigned int j;
2686 : tree field, value;
2687 3608 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (val), j, field, value)
2688 2163 : if (field == TREE_OPERAND (ref, 1))
2689 : {
2690 782 : if (value == void_node)
2691 6 : return boolean_false_node;
2692 : val = value;
2693 : ref = NULL_TREE;
2694 : break;
2695 : }
2696 2221 : if (ref == NULL_TREE)
2697 776 : continue;
2698 1445 : if (CONSTRUCTOR_NO_CLEARING (val))
2699 : {
2700 1403 : if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
2701 42 : return boolean_false_node;
2702 : val = val_uninit;
2703 : }
2704 : else
2705 : val = val_zero_init;
2706 1403 : continue;
2707 745 : case ARRAY_REF:
2708 745 : field = eval_and_check_array_index (ctx, ref, false,
2709 : non_constant_p, overflow_p,
2710 : jump_target);
2711 745 : if (*jump_target)
2712 : return NULL_TREE;
2713 745 : if (*non_constant_p)
2714 : return t;
2715 733 : if (val == val_zero_init || val == val_uninit)
2716 9 : continue;
2717 724 : if (TREE_CODE (val) == STRING_CST)
2718 0 : return boolean_true_node;
2719 724 : gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
2720 724 : HOST_WIDE_INT idx;
2721 724 : idx = find_array_ctor_elt (val, field, false);
2722 724 : if (idx != -1)
2723 : {
2724 340 : val = CONSTRUCTOR_ELT (val, idx)->value;
2725 340 : if (val == void_node)
2726 30 : return boolean_false_node;
2727 310 : continue;
2728 : }
2729 384 : if (CONSTRUCTOR_NO_CLEARING (val))
2730 : {
2731 159 : if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
2732 39 : return boolean_false_node;
2733 : val = val_uninit;
2734 : }
2735 : else
2736 : val = val_zero_init;
2737 345 : continue;
2738 0 : default:
2739 0 : gcc_unreachable ();
2740 1748 : }
2741 2866 : return boolean_true_node;
2742 4368 : }
2743 :
2744 : /* Attempt to evaluate T which represents a call to
2745 : __builtin_is_within_lifetime. */
2746 :
2747 : static tree
2748 3026 : cxx_eval_is_within_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
2749 : bool *non_constant_p, bool *overflow_p,
2750 : tree *jump_target)
2751 : {
2752 3026 : location_t loc = EXPR_LOCATION (t);
2753 3026 : tree arg = CALL_EXPR_ARG (t, 0);
2754 3026 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2755 : non_constant_p, overflow_p,
2756 : jump_target);
2757 3026 : if (*jump_target)
2758 : return NULL_TREE;
2759 3026 : if (*non_constant_p)
2760 : return t;
2761 : /* Need to strip casts to pointers to void, but should preserve
2762 : pointer casts within the innermost pointer to void cast if
2763 : any, so that e.g. pointers to heap allocations are handled
2764 : correctly. */
2765 : tree p = arg;
2766 5082 : while (CONVERT_EXPR_P (p) || TREE_CODE (p) == NON_LVALUE_EXPR)
2767 : {
2768 2226 : if (!TYPE_PTR_P (TREE_TYPE (p)))
2769 : break;
2770 2226 : if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (p))))
2771 174 : arg = TREE_OPERAND (p, 0);
2772 2226 : p = TREE_OPERAND (p, 0);
2773 : }
2774 2856 : if (integer_zerop (arg))
2775 : {
2776 24 : if (!ctx->quiet)
2777 6 : error_at (loc, "%qE called with a null pointer",
2778 6 : DECL_NAME (fun));
2779 24 : *non_constant_p = true;
2780 24 : return t;
2781 : }
2782 2832 : if (POINTER_TYPE_P (TREE_TYPE (arg))
2783 2832 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == FUNCTION_TYPE
2784 2811 : || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == METHOD_TYPE))
2785 : {
2786 21 : if (!ctx->quiet)
2787 6 : error_at (loc, "%qE called with pointer to function",
2788 6 : DECL_NAME (fun));
2789 21 : *non_constant_p = true;
2790 21 : return t;
2791 : }
2792 2811 : arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
2793 2811 : arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
2794 : non_constant_p, overflow_p,
2795 : jump_target);
2796 2811 : if (*jump_target)
2797 : return NULL_TREE;
2798 2811 : if (*non_constant_p)
2799 : return t;
2800 2811 : return is_within_lifetime (loc, ctx, t, fun, arg,
2801 2811 : non_constant_p, overflow_p, jump_target);
2802 : }
2803 :
2804 : static tree cxx_eval_store_expression (const constexpr_ctx *, tree,
2805 : value_cat, bool *, bool *,
2806 : tree *);
2807 :
2808 : /* Attempt to evaluate T which represents a call to
2809 : __builtin_start_lifetime. */
2810 :
2811 : static tree
2812 1563 : cxx_eval_start_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
2813 : bool *non_constant_p, bool *overflow_p,
2814 : tree *jump_target)
2815 : {
2816 1563 : location_t loc = EXPR_LOCATION (t);
2817 1563 : tree arg = CALL_EXPR_ARG (t, 0), within_lifetime;
2818 1563 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2819 : non_constant_p, overflow_p,
2820 : jump_target);
2821 1563 : if (*jump_target)
2822 : return NULL_TREE;
2823 1563 : if (*non_constant_p)
2824 : return t;
2825 1563 : arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
2826 1563 : arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
2827 : non_constant_p, overflow_p,
2828 : jump_target);
2829 1563 : if (*jump_target)
2830 : return NULL_TREE;
2831 1563 : if (*non_constant_p)
2832 : return t;
2833 1563 : switch (TREE_CODE (arg))
2834 : {
2835 1557 : case COMPONENT_REF:
2836 1557 : case ARRAY_REF:
2837 1557 : case REALPART_EXPR:
2838 1557 : case IMAGPART_EXPR:
2839 1557 : within_lifetime
2840 1557 : = is_within_lifetime (loc, ctx, t, fun, TREE_OPERAND (arg, 0),
2841 : non_constant_p, overflow_p, jump_target);
2842 1557 : if (*jump_target)
2843 : return NULL_TREE;
2844 1557 : if (*non_constant_p)
2845 : return t;
2846 1557 : if (within_lifetime != boolean_true_node)
2847 : {
2848 90 : if (!ctx->quiet)
2849 30 : error_at (loc, "%qE with containing object not within lifetime",
2850 30 : DECL_NAME (fun));
2851 90 : *non_constant_p = true;
2852 90 : return t;
2853 : }
2854 : break;
2855 : default:
2856 : break;
2857 : }
2858 1473 : tree ctor = build_constructor (TREE_TYPE (arg), NULL);
2859 1473 : CONSTRUCTOR_NO_CLEARING (ctor) = 1;
2860 1473 : CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
2861 1473 : tree modopexpr
2862 1473 : = build3_loc (loc, MODOP_EXPR, TREE_TYPE (arg), arg, ctor, NULL_TREE);
2863 1473 : arg = cxx_eval_store_expression (ctx, modopexpr, vc_discard, non_constant_p,
2864 : overflow_p, jump_target);
2865 1473 : ggc_free (modopexpr);
2866 1473 : if (*jump_target)
2867 : return NULL_TREE;
2868 1473 : if (*non_constant_p)
2869 : return t;
2870 1469 : return void_node;
2871 : }
2872 :
2873 : /* Attempt to evaluate T which represents a call to a builtin function.
2874 : We assume here that all builtin functions evaluate to scalar types
2875 : represented by _CST nodes. */
2876 :
2877 : static tree
2878 20742282 : cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
2879 : value_cat lval,
2880 : bool *non_constant_p, bool *overflow_p,
2881 : tree *jump_target)
2882 : {
2883 20742282 : const int nargs = call_expr_nargs (t);
2884 20742282 : tree *args = (tree *) alloca (nargs * sizeof (tree));
2885 20742282 : tree new_call;
2886 20742282 : int i;
2887 :
2888 : /* Don't fold __builtin_constant_p within a constexpr function. */
2889 20742282 : bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
2890 :
2891 : /* If we aren't requiring a constant expression, defer __builtin_constant_p
2892 : in a constexpr function until we have values for the parameters. */
2893 3568476 : if (bi_const_p
2894 3568476 : && ctx->manifestly_const_eval != mce_true
2895 1750634 : && current_function_decl
2896 1749505 : && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2897 : {
2898 1397558 : *non_constant_p = true;
2899 1397558 : return t;
2900 : }
2901 :
2902 19344724 : if (fndecl_built_in_p (fun, BUILT_IN_FRONTEND))
2903 3999681 : switch (DECL_FE_FUNCTION_CODE (fun))
2904 : {
2905 3976469 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
2906 : /* For __builtin_is_constant_evaluated, defer it if not
2907 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
2908 : without manifestly_const_eval even expressions or parts thereof
2909 : which will later be manifestly const_eval evaluated), otherwise fold
2910 : it to true. */
2911 3976469 : if (ctx->manifestly_const_eval == mce_unknown)
2912 : {
2913 3928275 : *non_constant_p = true;
2914 3928275 : return t;
2915 : }
2916 48194 : return constant_boolean_node (ctx->manifestly_const_eval == mce_true,
2917 48194 : boolean_type_node);
2918 :
2919 10917 : case CP_BUILT_IN_SOURCE_LOCATION:
2920 10917 : {
2921 10917 : temp_override<tree> ovr (current_function_decl);
2922 10917 : if (ctx->call && ctx->call->fundef)
2923 2753 : current_function_decl = ctx->call->fundef->decl;
2924 10917 : return fold_builtin_source_location (t);
2925 10917 : }
2926 :
2927 126 : case CP_BUILT_IN_EH_PTR_ADJUST_REF:
2928 126 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_EH_PTR_ADJUST_REF,
2929 : fun, non_constant_p, overflow_p,
2930 126 : jump_target);
2931 :
2932 2205 : case CP_BUILT_IN_CURRENT_EXCEPTION:
2933 2205 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_CURRENT_EXCEPTION,
2934 : fun, non_constant_p, overflow_p,
2935 2205 : jump_target);
2936 :
2937 82 : case CP_BUILT_IN_UNCAUGHT_EXCEPTIONS:
2938 82 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_UNCAUGHT_EXCEPTIONS,
2939 : fun, non_constant_p, overflow_p,
2940 82 : jump_target);
2941 :
2942 210 : case CP_BUILT_IN_CONSTEXPR_DIAG:
2943 210 : return cxx_eval_constexpr_diag (ctx, t, non_constant_p, overflow_p,
2944 210 : jump_target);
2945 :
2946 3026 : case CP_BUILT_IN_IS_WITHIN_LIFETIME:
2947 3026 : return cxx_eval_is_within_lifetime (ctx, t, fun, non_constant_p,
2948 3026 : overflow_p, jump_target);
2949 :
2950 1563 : case CP_BUILT_IN_START_LIFETIME:
2951 1563 : return cxx_eval_start_lifetime (ctx, t, fun, non_constant_p,
2952 1563 : overflow_p, jump_target);
2953 :
2954 : default:
2955 : break;
2956 : }
2957 :
2958 15350126 : int strops = 0;
2959 15350126 : int strret = 0;
2960 15350126 : bool bos = false;
2961 15350126 : if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
2962 14002878 : switch (DECL_FUNCTION_CODE (fun))
2963 : {
2964 : case BUILT_IN_STRLEN:
2965 : case BUILT_IN_STRNLEN:
2966 15349975 : strops = 1;
2967 : break;
2968 201107 : case BUILT_IN_MEMCHR:
2969 201107 : case BUILT_IN_STRCHR:
2970 201107 : case BUILT_IN_STRRCHR:
2971 201107 : strops = 1;
2972 201107 : strret = 1;
2973 201107 : break;
2974 112583 : case BUILT_IN_MEMCMP:
2975 112583 : case BUILT_IN_STRCMP:
2976 112583 : strops = 2;
2977 112583 : break;
2978 49873 : case BUILT_IN_STRSTR:
2979 49873 : strops = 2;
2980 49873 : strret = 1;
2981 49873 : break;
2982 66 : case BUILT_IN_ASAN_POINTER_COMPARE:
2983 66 : case BUILT_IN_ASAN_POINTER_SUBTRACT:
2984 66 : case BUILT_IN_OBSERVABLE_CHKPT:
2985 : /* These builtins shall be ignored during constant expression
2986 : evaluation. */
2987 66 : return void_node;
2988 85 : case BUILT_IN_UNREACHABLE:
2989 85 : case BUILT_IN_TRAP:
2990 85 : if (!*non_constant_p && !ctx->quiet)
2991 : {
2992 : /* Do not allow__builtin_unreachable in constexpr function.
2993 : The __builtin_unreachable call with BUILTINS_LOCATION
2994 : comes from cp_maybe_instrument_return. */
2995 25 : if (EXPR_LOCATION (t) == BUILTINS_LOCATION)
2996 0 : error ("%<constexpr%> call flows off the end of the function");
2997 : else
2998 25 : error ("%q+E is not a constant expression", t);
2999 : }
3000 85 : *non_constant_p = true;
3001 85 : return t;
3002 2881 : case BUILT_IN_OBJECT_SIZE:
3003 2881 : case BUILT_IN_DYNAMIC_OBJECT_SIZE:
3004 2881 : bos = ctx->manifestly_const_eval == mce_true;
3005 2881 : break;
3006 : default:
3007 : break;
3008 : }
3009 :
3010 : /* Be permissive for arguments to built-ins; __builtin_constant_p should
3011 : return constant false for a non-constant argument. */
3012 15349975 : constexpr_ctx new_ctx = *ctx;
3013 15349975 : new_ctx.quiet = true;
3014 41712504 : for (i = 0; i < nargs; ++i)
3015 : {
3016 26362531 : tree arg = CALL_EXPR_ARG (t, i);
3017 26362531 : tree oarg = arg;
3018 :
3019 : /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
3020 : expand_builtin doesn't know how to look in the values table. */
3021 26362531 : bool strop = i < strops;
3022 26362531 : if (strop)
3023 : {
3024 688075 : STRIP_NOPS (arg);
3025 688075 : if (TREE_CODE (arg) == ADDR_EXPR)
3026 8152 : arg = TREE_OPERAND (arg, 0);
3027 : else
3028 : strop = false;
3029 : }
3030 :
3031 : /* If builtin_valid_in_constant_expr_p is true,
3032 : potential_constant_expression_1 has not recursed into the arguments
3033 : of the builtin, verify it here. */
3034 26362531 : if (!builtin_valid_in_constant_expr_p (fun)
3035 26362531 : || potential_constant_expression (arg))
3036 : {
3037 26362394 : bool dummy1 = false, dummy2 = false;
3038 26362394 : tree jmp_target = NULL_TREE;
3039 26362394 : arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3040 : &dummy1, &dummy2, &jmp_target);
3041 26362392 : if (jmp_target)
3042 : {
3043 0 : *jump_target = jmp_target;
3044 0 : return NULL_TREE;
3045 : }
3046 : }
3047 :
3048 26362529 : if (bi_const_p)
3049 : /* For __builtin_constant_p, fold all expressions with constant values
3050 : even if they aren't C++ constant-expressions. */
3051 2170916 : arg = cp_fold_rvalue (arg);
3052 24191613 : else if (strop)
3053 : {
3054 8152 : if (TREE_CODE (arg) == CONSTRUCTOR)
3055 100 : arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
3056 8152 : if (TREE_CODE (arg) == STRING_CST)
3057 3042 : arg = build_address (arg);
3058 : else
3059 : arg = oarg;
3060 : }
3061 :
3062 26362529 : args[i] = arg;
3063 : }
3064 15349973 : if (bos)
3065 : {
3066 102 : tree arg = args[0];
3067 102 : STRIP_NOPS (arg);
3068 102 : if (TREE_CODE (arg) == ADDR_EXPR)
3069 102 : args[0] = arg;
3070 : }
3071 :
3072 15349973 : bool save_ffbcp = force_folding_builtin_constant_p;
3073 15349973 : force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true;
3074 15349973 : tree save_cur_fn = current_function_decl;
3075 : /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */
3076 15349973 : if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION)
3077 37 : && ctx->call
3078 15349977 : && ctx->call->fundef)
3079 4 : current_function_decl = ctx->call->fundef->decl;
3080 15349973 : if (fndecl_built_in_p (fun,
3081 : CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
3082 : BUILT_IN_FRONTEND))
3083 : {
3084 336 : location_t loc = EXPR_LOCATION (t);
3085 336 : if (nargs >= 1)
3086 333 : VERIFY_CONSTANT (args[0]);
3087 136 : new_call
3088 136 : = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
3089 : args);
3090 : }
3091 15349637 : else if (fndecl_built_in_p (fun,
3092 : CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
3093 : BUILT_IN_FRONTEND))
3094 : {
3095 471 : location_t loc = EXPR_LOCATION (t);
3096 471 : if (nargs >= 2)
3097 : {
3098 465 : VERIFY_CONSTANT (args[0]);
3099 237 : VERIFY_CONSTANT (args[1]);
3100 : }
3101 243 : new_call = fold_builtin_is_corresponding_member (loc, nargs, args);
3102 : }
3103 15349166 : else if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_STRING_LITERAL,
3104 : BUILT_IN_FRONTEND))
3105 : {
3106 4276 : location_t loc = EXPR_LOCATION (t);
3107 4276 : if (nargs >= 1)
3108 : {
3109 4276 : tree arg = CALL_EXPR_ARG (t, 0);
3110 4276 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3111 : non_constant_p, overflow_p,
3112 : jump_target);
3113 4276 : if (*jump_target)
3114 : return NULL_TREE;
3115 4276 : args[0] = arg;
3116 : }
3117 4276 : new_call = fold_builtin_is_string_literal (loc, nargs, args);
3118 : }
3119 : else
3120 30689780 : new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
3121 15344890 : CALL_EXPR_FN (t), nargs, args);
3122 15349545 : current_function_decl = save_cur_fn;
3123 15349545 : force_folding_builtin_constant_p = save_ffbcp;
3124 15349545 : if (new_call == NULL)
3125 : {
3126 10439498 : if (!*non_constant_p && !ctx->quiet)
3127 : {
3128 0 : new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
3129 0 : CALL_EXPR_FN (t), nargs, args);
3130 0 : error ("%q+E is not a constant expression", new_call);
3131 : }
3132 10439498 : *non_constant_p = true;
3133 10439498 : return t;
3134 : }
3135 :
3136 4910047 : if (!potential_constant_expression (new_call))
3137 : {
3138 861 : if (!*non_constant_p && !ctx->quiet)
3139 4 : error ("%q+E is not a constant expression", new_call);
3140 861 : *non_constant_p = true;
3141 861 : return t;
3142 : }
3143 :
3144 4909186 : if (strret)
3145 : {
3146 : /* memchr returns a pointer into the first argument, but we replaced the
3147 : argument above with a STRING_CST; put it back it now. */
3148 283 : tree op = CALL_EXPR_ARG (t, strret-1);
3149 283 : STRIP_NOPS (new_call);
3150 283 : if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
3151 142 : TREE_OPERAND (new_call, 0) = op;
3152 141 : else if (TREE_CODE (new_call) == ADDR_EXPR)
3153 4909186 : new_call = op;
3154 : }
3155 :
3156 4909186 : return cxx_eval_constant_expression (&new_ctx, new_call, lval,
3157 : non_constant_p, overflow_p,
3158 4909186 : jump_target);
3159 : }
3160 :
3161 : /* TEMP is the constant value of a temporary object of type TYPE. Adjust
3162 : the type of the value to match. */
3163 :
3164 : static tree
3165 136819057 : adjust_temp_type (tree type, tree temp)
3166 : {
3167 136819057 : if (same_type_p (TREE_TYPE (temp), type))
3168 : return temp;
3169 : /* Avoid wrapping an aggregate value in a NOP_EXPR. */
3170 62954841 : if (TREE_CODE (temp) == CONSTRUCTOR)
3171 : {
3172 : /* build_constructor wouldn't retain various CONSTRUCTOR flags. */
3173 3812882 : tree t = copy_node (temp);
3174 3812882 : TREE_TYPE (t) = type;
3175 3812882 : return t;
3176 : }
3177 59141959 : if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
3178 0 : return build0 (EMPTY_CLASS_EXPR, type);
3179 59141959 : gcc_assert (scalarish_type_p (type));
3180 : /* Now we know we're dealing with a scalar, and a prvalue of non-class
3181 : type is cv-unqualified. */
3182 59141959 : return cp_fold_convert (cv_unqualified (type), temp);
3183 : }
3184 :
3185 : /* If T is a CONSTRUCTOR, return an unshared copy of T and any
3186 : sub-CONSTRUCTORs. Otherwise return T.
3187 :
3188 : We use this whenever we initialize an object as a whole, whether it's a
3189 : parameter, a local variable, or a subobject, so that subsequent
3190 : modifications don't affect other places where it was used. */
3191 :
3192 : tree
3193 123567213 : unshare_constructor (tree t MEM_STAT_DECL)
3194 : {
3195 123567213 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
3196 : return t;
3197 18677270 : auto_vec <tree*, 4> ptrs;
3198 18677270 : ptrs.safe_push (&t);
3199 18677270 : while (!ptrs.is_empty ())
3200 : {
3201 24575015 : tree *p = ptrs.pop ();
3202 24575015 : tree n = copy_node (*p PASS_MEM_STAT);
3203 40776457 : CONSTRUCTOR_ELTS (n) = vec_safe_copy (CONSTRUCTOR_ELTS (*p) PASS_MEM_STAT);
3204 24575015 : *p = n;
3205 24575015 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n);
3206 24575015 : constructor_elt *ce;
3207 94415483 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i)
3208 : {
3209 26588183 : if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
3210 773 : ce->index = copy_node (ce->index PASS_MEM_STAT);
3211 26588183 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
3212 5897745 : ptrs.safe_push (&ce->value);
3213 : }
3214 : }
3215 18677270 : return t;
3216 18677270 : }
3217 :
3218 : /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs. */
3219 :
3220 : static void
3221 881634 : free_constructor (tree t)
3222 : {
3223 881634 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
3224 0 : return;
3225 881634 : releasing_vec ctors;
3226 881634 : vec_safe_push (ctors, t);
3227 2684307 : while (!ctors->is_empty ())
3228 : {
3229 921039 : tree c = ctors->pop ();
3230 921039 : if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c))
3231 : {
3232 : constructor_elt *ce;
3233 394318 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
3234 255267 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
3235 39405 : vec_safe_push (ctors, ce->value);
3236 139051 : ggc_free (elts);
3237 : }
3238 921039 : ggc_free (c);
3239 : }
3240 881634 : }
3241 :
3242 : /* Helper function of cxx_bind_parameters_in_call. Return non-NULL
3243 : if *TP is address of a static variable (or part of it) currently being
3244 : constructed or of a heap artificial variable. */
3245 :
3246 : static tree
3247 48164526 : addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data)
3248 : {
3249 48164526 : if (TREE_CODE (*tp) == ADDR_EXPR)
3250 8921839 : if (tree var = get_base_address (TREE_OPERAND (*tp, 0)))
3251 8921839 : if (VAR_P (var) && TREE_STATIC (var))
3252 : {
3253 5508157 : if (DECL_NAME (var) == heap_uninit_identifier
3254 5508157 : || DECL_NAME (var) == heap_identifier
3255 5508157 : || DECL_NAME (var) == heap_vec_uninit_identifier
3256 11016314 : || DECL_NAME (var) == heap_vec_identifier)
3257 : return var;
3258 :
3259 5508157 : constexpr_global_ctx *global = (constexpr_global_ctx *) data;
3260 5508157 : if (global->get_value (var))
3261 : return var;
3262 : }
3263 47717312 : if (TYPE_P (*tp))
3264 2493 : *walk_subtrees = false;
3265 : return NULL_TREE;
3266 : }
3267 :
3268 : /* Subroutine of cxx_eval_call_expression.
3269 : We are processing a call expression (either CALL_EXPR or
3270 : AGGR_INIT_EXPR) in the context of CTX. Evaluate
3271 : all arguments and bind their values to correspondings
3272 : parameters, making up the NEW_CALL context. */
3273 :
3274 : static tree
3275 184526375 : cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
3276 : tree orig_fun, bool *non_constant_p,
3277 : bool *overflow_p, bool *non_constant_args,
3278 : tree *jump_target)
3279 : {
3280 184526375 : int nargs = call_expr_nargs (t);
3281 184526375 : tree parms = DECL_ARGUMENTS (fun);
3282 184526375 : int i, j = 0;
3283 184526375 : if (DECL_HAS_IN_CHARGE_PARM_P (fun) && fun != orig_fun)
3284 1523 : ++nargs;
3285 184526375 : if (DECL_HAS_VTT_PARM_P (fun)
3286 1525 : && fun != orig_fun
3287 184527898 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3288 1082 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
3289 463 : ++nargs;
3290 : /* We don't record ellipsis args below. */
3291 184526375 : int nparms = list_length (parms);
3292 184526375 : int nbinds = nargs < nparms ? nargs : nparms;
3293 184526375 : tree binds = make_tree_vec (nbinds);
3294 :
3295 : /* The call is not a constant expression if it involves the cdtor for a type
3296 : with virtual bases before C++26. */
3297 184526375 : if (cxx_dialect < cxx26
3298 184526375 : && (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun)))
3299 : {
3300 17 : if (!ctx->quiet)
3301 : {
3302 3 : error_at (cp_expr_loc_or_input_loc (t),
3303 : "call to non-%<constexpr%> function %qD", fun);
3304 3 : explain_invalid_constexpr_fn (fun);
3305 : }
3306 17 : *non_constant_p = true;
3307 17 : return binds;
3308 : }
3309 :
3310 331644680 : for (i = 0; i < nargs; ++i)
3311 : {
3312 221493931 : tree x, arg;
3313 221493931 : tree type = parms ? TREE_TYPE (parms) : void_type_node;
3314 221493931 : if (parms && DECL_BY_REFERENCE (parms))
3315 26929 : type = TREE_TYPE (type);
3316 221493931 : if (i == 1
3317 221493931 : && j == 0
3318 47412875 : && DECL_HAS_IN_CHARGE_PARM_P (fun)
3319 221495322 : && orig_fun != fun)
3320 : {
3321 1391 : if (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3322 1391 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))
3323 428 : x = boolean_true_node;
3324 : else
3325 963 : x = boolean_false_node;
3326 : j = -1;
3327 : }
3328 221492540 : else if (i == 2
3329 221492540 : && j == -1
3330 1391 : && DECL_HAS_VTT_PARM_P (fun)
3331 1391 : && orig_fun != fun
3332 221493931 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
3333 985 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
3334 : {
3335 428 : x = build_zero_cst (type);
3336 428 : j = -2;
3337 : }
3338 : else
3339 221492112 : x = get_nth_callarg (t, i + j);
3340 : /* For member function, the first argument is a pointer to the implied
3341 : object. For a constructor, it might still be a dummy object, in
3342 : which case we get the real argument from ctx. */
3343 325068742 : if (i == 0 && DECL_CONSTRUCTOR_P (fun)
3344 244586486 : && is_dummy_object (x))
3345 : {
3346 11830859 : x = ctx->object;
3347 11830859 : x = build_address (x);
3348 : }
3349 221493931 : if (TREE_ADDRESSABLE (type))
3350 : {
3351 : /* Undo convert_for_arg_passing work here. */
3352 39401 : x = convert_from_reference (x);
3353 39401 : arg = cxx_eval_constant_expression (ctx, x, vc_glvalue,
3354 : non_constant_p, overflow_p,
3355 : jump_target);
3356 : }
3357 : else
3358 : /* Normally we would strip a TARGET_EXPR in an initialization context
3359 : such as this, but here we do the elision differently: we keep the
3360 : TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */
3361 221454530 : arg = cxx_eval_constant_expression (ctx, x, vc_prvalue,
3362 : non_constant_p, overflow_p,
3363 : jump_target);
3364 221493931 : if (*jump_target)
3365 : break;
3366 : /* Check we aren't dereferencing a null pointer when calling a non-static
3367 : member function, which is undefined behaviour. */
3368 162534316 : if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun)
3369 92449005 : && integer_zerop (arg)
3370 : /* But ignore calls from within compiler-generated code, to handle
3371 : cases like lambda function pointer conversion operator thunks
3372 : which pass NULL as the 'this' pointer. */
3373 221668529 : && !(TREE_CODE (t) == CALL_EXPR && CALL_FROM_THUNK_P (t)))
3374 : {
3375 527 : if (!ctx->quiet)
3376 6 : error_at (cp_expr_loc_or_input_loc (x),
3377 : "dereferencing a null pointer");
3378 527 : *non_constant_p = true;
3379 : }
3380 : /* Don't VERIFY_CONSTANT here. */
3381 221493847 : if (*non_constant_p && ctx->quiet)
3382 : break;
3383 : /* Just discard ellipsis args after checking their constantitude. */
3384 147118322 : if (!parms)
3385 360 : continue;
3386 :
3387 147117962 : if (!*non_constant_p)
3388 : {
3389 : /* Make sure the binding has the same type as the parm. But
3390 : only for constant args. */
3391 147117188 : if (TREE_ADDRESSABLE (type))
3392 : {
3393 26176 : if (!same_type_p (type, TREE_TYPE (arg)))
3394 : {
3395 9 : arg = build_fold_addr_expr (arg);
3396 9 : arg = cp_fold_convert (build_reference_type (type), arg);
3397 9 : arg = convert_from_reference (arg);
3398 : }
3399 : }
3400 147091012 : else if (!TYPE_REF_P (type))
3401 105545597 : arg = adjust_temp_type (type, arg);
3402 147117188 : if (!TREE_CONSTANT (arg))
3403 97130699 : *non_constant_args = true;
3404 49986489 : else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
3405 : /* The destructor needs to see any modifications the callee makes
3406 : to the argument. */
3407 0 : *non_constant_args = true;
3408 : /* If arg is or contains address of a heap artificial variable or
3409 : of a static variable being constructed, avoid caching the
3410 : function call, as those variables might be modified by the
3411 : function, or might be modified by the callers in between
3412 : the cached function and just read by the function. */
3413 49986489 : else if (!*non_constant_args
3414 49986489 : && cp_walk_tree (&arg, addr_of_non_const_var, ctx->global,
3415 : NULL))
3416 447214 : *non_constant_args = true;
3417 :
3418 : /* For virtual calls, adjust the this argument, so that it is
3419 : the object on which the method is called, rather than
3420 : one of its bases. */
3421 147117188 : if (i == 0 && DECL_VIRTUAL_P (fun))
3422 : {
3423 27404 : tree addr = arg;
3424 27404 : STRIP_NOPS (addr);
3425 27404 : if (TREE_CODE (addr) == ADDR_EXPR)
3426 : {
3427 27367 : tree obj = TREE_OPERAND (addr, 0);
3428 27367 : while (TREE_CODE (obj) == COMPONENT_REF
3429 11820 : && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))
3430 39265 : && !same_type_ignoring_top_level_qualifiers_p
3431 11727 : (TREE_TYPE (obj), DECL_CONTEXT (fun)))
3432 171 : obj = TREE_OPERAND (obj, 0);
3433 27367 : if (obj != TREE_OPERAND (addr, 0))
3434 168 : arg = build_fold_addr_expr_with_type (obj,
3435 : TREE_TYPE (arg));
3436 : }
3437 : }
3438 147117188 : TREE_VEC_ELT (binds, i) = arg;
3439 : }
3440 147117962 : parms = TREE_CHAIN (parms);
3441 : }
3442 :
3443 : return binds;
3444 : }
3445 :
3446 : static int
3447 109556501 : push_cx_call_context (tree call)
3448 : {
3449 109556501 : ++call_stack_tick;
3450 109556501 : if (!EXPR_HAS_LOCATION (call))
3451 78459 : SET_EXPR_LOCATION (call, input_location);
3452 109556501 : call_stack.safe_push (call);
3453 109556501 : int len = call_stack.length ();
3454 109556501 : if (len > max_constexpr_depth)
3455 33 : return false;
3456 : return len;
3457 : }
3458 :
3459 : static void
3460 109556497 : pop_cx_call_context (void)
3461 : {
3462 109556497 : ++call_stack_tick;
3463 109556497 : call_stack.pop ();
3464 109556497 : }
3465 :
3466 : vec<tree>
3467 258649 : cx_error_context (void)
3468 : {
3469 258649 : vec<tree> r = vNULL;
3470 258649 : if (call_stack_tick != last_cx_error_tick
3471 258649 : && !call_stack.is_empty ())
3472 : r = call_stack;
3473 258649 : last_cx_error_tick = call_stack_tick;
3474 258649 : return r;
3475 : }
3476 :
3477 : /* E is an operand of a failed assertion, fold it either with or without
3478 : constexpr context. */
3479 :
3480 : static tree
3481 829 : fold_operand (tree e, const constexpr_ctx *ctx)
3482 : {
3483 829 : if (ctx)
3484 : {
3485 32 : bool new_non_constant_p = false, new_overflow_p = false;
3486 32 : tree jmp_target = NULL_TREE;
3487 32 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
3488 : &new_non_constant_p,
3489 : &new_overflow_p, &jmp_target);
3490 : }
3491 : else
3492 797 : e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true);
3493 829 : return e;
3494 : }
3495 :
3496 : /* If we have a condition in conjunctive normal form (CNF), find the first
3497 : failing clause. In other words, given an expression like
3498 :
3499 : true && true && false && true && false
3500 :
3501 : return the first 'false'. EXPR is the expression. */
3502 :
3503 : static tree
3504 332 : find_failing_clause_r (const constexpr_ctx *ctx, tree expr)
3505 : {
3506 437 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3507 : {
3508 : /* First check the left side... */
3509 192 : tree e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 0));
3510 192 : if (e == NULL_TREE)
3511 : /* ...if we didn't find a false clause, check the right side. */
3512 105 : e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 1));
3513 : return e;
3514 : }
3515 245 : tree e = contextual_conv_bool (expr, tf_none);
3516 245 : e = fold_operand (e, ctx);
3517 245 : if (integer_zerop (e))
3518 : /* This is the failing clause. */
3519 140 : return expr;
3520 : return NULL_TREE;
3521 : }
3522 :
3523 : /* Wrapper for find_failing_clause_r. */
3524 :
3525 : tree
3526 1984 : find_failing_clause (const constexpr_ctx *ctx, tree expr)
3527 : {
3528 1984 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3529 140 : if (tree e = find_failing_clause_r (ctx, expr))
3530 1984 : expr = e;
3531 1984 : return expr;
3532 : }
3533 :
3534 : /* Emit additional diagnostics for failing condition BAD.
3535 : Used by finish_static_assert and IFN_ASSUME constexpr diagnostics.
3536 : If SHOW_EXPR_P is true, print the condition (because it was
3537 : instantiation-dependent). */
3538 :
3539 : void
3540 1984 : diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p,
3541 : const constexpr_ctx *ctx /* = nullptr */)
3542 : {
3543 : /* Nobody wants to see the artificial (bool) cast. */
3544 1984 : bad = tree_strip_nop_conversions (bad);
3545 1984 : if (TREE_CODE (bad) == CLEANUP_POINT_EXPR)
3546 3 : bad = TREE_OPERAND (bad, 0);
3547 :
3548 1984 : auto_diagnostic_nesting_level sentinel;
3549 :
3550 : /* Actually explain the failure if this is a concept check or a
3551 : requires-expression. */
3552 1984 : if (concept_check_p (bad) || TREE_CODE (bad) == REQUIRES_EXPR)
3553 334 : diagnose_constraints (cloc, bad, NULL_TREE);
3554 : /* Similarly if this is a standard trait. */
3555 1650 : else if (maybe_diagnose_standard_trait (cloc, bad))
3556 : ;
3557 1295 : else if (COMPARISON_CLASS_P (bad)
3558 1295 : && (ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))
3559 76 : || REFLECTION_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))))
3560 : {
3561 292 : tree op0 = fold_operand (TREE_OPERAND (bad, 0), ctx);
3562 292 : tree op1 = fold_operand (TREE_OPERAND (bad, 1), ctx);
3563 292 : tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
3564 292 : inform (cloc, "the comparison reduces to %qE", cond);
3565 : }
3566 1003 : else if (show_expr_p)
3567 755 : inform (cloc, "%qE evaluates to false", bad);
3568 1984 : }
3569 :
3570 : /* Process an assert/assume of ORIG_ARG. If it's not supposed to be evaluated,
3571 : do it without changing the current evaluation state. If it evaluates to
3572 : false, complain and return false; otherwise, return true. */
3573 :
3574 : static bool
3575 173593 : cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg,
3576 : location_t loc, bool evaluated,
3577 : bool *non_constant_p, bool *overflow_p)
3578 : {
3579 173593 : if (*non_constant_p)
3580 : return true;
3581 :
3582 173593 : tree eval, jmp_target = NULL_TREE;
3583 173593 : if (!evaluated)
3584 : {
3585 173593 : if (!potential_rvalue_constant_expression (arg))
3586 16 : return true;
3587 :
3588 173577 : constexpr_ctx new_ctx = *ctx;
3589 173577 : new_ctx.quiet = true;
3590 173577 : bool new_non_constant_p = false, new_overflow_p = false;
3591 : /* Avoid modification of existing values. */
3592 173577 : modifiable_tracker ms (new_ctx.global);
3593 173577 : eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3594 : &new_non_constant_p,
3595 : &new_overflow_p, &jmp_target);
3596 173577 : }
3597 : else
3598 0 : eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3599 : non_constant_p,
3600 : overflow_p, &jmp_target);
3601 173577 : if (jmp_target)
3602 : return true;
3603 :
3604 173577 : if (!*non_constant_p && integer_zerop (eval))
3605 : {
3606 42 : if (!ctx->quiet)
3607 : {
3608 : /* See if we can find which clause was failing
3609 : (for logical AND). */
3610 13 : tree bad = find_failing_clause (ctx, arg);
3611 : /* If not, or its location is unusable, fall back to the
3612 : previous location. */
3613 13 : location_t cloc = cp_expr_loc_or_loc (bad, loc);
3614 :
3615 : /* Report the error. */
3616 13 : auto_diagnostic_group d;
3617 13 : error_at (cloc, msg);
3618 13 : diagnose_failing_condition (bad, cloc, true, ctx);
3619 13 : return bad;
3620 13 : }
3621 29 : *non_constant_p = true;
3622 29 : return false;
3623 : }
3624 :
3625 : return true;
3626 : }
3627 :
3628 : /* Evaluate a call T to a GCC internal function when possible and return
3629 : the evaluated result or, under the control of CTX, give an error, set
3630 : NON_CONSTANT_P, and return the unevaluated call T otherwise. */
3631 :
3632 : static tree
3633 388244 : cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
3634 : value_cat lval,
3635 : bool *non_constant_p, bool *overflow_p,
3636 : tree *jump_target)
3637 : {
3638 388244 : enum tree_code opcode = ERROR_MARK;
3639 :
3640 388244 : switch (CALL_EXPR_IFN (t))
3641 : {
3642 166 : case IFN_UBSAN_NULL:
3643 166 : case IFN_UBSAN_BOUNDS:
3644 166 : case IFN_UBSAN_VPTR:
3645 166 : case IFN_FALLTHROUGH:
3646 166 : return void_node;
3647 :
3648 173593 : case IFN_ASSUME:
3649 173593 : if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0),
3650 : G_("failed %<assume%> attribute assumption"),
3651 173593 : EXPR_LOCATION (t), /*eval*/false,
3652 : non_constant_p, overflow_p))
3653 : return t;
3654 173564 : return void_node;
3655 :
3656 : case IFN_ADD_OVERFLOW:
3657 : opcode = PLUS_EXPR;
3658 : break;
3659 385 : case IFN_SUB_OVERFLOW:
3660 385 : opcode = MINUS_EXPR;
3661 385 : break;
3662 206750 : case IFN_MUL_OVERFLOW:
3663 206750 : opcode = MULT_EXPR;
3664 206750 : break;
3665 :
3666 96 : case IFN_LAUNDER:
3667 96 : return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3668 : vc_prvalue, non_constant_p,
3669 96 : overflow_p, jump_target);
3670 :
3671 0 : case IFN_DEFERRED_INIT:
3672 0 : return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
3673 :
3674 120 : case IFN_BSWAP:
3675 120 : case IFN_BITREVERSE:
3676 120 : {
3677 120 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3678 : vc_prvalue, non_constant_p,
3679 : overflow_p, jump_target);
3680 120 : if (*jump_target)
3681 : return NULL_TREE;
3682 120 : if (*non_constant_p)
3683 : return t;
3684 60 : location_t loc = cp_expr_loc_or_input_loc (t);
3685 60 : if (TREE_CODE (arg) != INTEGER_CST
3686 60 : || !INTEGRAL_TYPE_P (TREE_TYPE (arg))
3687 60 : || !TYPE_UNSIGNED (TREE_TYPE (arg))
3688 120 : || (CALL_EXPR_IFN (t) == IFN_BSWAP
3689 30 : && (TYPE_PRECISION (TREE_TYPE (arg)) % 8) != 0))
3690 : {
3691 0 : if (!ctx->quiet)
3692 0 : error_at (loc, "call to internal function %qE", t);
3693 0 : *non_constant_p = true;
3694 0 : return t;
3695 : }
3696 60 : return fold_build_builtin_bswapg_bitreverseg (loc, CALL_EXPR_IFN (t),
3697 60 : arg);
3698 : }
3699 :
3700 6634 : case IFN_VEC_CONVERT:
3701 6634 : {
3702 6634 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3703 : vc_prvalue, non_constant_p,
3704 : overflow_p, jump_target);
3705 6634 : if (*jump_target)
3706 : return NULL_TREE;
3707 6634 : if (TREE_CODE (arg) == VECTOR_CST)
3708 6237 : if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
3709 : return r;
3710 : }
3711 : /* FALLTHRU */
3712 :
3713 402 : default:
3714 402 : if (!ctx->quiet)
3715 0 : error_at (cp_expr_loc_or_input_loc (t),
3716 : "call to internal function %qE", t);
3717 402 : *non_constant_p = true;
3718 402 : return t;
3719 : }
3720 :
3721 : /* Evaluate constant arguments using OPCODE and return a complex
3722 : number containing the result and the overflow bit. */
3723 207635 : tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval,
3724 : non_constant_p, overflow_p,
3725 : jump_target);
3726 207635 : tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval,
3727 : non_constant_p, overflow_p,
3728 : jump_target);
3729 207635 : if (*jump_target)
3730 : return NULL_TREE;
3731 207635 : if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3732 : {
3733 2 : location_t loc = cp_expr_loc_or_input_loc (t);
3734 2 : tree type = TREE_TYPE (TREE_TYPE (t));
3735 2 : tree result = fold_binary_loc (loc, opcode, type,
3736 : fold_convert_loc (loc, type, arg0),
3737 : fold_convert_loc (loc, type, arg1));
3738 2 : tree ovf
3739 2 : = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1));
3740 : /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */
3741 2 : if (TREE_OVERFLOW (result))
3742 0 : TREE_OVERFLOW (result) = 0;
3743 :
3744 2 : return build_complex (TREE_TYPE (t), result, ovf);
3745 : }
3746 :
3747 207633 : *non_constant_p = true;
3748 207633 : return t;
3749 : }
3750 :
3751 : /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates. */
3752 :
3753 : static void
3754 6001400 : clear_no_implicit_zero (tree ctor)
3755 : {
3756 6001400 : if (CONSTRUCTOR_NO_CLEARING (ctor))
3757 : {
3758 1746046 : CONSTRUCTOR_NO_CLEARING (ctor) = false;
3759 7392032 : for (auto &e: CONSTRUCTOR_ELTS (ctor))
3760 2322106 : if (TREE_CODE (e.value) == CONSTRUCTOR)
3761 731036 : clear_no_implicit_zero (e.value);
3762 : }
3763 6001400 : }
3764 :
3765 : /* Complain about a const object OBJ being modified in a constant expression.
3766 : EXPR is the MODIFY_EXPR expression performing the modification. */
3767 :
3768 : static void
3769 65 : modifying_const_object_error (tree expr, tree obj)
3770 : {
3771 65 : location_t loc = cp_expr_loc_or_input_loc (expr);
3772 65 : auto_diagnostic_group d;
3773 130 : error_at (loc, "modifying a const object %qE is not allowed in "
3774 65 : "a constant expression", TREE_OPERAND (expr, 0));
3775 :
3776 : /* Find the underlying object that was declared as const. */
3777 65 : location_t decl_loc = UNKNOWN_LOCATION;
3778 207 : for (tree probe = obj; decl_loc == UNKNOWN_LOCATION; )
3779 77 : switch (TREE_CODE (probe))
3780 : {
3781 39 : case BIT_FIELD_REF:
3782 39 : case COMPONENT_REF:
3783 39 : {
3784 39 : tree elt = TREE_OPERAND (probe, 1);
3785 39 : if (CP_TYPE_CONST_P (TREE_TYPE (elt)))
3786 27 : decl_loc = DECL_SOURCE_LOCATION (elt);
3787 39 : probe = TREE_OPERAND (probe, 0);
3788 : }
3789 39 : break;
3790 :
3791 0 : case ARRAY_REF:
3792 0 : case REALPART_EXPR:
3793 0 : case IMAGPART_EXPR:
3794 0 : probe = TREE_OPERAND (probe, 0);
3795 0 : break;
3796 :
3797 38 : default:
3798 38 : decl_loc = location_of (probe);
3799 38 : break;
3800 : }
3801 65 : inform (decl_loc, "originally declared %<const%> here");
3802 65 : }
3803 :
3804 : /* Return true if FNDECL is a replaceable global allocation function that
3805 : should be usable during constant expression evaluation. */
3806 :
3807 : static inline bool
3808 38721576 : cxx_replaceable_global_alloc_fn (tree fndecl)
3809 : {
3810 38721576 : return (cxx_dialect >= cxx20
3811 36657186 : && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))
3812 2243081 : && CP_DECL_CONTEXT (fndecl) == global_namespace
3813 40964272 : && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)
3814 928120 : || DECL_IS_OPERATOR_DELETE_P (fndecl)));
3815 : }
3816 :
3817 : /* Return true if FNDECL is a placement new function that should be
3818 : usable during constant expression evaluation of std::construct_at. */
3819 :
3820 : static inline bool
3821 37239772 : cxx_placement_new_fn (tree fndecl)
3822 : {
3823 37239772 : return (cxx_dialect >= cxx20 && std_placement_new_fn_p (fndecl));
3824 : }
3825 :
3826 : /* Return true if FNDECL is std::construct_at. */
3827 :
3828 : static inline bool
3829 2369048 : is_std_construct_at (tree fndecl)
3830 : {
3831 2369048 : if (!decl_in_std_namespace_p (fndecl))
3832 : return false;
3833 :
3834 2324880 : tree name = DECL_NAME (fndecl);
3835 2324880 : return name && id_equal (name, "construct_at");
3836 : }
3837 :
3838 : /* Overload for the above taking constexpr_call*. */
3839 :
3840 : static inline bool
3841 2128054 : is_std_construct_at (const constexpr_call *call)
3842 : {
3843 2128054 : return (call
3844 1966051 : && call->fundef
3845 4094105 : && is_std_construct_at (call->fundef->decl));
3846 : }
3847 :
3848 : /* True if CTX is an instance of std::NAME class. */
3849 :
3850 : bool
3851 12368687 : is_std_class (tree ctx, const char *name)
3852 : {
3853 12368687 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3854 : return false;
3855 :
3856 12368065 : tree decl = TYPE_MAIN_DECL (ctx);
3857 12368065 : tree dname = DECL_NAME (decl);
3858 12368065 : if (dname == NULL_TREE || !id_equal (dname, name))
3859 : return false;
3860 :
3861 884531 : return decl_in_std_namespace_p (decl);
3862 : }
3863 :
3864 : /* True if CTX is an instance of std::allocator. */
3865 :
3866 : bool
3867 719751 : is_std_allocator (tree ctx)
3868 : {
3869 719751 : return is_std_class (ctx, "allocator");
3870 : }
3871 :
3872 : /* Return true if FNDECL is std::allocator<T>::allocate. */
3873 :
3874 : static bool
3875 108512 : is_std_allocator_allocate (tree fndecl)
3876 : {
3877 108512 : tree name = DECL_NAME (fndecl);
3878 108512 : if (name == NULL_TREE || !id_equal (name, "allocate"))
3879 : return false;
3880 :
3881 99967 : return is_std_allocator (DECL_CONTEXT (fndecl));
3882 : }
3883 :
3884 : /* Overload for the above taking constexpr_call*. */
3885 :
3886 : static inline bool
3887 119140 : is_std_allocator_allocate (const constexpr_call *call)
3888 : {
3889 119140 : return (call
3890 108512 : && call->fundef
3891 227652 : && is_std_allocator_allocate (call->fundef->decl));
3892 : }
3893 :
3894 : /* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
3895 :
3896 : static bool
3897 664934 : is_std_allocator_allocate_deallocate (tree fndecl)
3898 : {
3899 664934 : tree name = DECL_NAME (fndecl);
3900 664934 : if (name == NULL_TREE
3901 664934 : || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
3902 : return false;
3903 :
3904 618156 : return is_std_allocator (DECL_CONTEXT (fndecl));
3905 : }
3906 :
3907 : /* Overload for the above taking constexpr_call*. */
3908 :
3909 : static inline bool
3910 499300 : is_std_allocator_allocate_deallocate (const constexpr_call *call)
3911 : {
3912 499300 : return (call
3913 302144 : && call->fundef
3914 801444 : && is_std_allocator_allocate_deallocate (call->fundef->decl));
3915 : }
3916 :
3917 : /* Return true if FNDECL is std::source_location::current. */
3918 :
3919 : static inline bool
3920 58342 : is_std_source_location_current (tree fndecl)
3921 : {
3922 58342 : if (!decl_in_std_namespace_p (fndecl))
3923 : return false;
3924 :
3925 39155 : tree name = DECL_NAME (fndecl);
3926 39155 : if (name == NULL_TREE || !id_equal (name, "current"))
3927 : return false;
3928 :
3929 159 : tree ctx = DECL_CONTEXT (fndecl);
3930 159 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3931 : return false;
3932 :
3933 159 : name = DECL_NAME (TYPE_MAIN_DECL (ctx));
3934 159 : return name && id_equal (name, "source_location");
3935 : }
3936 :
3937 : /* Overload for the above taking constexpr_call*. */
3938 :
3939 : static inline bool
3940 85560 : is_std_source_location_current (const constexpr_call *call)
3941 : {
3942 85560 : return (call
3943 58342 : && call->fundef
3944 143902 : && is_std_source_location_current (call->fundef->decl));
3945 : }
3946 :
3947 : /* Return true if FNDECL is __dynamic_cast. */
3948 :
3949 : static inline bool
3950 36928918 : cxx_dynamic_cast_fn_p (tree fndecl)
3951 : {
3952 36928918 : return (cxx_dialect >= cxx20
3953 34864523 : && id_equal (DECL_NAME (fndecl), "__dynamic_cast")
3954 6788 : && CP_DECL_CONTEXT (fndecl) == abi_node
3955 : /* Only consider implementation-detail __dynamic_cast calls that
3956 : correspond to a dynamic_cast, and ignore direct calls to
3957 : abi::__dynamic_cast. */
3958 36935706 : && DECL_ARTIFICIAL (fndecl));
3959 : }
3960 :
3961 : /* Often, we have an expression in the form of address + offset, e.g.
3962 : "&_ZTV1A + 16". Extract the object from it, i.e. "_ZTV1A". */
3963 :
3964 : static tree
3965 5840 : extract_obj_from_addr_offset (tree expr)
3966 : {
3967 5840 : if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
3968 2786 : expr = TREE_OPERAND (expr, 0);
3969 5840 : STRIP_NOPS (expr);
3970 5840 : if (TREE_CODE (expr) == ADDR_EXPR)
3971 5829 : expr = TREE_OPERAND (expr, 0);
3972 5840 : return expr;
3973 : }
3974 :
3975 : /* Given a PATH like
3976 :
3977 : g.D.2181.D.2154.D.2102.D.2093
3978 :
3979 : find a component with type TYPE. Return NULL_TREE if not found, and
3980 : error_mark_node if the component is not accessible. If STOP is non-null,
3981 : this function will return NULL_TREE if STOP is found before TYPE. */
3982 :
3983 : static tree
3984 2831 : get_component_with_type (tree path, tree type, tree stop)
3985 : {
3986 7921 : while (true)
3987 : {
3988 5376 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path), type))
3989 : /* Found it. */
3990 : return path;
3991 3761 : else if (stop
3992 3761 : && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path),
3993 : stop)))
3994 : return NULL_TREE;
3995 3716 : else if (TREE_CODE (path) == COMPONENT_REF
3996 3716 : && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1)))
3997 : {
3998 : /* We need to check that the component we're accessing is in fact
3999 : accessible. */
4000 3716 : if (TREE_PRIVATE (TREE_OPERAND (path, 1))
4001 3716 : || TREE_PROTECTED (TREE_OPERAND (path, 1)))
4002 1171 : return error_mark_node;
4003 2545 : path = TREE_OPERAND (path, 0);
4004 : }
4005 : else
4006 : return NULL_TREE;
4007 : }
4008 : }
4009 :
4010 : /* Evaluate a call to __dynamic_cast (permitted by P1327R1).
4011 :
4012 : The declaration of __dynamic_cast is:
4013 :
4014 : void* __dynamic_cast (const void* __src_ptr,
4015 : const __class_type_info* __src_type,
4016 : const __class_type_info* __dst_type,
4017 : ptrdiff_t __src2dst);
4018 :
4019 : where src2dst has the following possible values
4020 :
4021 : >-1: src_type is a unique public non-virtual base of dst_type
4022 : dst_ptr + src2dst == src_ptr
4023 : -1: unspecified relationship
4024 : -2: src_type is not a public base of dst_type
4025 : -3: src_type is a multiple public non-virtual base of dst_type */
4026 :
4027 : static tree
4028 3173 : cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
4029 : bool *non_constant_p, bool *overflow_p,
4030 : tree *jump_target)
4031 : {
4032 : /* T will be something like
4033 : __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8)
4034 : dismantle it. */
4035 3173 : gcc_assert (call_expr_nargs (call) == 4);
4036 3173 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
4037 3173 : tree obj = CALL_EXPR_ARG (call, 0);
4038 3173 : tree type = CALL_EXPR_ARG (call, 2);
4039 3173 : HOST_WIDE_INT hint = int_cst_value (CALL_EXPR_ARG (call, 3));
4040 3173 : location_t loc = cp_expr_loc_or_input_loc (call);
4041 :
4042 : /* Get the target type of the dynamic_cast. */
4043 3173 : gcc_assert (TREE_CODE (type) == ADDR_EXPR);
4044 3173 : type = TREE_OPERAND (type, 0);
4045 3173 : type = TREE_TYPE (DECL_NAME (type));
4046 :
4047 : /* TYPE can only be either T* or T&. We can't know which of these it
4048 : is by looking at TYPE, but OBJ will be "(T*) x" in the first case,
4049 : and something like "(T*)(T&)(T*) x" in the second case.
4050 : This is true for the reference cases in C++ < 26 or when exceptions
4051 : aren't enabled, in that case we should diagnose errors. For C++26
4052 : with exceptions we should silently evaluate to null pointer and
4053 : let the callers call __cxa_bad_cast () later to throw an exception. */
4054 3173 : bool fail_for_non_constant_p = false;
4055 12899 : while (CONVERT_EXPR_P (obj) || TREE_CODE (obj) == SAVE_EXPR)
4056 : {
4057 9726 : if (cxx_dialect < cxx26 || !flag_exceptions)
4058 5557 : fail_for_non_constant_p |= TYPE_REF_P (TREE_TYPE (obj));
4059 9726 : obj = TREE_OPERAND (obj, 0);
4060 : }
4061 :
4062 : /* Evaluate the object so that we know its dynamic type. */
4063 3173 : obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p,
4064 : overflow_p, jump_target);
4065 3173 : if (*non_constant_p)
4066 : return call;
4067 3054 : if (*jump_target)
4068 : return NULL_TREE;
4069 :
4070 : /* For dynamic_cast from classes with virtual bases we can get something
4071 : like (virt_base *)(&d + 16) as OBJ. Try to convert that into
4072 : d.D.1234 using cxx_fold_indirect_ref. */
4073 3054 : if (cxx_dialect >= cxx26 && CONVERT_EXPR_P (obj))
4074 : {
4075 1206 : tree objo = obj;
4076 1206 : STRIP_NOPS (objo);
4077 1206 : if (TREE_CODE (objo) == POINTER_PLUS_EXPR)
4078 : {
4079 1152 : objo = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (TREE_TYPE (obj)),
4080 : obj, NULL, jump_target);
4081 1152 : if (objo)
4082 1152 : obj = build_fold_addr_expr (objo);
4083 : }
4084 : }
4085 :
4086 : /* We expect OBJ to be in form of &d.D.2102 when HINT == 0,
4087 : but when HINT is > 0, it can also be something like
4088 : &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET. */
4089 3054 : obj = extract_obj_from_addr_offset (obj);
4090 3054 : const tree objtype = TREE_TYPE (obj);
4091 : /* If OBJ doesn't refer to a base field, we're done. */
4092 6029 : if (tree t = (TREE_CODE (obj) == COMPONENT_REF
4093 3054 : ? TREE_OPERAND (obj, 1) : obj))
4094 3054 : if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t))
4095 : {
4096 79 : if (fail_for_non_constant_p)
4097 : {
4098 55 : if (!ctx->quiet)
4099 : {
4100 2 : auto_diagnostic_group d;
4101 2 : error_at (loc, "reference %<dynamic_cast%> failed");
4102 2 : inform (loc, "dynamic type %qT of its operand does "
4103 : "not have a base class of type %qT",
4104 : objtype, type);
4105 2 : }
4106 55 : *non_constant_p = true;
4107 : }
4108 79 : return integer_zero_node;
4109 : }
4110 :
4111 : /* [class.cdtor] When a dynamic_cast is used in a constructor ...
4112 : or in a destructor ... if the operand of the dynamic_cast refers
4113 : to the object under construction or destruction, this object is
4114 : considered to be a most derived object that has the type of the
4115 : constructor or destructor's class. */
4116 2975 : tree vtable = build_vfield_ref (obj, objtype);
4117 2975 : vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue,
4118 : non_constant_p, overflow_p,
4119 : jump_target);
4120 2975 : if (*non_constant_p)
4121 : return call;
4122 2798 : if (*jump_target)
4123 : return NULL_TREE;
4124 : /* With -fsanitize=vptr, we initialize all vtable pointers to null,
4125 : so it's possible that we got a null pointer now. */
4126 2798 : if (integer_zerop (vtable))
4127 : {
4128 12 : if (!ctx->quiet)
4129 3 : error_at (loc, "virtual table pointer is used uninitialized");
4130 12 : *non_constant_p = true;
4131 12 : return integer_zero_node;
4132 : }
4133 : /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */
4134 2786 : vtable = extract_obj_from_addr_offset (vtable);
4135 2786 : const tree mdtype = DECL_CONTEXT (vtable);
4136 :
4137 : /* Given dynamic_cast<T>(v),
4138 :
4139 : [expr.dynamic.cast] If C is the class type to which T points or refers,
4140 : the runtime check logically executes as follows:
4141 :
4142 : If, in the most derived object pointed (referred) to by v, v points
4143 : (refers) to a public base class subobject of a C object, and if only
4144 : one object of type C is derived from the subobject pointed (referred)
4145 : to by v the result points (refers) to that C object.
4146 :
4147 : In this case, HINT >= 0 or -3. */
4148 2786 : if (hint >= 0 || hint == -3)
4149 : {
4150 : /* Look for a component with type TYPE. */
4151 687 : tree t = get_component_with_type (obj, type, mdtype);
4152 : /* If not accessible, give an error. */
4153 687 : if (t == error_mark_node)
4154 : {
4155 198 : if (fail_for_non_constant_p)
4156 : {
4157 108 : if (!ctx->quiet)
4158 : {
4159 12 : auto_diagnostic_group d;
4160 12 : error_at (loc, "reference %<dynamic_cast%> failed");
4161 12 : inform (loc, "static type %qT of its operand is a "
4162 : "non-public base class of dynamic type %qT",
4163 : objtype, type);
4164 :
4165 12 : }
4166 108 : *non_constant_p = true;
4167 : }
4168 198 : return integer_zero_node;
4169 : }
4170 489 : else if (t)
4171 : /* The result points to the TYPE object. */
4172 444 : return cp_build_addr_expr (t, complain);
4173 : /* Else, TYPE was not found, because the HINT turned out to be wrong.
4174 : Fall through to the normal processing. */
4175 : }
4176 :
4177 : /* Otherwise, if v points (refers) to a public base class subobject of the
4178 : most derived object, and the type of the most derived object has a base
4179 : class, of type C, that is unambiguous and public, the result points
4180 : (refers) to the C subobject of the most derived object.
4181 :
4182 : But it can also be an invalid case. */
4183 :
4184 : /* Get the most derived object. */
4185 2144 : obj = get_component_with_type (obj, mdtype, NULL_TREE);
4186 2144 : if (obj == error_mark_node)
4187 : {
4188 973 : if (fail_for_non_constant_p)
4189 : {
4190 350 : if (!ctx->quiet)
4191 : {
4192 38 : auto_diagnostic_group d;
4193 38 : error_at (loc, "reference %<dynamic_cast%> failed");
4194 38 : inform (loc, "static type %qT of its operand is a non-public"
4195 : " base class of dynamic type %qT", objtype, mdtype);
4196 38 : }
4197 350 : *non_constant_p = true;
4198 : }
4199 973 : return integer_zero_node;
4200 : }
4201 : else
4202 1171 : gcc_assert (obj);
4203 :
4204 : /* Check that the type of the most derived object has a base class
4205 : of type TYPE that is unambiguous and public. */
4206 1171 : base_kind b_kind;
4207 1171 : tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none);
4208 1171 : if (!binfo || binfo == error_mark_node)
4209 : {
4210 441 : if (fail_for_non_constant_p)
4211 : {
4212 134 : if (!ctx->quiet)
4213 : {
4214 16 : auto_diagnostic_group d;
4215 16 : error_at (loc, "reference %<dynamic_cast%> failed");
4216 16 : if (b_kind == bk_ambig)
4217 6 : inform (loc, "%qT is an ambiguous base class of dynamic "
4218 : "type %qT of its operand", type, mdtype);
4219 : else
4220 10 : inform (loc, "dynamic type %qT of its operand does not "
4221 : "have an unambiguous public base class %qT",
4222 : mdtype, type);
4223 16 : }
4224 134 : *non_constant_p = true;
4225 : }
4226 441 : return integer_zero_node;
4227 : }
4228 : /* If so, return the TYPE subobject of the most derived object. */
4229 730 : obj = convert_to_base_statically (obj, binfo);
4230 730 : return cp_build_addr_expr (obj, complain);
4231 : }
4232 :
4233 : /* Data structure used by replace_decl and replace_decl_r. */
4234 :
4235 : struct replace_decl_data
4236 : {
4237 : /* The _DECL we want to replace. */
4238 : tree decl;
4239 : /* The replacement for DECL. */
4240 : tree replacement;
4241 : /* Trees we've visited. */
4242 : hash_set<tree> *pset;
4243 : /* Whether we've performed any replacements. */
4244 : bool changed;
4245 : };
4246 :
4247 : /* Helper function for replace_decl, called through cp_walk_tree. */
4248 :
4249 : static tree
4250 17066293 : replace_decl_r (tree *tp, int *walk_subtrees, void *data)
4251 : {
4252 17066293 : replace_decl_data *d = (replace_decl_data *) data;
4253 :
4254 : /* We could be replacing
4255 : &<retval>.bar -> &foo.bar
4256 : where foo is a static VAR_DECL, so we need to recompute TREE_CONSTANT
4257 : on the ADDR_EXPR around it. */
4258 17066293 : if (TREE_CODE (*tp) == ADDR_EXPR)
4259 : {
4260 1539069 : d->pset->add (*tp);
4261 1539069 : auto save_changed = d->changed;
4262 1539069 : d->changed = false;
4263 1539069 : cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr);
4264 1539069 : if (d->changed)
4265 : {
4266 1855 : cxx_mark_addressable (*tp);
4267 1855 : recompute_tree_invariant_for_addr_expr (*tp);
4268 : }
4269 : else
4270 1537214 : d->changed = save_changed;
4271 1539069 : *walk_subtrees = 0;
4272 : }
4273 15527224 : else if (*tp == d->decl)
4274 : {
4275 2095 : *tp = unshare_expr (d->replacement);
4276 2095 : d->changed = true;
4277 2095 : *walk_subtrees = 0;
4278 : }
4279 15525129 : else if (TYPE_P (*tp)
4280 15525129 : || d->pset->add (*tp))
4281 2835310 : *walk_subtrees = 0;
4282 :
4283 17066293 : return NULL_TREE;
4284 : }
4285 :
4286 : /* Replace every occurrence of DECL with (an unshared copy of)
4287 : REPLACEMENT within the expression *TP. Returns true iff a
4288 : replacement was performed. */
4289 :
4290 : bool
4291 2274915 : replace_decl (tree *tp, tree decl, tree replacement)
4292 : {
4293 2274915 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
4294 : (TREE_TYPE (decl), TREE_TYPE (replacement)));
4295 2274915 : hash_set<tree> pset;
4296 2274915 : replace_decl_data data = { decl, replacement, &pset, false };
4297 2274915 : cp_walk_tree (tp, replace_decl_r, &data, NULL);
4298 2274915 : return data.changed;
4299 2274915 : }
4300 :
4301 : /* Evaluate the call T to virtual function thunk THUNK_FNDECL. */
4302 :
4303 : static tree
4304 44 : cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl,
4305 : value_cat lval,
4306 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
4307 : {
4308 44 : tree function = THUNK_TARGET (thunk_fndecl);
4309 :
4310 44 : if (THUNK_VIRTUAL_OFFSET (thunk_fndecl))
4311 : {
4312 13 : if (!ctx->quiet)
4313 : {
4314 3 : if (!DECL_DECLARED_CONSTEXPR_P (function))
4315 : {
4316 0 : error ("call to non-%<constexpr%> function %qD", function);
4317 0 : explain_invalid_constexpr_fn (function);
4318 : }
4319 : else
4320 : /* virtual_offset is only set for virtual bases, which make the
4321 : class non-literal, so we don't need to handle it here. */
4322 3 : error ("calling constexpr member function %qD through virtual "
4323 : "base subobject", function);
4324 : }
4325 13 : *non_constant_p = true;
4326 13 : return t;
4327 : }
4328 :
4329 31 : tree new_call = copy_node (t);
4330 31 : CALL_EXPR_FN (new_call) = function;
4331 31 : TREE_TYPE (new_call) = TREE_TYPE (TREE_TYPE (function));
4332 :
4333 31 : tree offset = size_int (THUNK_FIXED_OFFSET (thunk_fndecl));
4334 :
4335 31 : if (DECL_THIS_THUNK_P (thunk_fndecl))
4336 : {
4337 : /* 'this'-adjusting thunk. */
4338 19 : tree this_arg = CALL_EXPR_ARG (t, 0);
4339 19 : this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg),
4340 : this_arg, offset);
4341 19 : CALL_EXPR_ARG (new_call, 0) = this_arg;
4342 : }
4343 : else
4344 : {
4345 : /* Return-adjusting thunk. As in expand_thunk, adjust a pointer only
4346 : if it is non-null. */
4347 12 : tree call = new_call;
4348 12 : if (TYPE_PTR_P (TREE_TYPE (call)))
4349 12 : call = save_expr (call);
4350 12 : new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (call), call, offset);
4351 12 : if (TYPE_PTR_P (TREE_TYPE (call)))
4352 12 : new_call = build_if_nonnull (call, new_call, tf_none);
4353 : }
4354 :
4355 31 : tree result = cxx_eval_constant_expression (ctx, new_call, lval,
4356 : non_constant_p, overflow_p,
4357 : jump_target);
4358 31 : if (!*non_constant_p
4359 27 : && !*overflow_p
4360 27 : && !*jump_target
4361 27 : && result != void_node
4362 27 : && INDIRECT_TYPE_P (TREE_TYPE (t))
4363 55 : && !(same_type_ignoring_top_level_qualifiers_p
4364 24 : (TREE_TYPE (result), TREE_TYPE (t))))
4365 15 : result = adjust_temp_type (TREE_TYPE (t), result);
4366 : return result;
4367 : }
4368 :
4369 : /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set
4370 : its TREE_READONLY flag according to READONLY_P. Used for constexpr
4371 : 'tors to detect modifying const objects in a constexpr context. */
4372 :
4373 : static void
4374 11185101 : cxx_set_object_constness (const constexpr_ctx *ctx, tree object,
4375 : bool readonly_p, bool *non_constant_p,
4376 : bool *overflow_p, tree *jump_target)
4377 : {
4378 22370202 : if (CLASS_TYPE_P (TREE_TYPE (object))
4379 22370202 : && CP_TYPE_CONST_P (TREE_TYPE (object)))
4380 : {
4381 : /* Subobjects might not be stored in ctx->global->values but we
4382 : can get its CONSTRUCTOR by evaluating *this. */
4383 1042148 : tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue,
4384 : non_constant_p, overflow_p,
4385 : jump_target);
4386 1042148 : if (!*non_constant_p
4387 12185564 : && !throws (jump_target)
4388 2042611 : && TREE_CODE (e) == CONSTRUCTOR)
4389 1000463 : TREE_READONLY (e) = readonly_p;
4390 : }
4391 11185101 : }
4392 :
4393 : /* Allocate an exception for OBJECT and throw it. */
4394 :
4395 : tree
4396 3164 : cxa_allocate_and_throw_exception (location_t loc, const constexpr_ctx *ctx,
4397 : tree object)
4398 : {
4399 3164 : tree type = TREE_TYPE (object);
4400 : /* This simulates a call to __cxa_allocate_exception. We need
4401 : (struct exception *) &heap -- memory on the heap so that
4402 : it can survive the stack being unwound. */
4403 3164 : tree arr = build_array_of_n_type (type, 1);
4404 3164 : tree var = cxa_allocate_exception (loc, ctx, arr, size_zero_node);
4405 3164 : DECL_NAME (var) = heap_identifier;
4406 3164 : ctx->global->put_value (var, NULL_TREE);
4407 :
4408 : /* *(struct exception *) &heap = exc{ ... } */
4409 3164 : tree ptr = build_nop (build_pointer_type (type), build_address (var));
4410 3164 : object = cp_build_init_expr (cp_build_fold_indirect_ref (ptr), object);
4411 3164 : bool non_constant_p = false, overflow_p = false;
4412 3164 : tree jump_target = NULL_TREE;
4413 3164 : cxx_eval_constant_expression (ctx, object, vc_prvalue, &non_constant_p,
4414 : &overflow_p, &jump_target);
4415 3164 : if (non_constant_p)
4416 : {
4417 0 : if (!ctx->quiet)
4418 0 : error_at (loc, "couldn%'t throw %qT", type);
4419 : return NULL_TREE;
4420 : }
4421 :
4422 : /* Now we can __cxa_throw. */
4423 3164 : DECL_EXCEPTION_REFCOUNT (var)
4424 3164 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (var), size_one_node);
4425 3164 : ++ctx->global->uncaught_exceptions;
4426 :
4427 3164 : return var;
4428 : }
4429 :
4430 : /* Subroutine of cxx_eval_constant_expression.
4431 : Evaluate the call expression tree T in the context of OLD_CALL expression
4432 : evaluation. */
4433 :
4434 : static tree
4435 206993461 : cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
4436 : value_cat lval,
4437 : bool *non_constant_p, bool *overflow_p,
4438 : tree *jump_target)
4439 : {
4440 206993461 : location_t loc = cp_expr_loc_or_input_loc (t);
4441 206993461 : tree fun = get_function_named_in_call (t);
4442 :
4443 206993461 : if (fun == NULL_TREE)
4444 388244 : return cxx_eval_internal_function (ctx, t, lval,
4445 : non_constant_p, overflow_p,
4446 388244 : jump_target);
4447 :
4448 206605217 : if (TREE_CODE (fun) != FUNCTION_DECL)
4449 : {
4450 : /* Might be a constexpr function pointer. */
4451 419654 : fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue,
4452 : non_constant_p, overflow_p,
4453 : jump_target);
4454 419654 : if (*jump_target)
4455 : return NULL_TREE;
4456 419654 : STRIP_NOPS (fun);
4457 419654 : if (TREE_CODE (fun) == ADDR_EXPR)
4458 31303 : fun = TREE_OPERAND (fun, 0);
4459 : /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
4460 : indirection, the called expression is a pointer into the
4461 : virtual table which should contain FDESC_EXPR. Extract the
4462 : FUNCTION_DECL from there. */
4463 : else if (TARGET_VTABLE_USES_DESCRIPTORS
4464 : && TREE_CODE (fun) == POINTER_PLUS_EXPR
4465 : && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
4466 : && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
4467 : {
4468 : tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
4469 : if (VAR_P (d)
4470 : && DECL_VTABLE_OR_VTT_P (d)
4471 : && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
4472 : && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
4473 : && DECL_INITIAL (d)
4474 : && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
4475 : {
4476 : tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
4477 : TYPE_SIZE_UNIT (vtable_entry_type));
4478 : HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
4479 : if (idx >= 0)
4480 : {
4481 : tree fdesc
4482 : = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
4483 : if (TREE_CODE (fdesc) == FDESC_EXPR
4484 : && integer_zerop (TREE_OPERAND (fdesc, 1)))
4485 : fun = TREE_OPERAND (fdesc, 0);
4486 : }
4487 : }
4488 : }
4489 : }
4490 206605217 : if (TREE_CODE (fun) != FUNCTION_DECL)
4491 : {
4492 388351 : if (!ctx->quiet && !*non_constant_p)
4493 0 : error_at (loc, "expression %qE does not designate a %<constexpr%> "
4494 : "function", fun);
4495 388351 : *non_constant_p = true;
4496 388351 : return t;
4497 : }
4498 206216866 : tree orig_fun = fun;
4499 206216866 : if (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun))
4500 24582036 : fun = DECL_CLONED_FUNCTION (fun);
4501 :
4502 206216866 : if (is_ubsan_builtin_p (fun))
4503 58 : return void_node;
4504 :
4505 206216808 : if (fndecl_built_in_p (fun))
4506 20742282 : return cxx_eval_builtin_function_call (ctx, t, fun,
4507 : lval, non_constant_p, overflow_p,
4508 20742280 : jump_target);
4509 185474526 : if (DECL_THUNK_P (fun))
4510 44 : return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p,
4511 44 : jump_target);
4512 185474482 : if (metafunction_p (fun))
4513 : {
4514 : /* To be able to evaluate a metafunction, we may have to instantiate
4515 : constexpr functions. If we're not allowed to instantiate, leave
4516 : this for later. Don't evaluate metafunctions at all when mce_unknown,
4517 : otherwise we might fold those prematurely. See
4518 : g++.dg/reflect/p2996-17.C. */
4519 82942 : if (uid_sensitive_constexpr_evaluation_p ()
4520 82380 : || ctx->manifestly_const_eval == mce_unknown)
4521 : {
4522 20924 : *non_constant_p = true;
4523 20924 : return t;
4524 : }
4525 62018 : ctx->global->state_dependent = true;
4526 62018 : tree e = process_metafunction (ctx, fun, t, non_constant_p, overflow_p,
4527 : jump_target);
4528 62018 : if (*jump_target)
4529 : return NULL_TREE;
4530 58842 : if (*non_constant_p)
4531 : return t;
4532 57774 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
4533 : non_constant_p, overflow_p,
4534 : jump_target);
4535 57774 : if (*jump_target)
4536 : return NULL_TREE;
4537 57774 : if (*non_constant_p)
4538 : return t;
4539 57768 : return e;
4540 : }
4541 185391540 : bool non_constexpr_call = false;
4542 185391540 : if (!maybe_constexpr_fn (fun))
4543 : {
4544 905842 : if (TREE_CODE (t) == CALL_EXPR
4545 898285 : && cxx_replaceable_global_alloc_fn (fun)
4546 1571555 : && (CALL_FROM_NEW_OR_DELETE_P (t)
4547 331656 : || is_std_allocator_allocate_deallocate (ctx->call)))
4548 : {
4549 495775 : const bool new_op_p = IDENTIFIER_NEW_OP_P (DECL_NAME (fun));
4550 495775 : const int nargs = call_expr_nargs (t);
4551 495775 : tree arg0 = NULL_TREE;
4552 787137 : for (int i = 0; i < nargs; ++i)
4553 : {
4554 496844 : tree arg = CALL_EXPR_ARG (t, i);
4555 496844 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4556 : non_constant_p, overflow_p,
4557 : jump_target);
4558 496844 : if (*jump_target)
4559 : return NULL_TREE;
4560 : /* Deleting a non-constant pointer has a better error message
4561 : below. */
4562 496834 : if (new_op_p || i != 0)
4563 416215 : VERIFY_CONSTANT (arg);
4564 210743 : if (i == 0)
4565 : arg0 = arg;
4566 : }
4567 290293 : gcc_assert (arg0);
4568 290293 : if (new_op_p)
4569 : {
4570 209674 : if (!tree_fits_uhwi_p (arg0))
4571 : {
4572 : /* We should not get here; the VERIFY_CONSTANT above
4573 : should have already caught it. */
4574 0 : gcc_checking_assert (false);
4575 : if (!ctx->quiet)
4576 : error_at (loc, "cannot allocate array: size not constant");
4577 : *non_constant_p = true;
4578 : return t;
4579 : }
4580 419348 : tree type = build_array_type_nelts (char_type_node,
4581 209674 : tree_to_uhwi (arg0));
4582 209674 : tree var = build_decl (loc, VAR_DECL,
4583 209674 : (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4584 : & OVL_OP_FLAG_VEC)
4585 : ? heap_vec_uninit_identifier
4586 : : heap_uninit_identifier,
4587 209674 : type);
4588 209674 : DECL_ARTIFICIAL (var) = 1;
4589 209674 : ctx->global->heap_vars.safe_push (var);
4590 209674 : ctx->global->put_value (var, NULL_TREE);
4591 209674 : return fold_convert (ptr_type_node, build_address (var));
4592 : }
4593 : else
4594 : {
4595 80619 : STRIP_NOPS (arg0);
4596 80619 : if (TREE_CODE (arg0) == ADDR_EXPR
4597 80619 : && VAR_P (TREE_OPERAND (arg0, 0)))
4598 : {
4599 80619 : tree var = TREE_OPERAND (arg0, 0);
4600 80619 : if (DECL_NAME (var) == heap_uninit_identifier
4601 80619 : || DECL_NAME (var) == heap_identifier)
4602 : {
4603 80445 : if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4604 : & OVL_OP_FLAG_VEC)
4605 : {
4606 9 : if (!ctx->quiet)
4607 : {
4608 3 : auto_diagnostic_group d;
4609 3 : error_at (loc, "array deallocation of object "
4610 : "allocated with non-array "
4611 : "allocation");
4612 3 : inform (DECL_SOURCE_LOCATION (var),
4613 : "allocation performed here");
4614 3 : }
4615 9 : *non_constant_p = true;
4616 9 : return t;
4617 : }
4618 80436 : DECL_NAME (var) = heap_deleted_identifier;
4619 80436 : ctx->global->destroy_value (var);
4620 80436 : ctx->global->heap_dealloc_count++;
4621 80436 : return void_node;
4622 : }
4623 174 : else if (DECL_NAME (var) == heap_vec_uninit_identifier
4624 174 : || DECL_NAME (var) == heap_vec_identifier)
4625 : {
4626 150 : if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4627 : & OVL_OP_FLAG_VEC) == 0)
4628 : {
4629 9 : if (!ctx->quiet)
4630 : {
4631 3 : auto_diagnostic_group d;
4632 3 : error_at (loc, "non-array deallocation of "
4633 : "object allocated with array "
4634 : "allocation");
4635 3 : inform (DECL_SOURCE_LOCATION (var),
4636 : "allocation performed here");
4637 3 : }
4638 9 : *non_constant_p = true;
4639 9 : return t;
4640 : }
4641 141 : DECL_NAME (var) = heap_deleted_identifier;
4642 141 : ctx->global->destroy_value (var);
4643 141 : ctx->global->heap_dealloc_count++;
4644 141 : return void_node;
4645 : }
4646 24 : else if (DECL_NAME (var) == heap_deleted_identifier)
4647 : {
4648 15 : if (!ctx->quiet)
4649 6 : error_at (loc, "deallocation of already deallocated "
4650 : "storage");
4651 15 : *non_constant_p = true;
4652 15 : return t;
4653 : }
4654 : }
4655 9 : if (!ctx->quiet)
4656 3 : error_at (loc, "deallocation of storage that was "
4657 : "not previously allocated");
4658 9 : *non_constant_p = true;
4659 9 : return t;
4660 : }
4661 : }
4662 : /* Allow placement new in std::construct_at, just return the second
4663 : argument. */
4664 410067 : if (TREE_CODE (t) == CALL_EXPR
4665 402510 : && cxx_placement_new_fn (fun)
4666 590871 : && is_std_construct_at (ctx->call))
4667 : {
4668 45973 : const int nargs = call_expr_nargs (t);
4669 45973 : tree arg1 = NULL_TREE;
4670 137919 : for (int i = 0; i < nargs; ++i)
4671 : {
4672 91946 : tree arg = CALL_EXPR_ARG (t, i);
4673 91946 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4674 : non_constant_p, overflow_p,
4675 : jump_target);
4676 91946 : if (*jump_target)
4677 : return NULL_TREE;
4678 91946 : if (i == 1)
4679 : arg1 = arg;
4680 : else
4681 91946 : VERIFY_CONSTANT (arg);
4682 : }
4683 45973 : gcc_assert (arg1);
4684 : return arg1;
4685 : }
4686 364094 : else if (cxx_dynamic_cast_fn_p (fun))
4687 3173 : return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p,
4688 3173 : jump_target);
4689 360921 : else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun))
4690 27937 : return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun,
4691 : non_constant_p, overflow_p,
4692 27937 : jump_target);
4693 :
4694 : /* Calls to non-constexpr functions can be diagnosed right away
4695 : before C++26, though in C++26 evaluation of the arguments might
4696 : throw and if caught it could be still constant expression.
4697 : So for C++26 this is diagnosed only after
4698 : cxx_bind_parameters_in_call. */
4699 332984 : if (cxx_dialect >= cxx26)
4700 : non_constexpr_call = true;
4701 : else
4702 : {
4703 292307 : if (!ctx->quiet)
4704 : {
4705 208 : if (!lambda_static_thunk_p (fun))
4706 208 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4707 208 : explain_invalid_constexpr_fn (fun);
4708 : }
4709 292307 : *non_constant_p = true;
4710 292307 : return t;
4711 : }
4712 : }
4713 :
4714 184526375 : constexpr_ctx new_ctx = *ctx;
4715 184526375 : ctx = &new_ctx;
4716 207618947 : if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
4717 188519984 : && TREE_CODE (t) == AGGR_INIT_EXPR)
4718 : {
4719 : /* We want to have an initialization target for an AGGR_INIT_EXPR.
4720 : If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
4721 2809 : new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
4722 2809 : tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
4723 2809 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
4724 2809 : ctx->global->put_value (new_ctx.object, ctor);
4725 : }
4726 : /* An immediate invocation is manifestly constant evaluated including the
4727 : arguments of the call, so use mce_true even for the argument
4728 : evaluation. */
4729 369052750 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
4730 4774412 : new_ctx.manifestly_const_eval = mce_true;
4731 :
4732 : /* We used to shortcut trivial constructor/op= here, but nowadays
4733 : we can only get a trivial function here with -fno-elide-constructors. */
4734 184526511 : gcc_checking_assert (!trivial_fn_p (fun)
4735 : || !flag_elide_constructors
4736 : /* Or it's a call from maybe_thunk_body (111075). */
4737 : || (TREE_CODE (t) == CALL_EXPR ? CALL_FROM_THUNK_P (t)
4738 : : AGGR_INIT_FROM_THUNK_P (t))
4739 : /* We don't elide constructors when processing
4740 : a noexcept-expression. */
4741 : || cp_noexcept_operand);
4742 :
4743 184526375 : bool non_constant_args = false;
4744 184526375 : constexpr_call new_call;
4745 184526375 : new_call.bindings
4746 184526375 : = cxx_bind_parameters_in_call (ctx, t, fun, orig_fun, non_constant_p,
4747 : overflow_p, &non_constant_args,
4748 : jump_target);
4749 :
4750 : /* We build up the bindings list before we know whether we already have this
4751 : call cached. If we don't end up saving these bindings, ggc_free them when
4752 : this function exits. */
4753 184526375 : class free_bindings
4754 : {
4755 : tree *bindings;
4756 : public:
4757 184526375 : free_bindings (tree &b): bindings (&b) { }
4758 184526371 : ~free_bindings () { if (bindings) ggc_free (*bindings); }
4759 4658176 : void preserve () { bindings = NULL; }
4760 184526375 : } fb (new_call.bindings);
4761 :
4762 184526375 : if (*jump_target)
4763 : return NULL_TREE;
4764 184526291 : if (*non_constant_p)
4765 : return t;
4766 110149998 : if (non_constexpr_call)
4767 : {
4768 6367 : if (!ctx->quiet)
4769 : {
4770 436 : if (!lambda_static_thunk_p (fun))
4771 436 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4772 436 : explain_invalid_constexpr_fn (fun);
4773 : }
4774 6367 : *non_constant_p = true;
4775 6367 : return t;
4776 : }
4777 :
4778 : /* We can't defer instantiating the function any longer. */
4779 110143631 : if (!DECL_INITIAL (fun)
4780 3143497 : && (DECL_TEMPLOID_INSTANTIATION (fun) || DECL_DEFAULTED_FN (fun))
4781 110143631 : && !uid_sensitive_constexpr_evaluation_p ())
4782 : {
4783 2900614 : location_t save_loc = input_location;
4784 2900614 : input_location = loc;
4785 2900614 : ++function_depth;
4786 2900614 : if (ctx->manifestly_const_eval == mce_true)
4787 369836 : FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true;
4788 2900614 : if (DECL_TEMPLOID_INSTANTIATION (fun))
4789 2900600 : instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
4790 : else
4791 14 : synthesize_method (fun);
4792 2900614 : --function_depth;
4793 2900614 : input_location = save_loc;
4794 : }
4795 :
4796 : /* If in direct recursive call, optimize definition search. */
4797 110143631 : if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun)
4798 29271 : new_call.fundef = ctx->call->fundef;
4799 : else
4800 : {
4801 110114360 : new_call.fundef = retrieve_constexpr_fundef (fun);
4802 110114360 : if (new_call.fundef == NULL || new_call.fundef->body == NULL
4803 109542861 : || new_call.fundef->result == error_mark_node
4804 109527236 : || fun == current_function_decl)
4805 : {
4806 587130 : if (!ctx->quiet)
4807 : {
4808 : /* We need to check for current_function_decl here in case we're
4809 : being called during cp_fold_function, because at that point
4810 : DECL_INITIAL is set properly and we have a fundef but we
4811 : haven't lowered invisirefs yet (c++/70344). */
4812 187 : if (DECL_INITIAL (fun) == error_mark_node
4813 187 : || fun == current_function_decl)
4814 15 : error_at (loc, "%qD called in a constant expression before its "
4815 : "definition is complete", fun);
4816 172 : else if (DECL_INITIAL (fun))
4817 : {
4818 : /* The definition of fun was somehow unsuitable. But pretend
4819 : that lambda static thunks don't exist. */
4820 134 : if (!lambda_static_thunk_p (fun))
4821 122 : error_at (loc, "%qD called in a constant expression", fun);
4822 134 : explain_invalid_constexpr_fn (fun);
4823 : }
4824 : else
4825 38 : error_at (loc, "%qD used before its definition", fun);
4826 : }
4827 587130 : *non_constant_p = true;
4828 587130 : return t;
4829 : }
4830 : }
4831 :
4832 : /* Don't complain about problems evaluating an ill-formed function. */
4833 109556501 : if (function *f = DECL_STRUCT_FUNCTION (fun))
4834 109556501 : if (f->language->erroneous)
4835 976 : new_ctx.quiet = true;
4836 :
4837 109556501 : int depth_ok = push_cx_call_context (t);
4838 :
4839 : /* Remember the object we are constructing or destructing. */
4840 109556501 : tree new_obj = NULL_TREE;
4841 219113002 : if (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))
4842 : {
4843 : /* In a cdtor, it should be the first `this' argument.
4844 : At this point it has already been evaluated in the call
4845 : to cxx_bind_parameters_in_call. */
4846 13814828 : new_obj = TREE_VEC_ELT (new_call.bindings, 0);
4847 13814828 : bool empty_base = false;
4848 13814828 : new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj,
4849 : &empty_base, jump_target);
4850 13814828 : if (*jump_target)
4851 0 : return NULL_TREE;
4852 : /* If we're initializing an empty class, don't set constness, because
4853 : cxx_fold_indirect_ref will return the wrong object to set constness
4854 : of. */
4855 13814828 : if (empty_base)
4856 : new_obj = NULL_TREE;
4857 6903595 : else if (ctx->call && ctx->call->fundef
4858 25050454 : && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl))
4859 : {
4860 3608695 : tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0);
4861 3608695 : STRIP_NOPS (cur_obj);
4862 3608695 : if (TREE_CODE (cur_obj) == ADDR_EXPR)
4863 3606190 : cur_obj = TREE_OPERAND (cur_obj, 0);
4864 3608695 : if (new_obj == cur_obj)
4865 : /* We're calling the target constructor of a delegating
4866 : constructor, or accessing a base subobject through a
4867 : NOP_EXPR as part of a call to a base constructor, so
4868 : there is no new (sub)object. */
4869 13814828 : new_obj = NULL_TREE;
4870 : }
4871 : }
4872 :
4873 109556501 : tree result = NULL_TREE;
4874 :
4875 109556501 : constexpr_call *entry = NULL;
4876 109556501 : if (depth_ok && !non_constant_args && ctx->strict)
4877 : {
4878 36959086 : new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
4879 36959086 : new_call.hash
4880 36959086 : = iterative_hash_template_arg (new_call.bindings, new_call.hash);
4881 :
4882 : /* If we have seen this call before, we are done. */
4883 36959086 : maybe_initialize_constexpr_call_table ();
4884 36959086 : bool insert = depth_ok < constexpr_cache_depth;
4885 36959086 : constexpr_call **slot
4886 50185796 : = constexpr_call_table->find_slot (&new_call,
4887 : insert ? INSERT : NO_INSERT);
4888 36959086 : entry = slot ? *slot : NULL;
4889 32580215 : if (entry == NULL)
4890 : {
4891 : /* Only cache up to constexpr_cache_depth to limit memory use. */
4892 9037047 : if (insert)
4893 : {
4894 : /* We need to keep a pointer to the entry, not just the slot, as
4895 : the slot can move during evaluation of the body. */
4896 4658176 : *slot = entry = ggc_alloc<constexpr_call> ();
4897 4658176 : *entry = new_call;
4898 4658176 : entry->result (ctx->manifestly_const_eval) = unknown_type_node;
4899 4658176 : fb.preserve ();
4900 :
4901 : /* Unshare args going into the hash table to separate them
4902 : from the caller's context, for better GC and to avoid
4903 : problems with verify_gimple. */
4904 4658176 : tree bound = new_call.bindings;
4905 7533612 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
4906 : {
4907 2875436 : tree &arg = TREE_VEC_ELT (bound, i);
4908 2875436 : arg = unshare_expr_without_location (arg);
4909 : }
4910 : }
4911 : }
4912 : /* Calls that are in progress have their result set to unknown_type_node,
4913 : so that we can detect circular dependencies. Now that we only cache
4914 : up to constexpr_cache_depth this won't catch circular dependencies that
4915 : start deeper, but they'll hit the recursion or ops limit. */
4916 27922039 : else if (entry->result (ctx->manifestly_const_eval) == unknown_type_node)
4917 : {
4918 6 : if (!ctx->quiet)
4919 0 : error ("call has circular dependency");
4920 6 : *non_constant_p = true;
4921 6 : entry->result (ctx->manifestly_const_eval) = result = error_mark_node;
4922 : }
4923 : else
4924 27922033 : result = entry->result (ctx->manifestly_const_eval);
4925 : }
4926 :
4927 109556468 : if (!depth_ok)
4928 : {
4929 33 : if (!ctx->quiet)
4930 3 : error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
4931 : "%<-fconstexpr-depth=%> to increase the maximum)",
4932 : max_constexpr_depth);
4933 33 : *non_constant_p = true;
4934 33 : result = error_mark_node;
4935 : }
4936 : else
4937 : {
4938 109556468 : bool cacheable = !!entry;
4939 109556468 : if (result && result != error_mark_node)
4940 : /* OK */;
4941 86767136 : else if (!DECL_SAVED_TREE (fun))
4942 : {
4943 : /* When at_eof >= 3, cgraph has started throwing away
4944 : DECL_SAVED_TREE, so fail quietly. FIXME we get here because of
4945 : late code generation for VEC_INIT_EXPR, which needs to be
4946 : completely reconsidered. */
4947 0 : gcc_assert (at_eof >= 3 && ctx->quiet);
4948 0 : *non_constant_p = true;
4949 : }
4950 86767136 : else if (tree copy = get_fundef_copy (new_call.fundef))
4951 : {
4952 86767127 : tree body, parms, res;
4953 86767127 : releasing_vec ctors;
4954 :
4955 : /* Reuse or create a new unshared copy of this function's body. */
4956 86767127 : body = TREE_PURPOSE (copy);
4957 86767127 : parms = TREE_VALUE (copy);
4958 86767127 : res = TREE_TYPE (copy);
4959 :
4960 : /* Associate the bindings with the remapped parms. */
4961 86767127 : tree bound = new_call.bindings;
4962 86767127 : tree remapped = parms;
4963 212349131 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
4964 : {
4965 125582004 : tree arg = TREE_VEC_ELT (bound, i);
4966 125582004 : if (entry)
4967 : {
4968 : /* Unshare again so the callee doesn't change the
4969 : argument values in the hash table. XXX Could we unshare
4970 : lazily in cxx_eval_store_expression? */
4971 3116230 : arg = unshare_constructor (arg);
4972 3116230 : if (TREE_CODE (arg) == CONSTRUCTOR)
4973 881138 : vec_safe_push (ctors, arg);
4974 : }
4975 125582004 : ctx->global->put_value (remapped, arg);
4976 125582004 : remapped = DECL_CHAIN (remapped);
4977 : }
4978 86767127 : if (remapped)
4979 : {
4980 : /* We shouldn't have any parms without args, but fail gracefully
4981 : in error recovery. */
4982 6 : gcc_checking_assert (seen_error ());
4983 6 : *non_constant_p = true;
4984 : }
4985 : /* Add the RESULT_DECL to the values map, too. */
4986 86767127 : gcc_assert (!DECL_BY_REFERENCE (res));
4987 86767127 : ctx->global->put_value (res, NULL_TREE);
4988 :
4989 : /* Remember the current call we're evaluating. */
4990 86767127 : constexpr_ctx call_ctx = *ctx;
4991 86767127 : call_ctx.call = &new_call;
4992 86767127 : unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
4993 86767127 : unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
4994 86767127 : bool save_state_dependent = ctx->global->state_dependent;
4995 :
4996 : /* Make sure we fold std::is_constant_evaluated to true in an
4997 : immediate function. */
4998 173534254 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
4999 2759416 : call_ctx.manifestly_const_eval = mce_true;
5000 :
5001 : /* If this is a constexpr destructor, the object's const and volatile
5002 : semantics are no longer in effect; see [class.dtor]p5. */
5003 97952228 : if (new_obj && DECL_DESTRUCTOR_P (fun))
5004 1254021 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false,
5005 : non_constant_p, overflow_p, jump_target);
5006 :
5007 : /* If this is a constructor, we are beginning the lifetime of the
5008 : object we are initializing. */
5009 86767127 : if (new_obj
5010 22370202 : && DECL_CONSTRUCTOR_P (fun)
5011 9931080 : && TREE_CODE (new_obj) == COMPONENT_REF
5012 89604661 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE)
5013 : {
5014 8212 : tree ctor = build_constructor (TREE_TYPE (new_obj), NULL);
5015 8212 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
5016 8212 : tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj),
5017 : new_obj, ctor);
5018 8212 : cxx_eval_constant_expression (ctx, activate,
5019 : lval, non_constant_p, overflow_p,
5020 : jump_target);
5021 8212 : ggc_free (activate);
5022 8212 : if (*jump_target)
5023 0 : return NULL_TREE;
5024 : }
5025 :
5026 86767127 : ctx->global->state_dependent = false;
5027 :
5028 86767127 : tree jmp_target = NULL_TREE;
5029 86767127 : cxx_eval_constant_expression (&call_ctx, body,
5030 : vc_discard, non_constant_p, overflow_p,
5031 : &jmp_target);
5032 :
5033 86767123 : if (!*non_constant_p && throws (&jmp_target))
5034 : {
5035 3683 : result = NULL_TREE;
5036 3683 : cacheable = false;
5037 3683 : *jump_target = jmp_target;
5038 : }
5039 86763440 : else if (!*non_constant_p && TREE_THIS_VOLATILE (fun))
5040 : {
5041 : /* Return from a [[noreturn]] function. */
5042 11 : if (!ctx->quiet)
5043 5 : error ("%<[[noreturn]]%> call returns");
5044 11 : *non_constant_p = true;
5045 : }
5046 173526858 : else if (DECL_CONSTRUCTOR_P (fun))
5047 : /* This can be null for a subobject constructor call, in
5048 : which case what we care about is the initialization
5049 : side-effects rather than the value. We could get at the
5050 : value by evaluating *this, but we don't bother; there's
5051 : no need to put such a call in the hash table. */
5052 12390892 : result = lval ? ctx->object : ctx->ctor;
5053 74372537 : else if (VOID_TYPE_P (TREE_TYPE (res)))
5054 7384043 : result = void_node;
5055 : else
5056 : {
5057 66988494 : result = ctx->global->get_value (res);
5058 10974969 : if (result == NULL_TREE && !*non_constant_p
5059 66988714 : && !DECL_DESTRUCTOR_P (fun))
5060 : {
5061 110 : if (!ctx->quiet)
5062 6 : error ("%<constexpr%> call flows off the end "
5063 : "of the function");
5064 110 : *non_constant_p = true;
5065 : }
5066 : }
5067 :
5068 86767123 : if (ctx->global->state_dependent)
5069 65830 : cacheable = false;
5070 86767123 : ctx->global->state_dependent |= save_state_dependent;
5071 :
5072 : /* At this point, the object's constructor will have run, so
5073 : the object is no longer under construction, and its possible
5074 : 'const' semantics now apply. Make a note of this fact by
5075 : marking the CONSTRUCTOR TREE_READONLY. */
5076 97952224 : if (new_obj && DECL_CONSTRUCTOR_P (fun))
5077 9931080 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true,
5078 : non_constant_p, overflow_p, jump_target);
5079 :
5080 : /* Remove the parms/result from the values map. */
5081 86767123 : destroy_value_checked (ctx, res, non_constant_p);
5082 299116254 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
5083 125582008 : destroy_value_checked (ctx, parm, non_constant_p);
5084 :
5085 : /* Free any parameter CONSTRUCTORs we aren't returning directly. */
5086 87648261 : while (!ctors->is_empty ())
5087 : {
5088 881138 : tree c = ctors->pop ();
5089 881138 : if (c != result)
5090 881138 : free_constructor (c);
5091 : }
5092 :
5093 : /* Make the unshared function copy we used available for re-use. */
5094 86767123 : save_fundef_copy (fun, copy);
5095 :
5096 : /* If the call allocated some heap object that hasn't been
5097 : deallocated during the call, or if it deallocated some heap
5098 : object it has not allocated, the call isn't really stateless
5099 : for the constexpr evaluation and should not be cached.
5100 : It is fine if the call allocates something and deallocates it
5101 : too. */
5102 86767123 : if (cacheable
5103 96553095 : && (save_heap_alloc_count != ctx->global->heap_vars.length ()
5104 9781471 : || (save_heap_dealloc_count
5105 9781471 : != ctx->global->heap_dealloc_count)))
5106 : {
5107 4501 : tree heap_var;
5108 4501 : unsigned int i;
5109 4501 : if ((ctx->global->heap_vars.length ()
5110 4501 : - ctx->global->heap_dealloc_count)
5111 4501 : != save_heap_alloc_count - save_heap_dealloc_count)
5112 : cacheable = false;
5113 : else
5114 139075 : FOR_EACH_VEC_ELT_FROM (ctx->global->heap_vars, i, heap_var,
5115 : save_heap_alloc_count)
5116 136450 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
5117 : {
5118 : cacheable = false;
5119 : break;
5120 : }
5121 : }
5122 :
5123 : /* Rewrite all occurrences of the function's RESULT_DECL with the
5124 : current object under construction. */
5125 86767123 : if (!*non_constant_p
5126 72100313 : && ctx->object
5127 17241441 : && CLASS_TYPE_P (TREE_TYPE (res))
5128 89966962 : && !is_empty_class (TREE_TYPE (res)))
5129 : {
5130 2274769 : if (!same_type_ignoring_top_level_qualifiers_p
5131 2274769 : (TREE_TYPE (res), TREE_TYPE (ctx->object)))
5132 0 : *non_constant_p = true;
5133 2274769 : else if (replace_decl (&result, res, ctx->object))
5134 : {
5135 1791 : cacheable = false;
5136 1791 : result = cxx_eval_constant_expression (ctx, result, lval,
5137 : non_constant_p,
5138 : overflow_p,
5139 : jump_target);
5140 1791 : if (*jump_target)
5141 : {
5142 0 : cacheable = false;
5143 0 : result = NULL_TREE;
5144 : }
5145 : }
5146 : }
5147 :
5148 : /* Only cache a permitted result of a constant expression. */
5149 86765332 : if (cacheable && !reduced_constant_expression_p (result))
5150 : cacheable = false;
5151 :
5152 : /* Only cache a result without contract violations. */
5153 81725805 : if (cacheable && ctx->global->contract_statement)
5154 82024834 : cacheable = false;
5155 86767123 : }
5156 : else
5157 : /* Couldn't get a function copy to evaluate. */
5158 9 : *non_constant_p = true;
5159 :
5160 109556464 : if (result == error_mark_node)
5161 6 : *non_constant_p = true;
5162 109556464 : if (*non_constant_p || *overflow_p)
5163 14666975 : result = error_mark_node;
5164 94889489 : else if (!result)
5165 3951004 : result = void_node;
5166 109556464 : if (entry)
5167 : {
5168 65160426 : entry->result (ctx->manifestly_const_eval)
5169 32580213 : = cacheable ? result : error_mark_node;
5170 :
5171 32580213 : if (result != error_mark_node
5172 27605778 : && ctx->manifestly_const_eval == mce_unknown)
5173 : {
5174 : /* Evaluation succeeded and was independent of whether we're in a
5175 : manifestly constant-evaluated context, so we can also reuse
5176 : this result when evaluating this call with a fixed context. */
5177 1923899 : if (!entry->result (mce_true))
5178 714459 : entry->result (mce_true) = entry->result (mce_unknown);
5179 1923899 : if (!entry->result (mce_false))
5180 681280 : entry->result (mce_false) = entry->result (mce_unknown);
5181 : }
5182 : }
5183 : }
5184 :
5185 : /* The result of a constexpr function must be completely initialized.
5186 :
5187 : However, in C++20, a constexpr constructor doesn't necessarily have
5188 : to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
5189 : in order to detect reading an uninitialized object in constexpr instead
5190 : of value-initializing it. (reduced_constant_expression_p is expected to
5191 : take care of clearing the flag.) */
5192 109556497 : if (TREE_CODE (result) == CONSTRUCTOR
5193 109556497 : && (cxx_dialect < cxx20
5194 21479634 : || !DECL_CONSTRUCTOR_P (fun)))
5195 5270364 : clear_no_implicit_zero (result);
5196 :
5197 109556497 : pop_cx_call_context ();
5198 :
5199 : /* A virtual call with a zero-offset covariant return needs no thunk, so
5200 : constant evaluation can evaluate the final overrider directly. The
5201 : result then has the overrider's return type rather than the static type
5202 : of the call. Adjust after caching so a direct call can reuse the result
5203 : with its original type. */
5204 109556497 : if (!*non_constant_p
5205 94889645 : && !*overflow_p
5206 94889489 : && !*jump_target
5207 94885806 : && DECL_VIRTUAL_P (fun)
5208 26460 : && result != void_node
5209 2173 : && INDIRECT_TYPE_P (TREE_TYPE (t))
5210 109557506 : && !(same_type_ignoring_top_level_qualifiers_p
5211 1009 : (TREE_TYPE (result), TREE_TYPE (t))))
5212 11 : result = adjust_temp_type (TREE_TYPE (t), result);
5213 :
5214 109556497 : return result;
5215 184526371 : }
5216 :
5217 : /* Return true if T is a valid constant initializer. If a CONSTRUCTOR
5218 : initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
5219 : cleared. If called recursively on a FIELD_DECL's CONSTRUCTOR, SZ
5220 : is DECL_SIZE of the FIELD_DECL, otherwise NULL.
5221 : UNION_ELEMENTAL_SUBOBJECT is true when recursing on union elemental
5222 : subobjects.
5223 : FIXME speed this up, it's taking 16% of compile time on sieve testcase. */
5224 :
5225 : bool
5226 1246709405 : reduced_constant_expression_p (tree t, tree sz /* = NULL_TREE */,
5227 : bool union_elemental_subobject /* = false */)
5228 : {
5229 1246709405 : if (t == NULL_TREE)
5230 : return false;
5231 :
5232 1241740204 : switch (TREE_CODE (t))
5233 : {
5234 : case PTRMEM_CST:
5235 : case REFLECT_EXPR:
5236 : /* Even if we can't lower this yet, it's constant. */
5237 : return true;
5238 :
5239 : case OMP_DECLARE_MAPPER:
5240 : return true;
5241 :
5242 64025448 : case CONSTRUCTOR:
5243 : /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
5244 64025448 : tree field;
5245 64025448 : if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
5246 : /* A constant vector would be folded to VECTOR_CST.
5247 : A CONSTRUCTOR of scalar type means uninitialized. */
5248 : return false;
5249 64008871 : if (CONSTRUCTOR_NO_CLEARING (t))
5250 : {
5251 3509532 : if (union_elemental_subobject
5252 5261 : && cxx_dialect >= cxx26
5253 1954 : && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
5254 3510734 : && CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (t))
5255 : field = NULL_TREE;
5256 3509164 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
5257 : {
5258 : /* There must be a valid constant initializer at every array
5259 : index. */
5260 6089 : tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
5261 6089 : tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
5262 6089 : tree cursor = min;
5263 96687 : for (auto &e: CONSTRUCTOR_ELTS (t))
5264 : {
5265 78639 : if (!reduced_constant_expression_p
5266 78639 : (e.value, NULL_TREE, union_elemental_subobject))
5267 : return false;
5268 78480 : if (array_index_cmp (cursor, e.index) != 0)
5269 : return false;
5270 78420 : if (TREE_CODE (e.index) == RANGE_EXPR)
5271 0 : cursor = TREE_OPERAND (e.index, 1);
5272 78420 : if (TREE_CODE (e.value) == RAW_DATA_CST)
5273 0 : cursor
5274 0 : = int_const_binop (PLUS_EXPR, cursor,
5275 0 : size_int (RAW_DATA_LENGTH (e.value)));
5276 : else
5277 78420 : cursor = int_const_binop (PLUS_EXPR, cursor,
5278 78420 : size_one_node);
5279 : }
5280 5870 : if (find_array_ctor_elt (t, max) == -1)
5281 : return false;
5282 5599 : goto ok;
5283 : }
5284 3503075 : else if (cxx_dialect >= cxx20
5285 3503075 : && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
5286 : {
5287 : /* A union can have at most one active member. A union with no
5288 : active member has no constituent values, so all constituent
5289 : values are constant. */
5290 : field = NULL_TREE;
5291 : union_elemental_subobject = true;
5292 : }
5293 : else
5294 : {
5295 3499499 : field = next_subobject_field (TYPE_FIELDS (TREE_TYPE (t)));
5296 3499499 : union_elemental_subobject = false;
5297 : }
5298 : }
5299 : else
5300 : {
5301 60499339 : field = NULL_TREE;
5302 60499339 : if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
5303 : union_elemental_subobject = true;
5304 59541486 : else if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE)
5305 56800890 : union_elemental_subobject = false;
5306 : }
5307 602778228 : for (auto &e: CONSTRUCTOR_ELTS (t))
5308 : {
5309 : /* If VAL is null, we're in the middle of initializing this
5310 : element. */
5311 470816723 : if (!reduced_constant_expression_p (e.value,
5312 470816723 : (e.index
5313 470816687 : && (TREE_CODE (e.index)
5314 : == FIELD_DECL))
5315 59491690 : ? DECL_SIZE (e.index)
5316 : : NULL_TREE,
5317 : union_elemental_subobject))
5318 : return false;
5319 : /* We want to remove initializers for empty fields in a struct to
5320 : avoid confusing output_constructor. */
5321 470239772 : if (is_empty_field (e.index)
5322 470239772 : && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
5323 : return false;
5324 : /* Check for non-empty fields between initialized fields when
5325 : CONSTRUCTOR_NO_CLEARING. */
5326 469115664 : for (; field && e.index != field;
5327 384210 : field = next_subobject_field (DECL_CHAIN (field)))
5328 388958 : if (!is_really_empty_class (TREE_TYPE (field),
5329 : /*ignore_vptr*/false))
5330 : return false;
5331 468726706 : if (field)
5332 3989644 : field = next_subobject_field (DECL_CHAIN (field));
5333 : }
5334 : /* There could be a non-empty field at the end. */
5335 62199739 : for (; field; field = next_subobject_field (DECL_CHAIN (field)))
5336 293806 : if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false))
5337 : {
5338 : /* Ignore FIELD_DECLs with bit positions beyond DECL_SIZE of
5339 : the parent FIELD_DECL (if any) for classes with virtual
5340 : bases. */
5341 6832 : if (cxx_dialect >= cxx26
5342 4334 : && sz
5343 7352 : && tree_int_cst_le (sz, bit_position (field)))
5344 : break;
5345 : return false;
5346 : }
5347 61905933 : ok:
5348 61911924 : if (CONSTRUCTOR_NO_CLEARING (t))
5349 : /* All the fields are initialized. */
5350 3376157 : CONSTRUCTOR_NO_CLEARING (t) = false;
5351 : return true;
5352 :
5353 1177394826 : default:
5354 : /* FIXME are we calling this too much? */
5355 1177394826 : return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
5356 : }
5357 : }
5358 :
5359 : /* *TP was not deemed constant by reduced_constant_expression_p. Explain
5360 : why and suggest what could be done about it. */
5361 :
5362 : static tree
5363 1602 : verify_constant_explain_r (tree *tp, int *walk_subtrees, void *)
5364 : {
5365 1602 : bool ref_p = false;
5366 :
5367 : /* No need to look into types or unevaluated operands. */
5368 1602 : if (TYPE_P (*tp) || unevaluated_p (TREE_CODE (*tp)))
5369 : {
5370 0 : *walk_subtrees = false;
5371 0 : return NULL_TREE;
5372 : }
5373 :
5374 1602 : switch (TREE_CODE (*tp))
5375 : {
5376 104 : CASE_CONVERT:
5377 104 : if (TREE_CODE (TREE_OPERAND (*tp, 0)) != ADDR_EXPR)
5378 : break;
5379 85 : ref_p = TYPE_REF_P (TREE_TYPE (*tp));
5380 85 : *tp = TREE_OPERAND (*tp, 0);
5381 217 : gcc_fallthrough ();
5382 217 : case ADDR_EXPR:
5383 217 : {
5384 217 : tree op = TREE_OPERAND (*tp, 0);
5385 217 : if (VAR_P (op)
5386 116 : && DECL_DECLARED_CONSTEXPR_P (op)
5387 39 : && !TREE_STATIC (op)
5388 : /* ??? We should also say something about temporaries. */
5389 253 : && !DECL_ARTIFICIAL (op))
5390 : {
5391 33 : if (ref_p)
5392 12 : inform (location_of (*tp), "reference to %qD is not a constant "
5393 : "expression", op);
5394 : else
5395 21 : inform (location_of (*tp), "pointer to %qD is not a constant "
5396 : "expression", op);
5397 33 : const location_t op_loc = DECL_SOURCE_LOCATION (op);
5398 33 : rich_location richloc (line_table, op_loc);
5399 33 : richloc.add_fixit_insert_before (op_loc, "static ");
5400 33 : inform (&richloc,
5401 : "address of non-static constexpr variable %qD may differ on "
5402 : "each invocation of the enclosing function; add %<static%> "
5403 : "to give it a constant address", op);
5404 33 : }
5405 : break;
5406 : }
5407 : default:
5408 : break;
5409 : }
5410 :
5411 : return NULL_TREE;
5412 : }
5413 :
5414 : /* Some expressions may have constant operands but are not constant
5415 : themselves, such as 1/0. Call this function to check for that
5416 : condition.
5417 :
5418 : We only call this in places that require an arithmetic constant, not in
5419 : places where we might have a non-constant expression that can be a
5420 : component of a constant expression, such as the address of a constexpr
5421 : variable that might be dereferenced later. */
5422 :
5423 : static bool
5424 674183100 : verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
5425 : bool *overflow_p)
5426 : {
5427 661167717 : if (!*non_constant_p && !reduced_constant_expression_p (t)
5428 677123315 : && t != void_node)
5429 : {
5430 2939780 : if (!allow_non_constant)
5431 : {
5432 422 : auto_diagnostic_group d;
5433 577 : error_at (cp_expr_loc_or_input_loc (t),
5434 : "%q+E is not a constant expression", t);
5435 422 : cp_walk_tree_without_duplicates (&t, verify_constant_explain_r,
5436 : nullptr);
5437 422 : }
5438 2939780 : *non_constant_p = true;
5439 : }
5440 674183100 : if (TREE_OVERFLOW_P (t))
5441 : {
5442 678 : if (!allow_non_constant)
5443 : {
5444 155 : permerror (input_location, "overflow in constant expression");
5445 : /* If we're being permissive (and are in an enforcing
5446 : context), ignore the overflow. */
5447 155 : if (flag_permissive)
5448 75 : return *non_constant_p;
5449 : }
5450 603 : *overflow_p = true;
5451 : }
5452 674183025 : return *non_constant_p;
5453 : }
5454 :
5455 : /* Check whether the shift operation with code CODE and type TYPE on LHS
5456 : and RHS is undefined. If it is, give an error with an explanation,
5457 : and return true; return false otherwise. */
5458 :
5459 : static bool
5460 80284515 : cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
5461 : enum tree_code code, tree type, tree lhs, tree rhs)
5462 : {
5463 80284515 : if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
5464 5581639 : || TREE_CODE (lhs) != INTEGER_CST
5465 5581363 : || TREE_CODE (rhs) != INTEGER_CST)
5466 : return false;
5467 :
5468 5581363 : tree lhstype = TREE_TYPE (lhs);
5469 5581363 : unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
5470 :
5471 : /* [expr.shift] The behavior is undefined if the right operand
5472 : is negative, or greater than or equal to the length in bits
5473 : of the promoted left operand. */
5474 5581363 : if (tree_int_cst_sgn (rhs) == -1)
5475 : {
5476 126 : if (!ctx->quiet)
5477 35 : permerror (loc, "right operand of shift expression %q+E is negative",
5478 : build2_loc (loc, code, type, lhs, rhs));
5479 126 : return (!flag_permissive || ctx->quiet);
5480 : }
5481 5581237 : if (compare_tree_int (rhs, uprec) >= 0)
5482 : {
5483 200 : if (!ctx->quiet)
5484 34 : permerror (loc, "right operand of shift expression %q+E is greater "
5485 : "than or equal to the precision %wu of the left operand",
5486 : build2_loc (loc, code, type, lhs, rhs), uprec);
5487 200 : return (!flag_permissive || ctx->quiet);
5488 : }
5489 :
5490 : /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
5491 : if E1 has a signed type and non-negative value, and E1x2^E2 is
5492 : representable in the corresponding unsigned type of the result type,
5493 : then that value, converted to the result type, is the resulting value;
5494 : otherwise, the behavior is undefined.
5495 : For C++20:
5496 : The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
5497 : 2^N, where N is the range exponent of the type of the result. */
5498 5581037 : if (code == LSHIFT_EXPR
5499 4667605 : && !TYPE_OVERFLOW_WRAPS (lhstype)
5500 2199705 : && cxx_dialect >= cxx11
5501 7760565 : && cxx_dialect < cxx20)
5502 : {
5503 54036 : if (tree_int_cst_sgn (lhs) == -1)
5504 : {
5505 74 : if (!ctx->quiet)
5506 18 : permerror (loc,
5507 : "left operand of shift expression %q+E is negative",
5508 : build2_loc (loc, code, type, lhs, rhs));
5509 74 : return (!flag_permissive || ctx->quiet);
5510 : }
5511 : /* For signed x << y the following:
5512 : (unsigned) x >> ((prec (lhs) - 1) - y)
5513 : if > 1, is undefined. The right-hand side of this formula
5514 : is the highest bit of the LHS that can be set (starting from 0),
5515 : so that the shift doesn't overflow. We then right-shift the LHS
5516 : to see whether any other bit is set making the original shift
5517 : undefined -- the result is not representable in the corresponding
5518 : unsigned type. */
5519 53962 : tree t = build_int_cst (unsigned_type_node, uprec - 1);
5520 53962 : t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
5521 53962 : tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
5522 53962 : t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
5523 53962 : if (tree_int_cst_lt (integer_one_node, t))
5524 : {
5525 41 : if (!ctx->quiet)
5526 7 : permerror (loc, "shift expression %q+E overflows",
5527 : build2_loc (loc, code, type, lhs, rhs));
5528 41 : return (!flag_permissive || ctx->quiet);
5529 : }
5530 : }
5531 : return false;
5532 : }
5533 :
5534 : /* Subroutine of cxx_eval_constant_expression.
5535 : Attempt to reduce the unary expression tree T to a compile time value.
5536 : If successful, return the value. Otherwise issue a diagnostic
5537 : and return error_mark_node. */
5538 :
5539 : static tree
5540 25813295 : cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
5541 : bool /*lval*/,
5542 : bool *non_constant_p, bool *overflow_p,
5543 : tree *jump_target)
5544 : {
5545 25813295 : tree r;
5546 25813295 : tree orig_arg = TREE_OPERAND (t, 0);
5547 25813295 : tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue,
5548 : non_constant_p, overflow_p,
5549 : jump_target);
5550 25813293 : if (*jump_target)
5551 : return NULL_TREE;
5552 25813291 : VERIFY_CONSTANT (arg);
5553 20555997 : location_t loc = EXPR_LOCATION (t);
5554 20555997 : enum tree_code code = TREE_CODE (t);
5555 20555997 : tree type = TREE_TYPE (t);
5556 20555997 : r = fold_unary_loc (loc, code, type, arg);
5557 20555997 : if (r == NULL_TREE)
5558 : {
5559 17 : if (arg == orig_arg)
5560 : r = t;
5561 : else
5562 13 : r = build1_loc (loc, code, type, arg);
5563 : }
5564 20555997 : VERIFY_CONSTANT (r);
5565 : return r;
5566 : }
5567 :
5568 : /* Helper function for cxx_eval_binary_expression. Try to optimize
5569 : original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
5570 : generic folding should be used. */
5571 :
5572 : static tree
5573 10848221 : cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
5574 : tree lhs, tree rhs, bool *non_constant_p,
5575 : bool *overflow_p, tree *jump_target)
5576 : {
5577 10848221 : STRIP_NOPS (lhs);
5578 10848221 : if (TREE_CODE (lhs) != ADDR_EXPR)
5579 : return NULL_TREE;
5580 :
5581 9979693 : lhs = TREE_OPERAND (lhs, 0);
5582 :
5583 : /* &A[i] p+ j => &A[i + j] */
5584 9979693 : if (TREE_CODE (lhs) == ARRAY_REF
5585 208338 : && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
5586 208338 : && TREE_CODE (rhs) == INTEGER_CST
5587 208338 : && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
5588 10188031 : && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
5589 : {
5590 208338 : tree orig_type = TREE_TYPE (t);
5591 208338 : location_t loc = EXPR_LOCATION (t);
5592 208338 : tree type = TREE_TYPE (lhs);
5593 :
5594 208338 : t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
5595 208338 : tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
5596 208338 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
5597 : non_constant_p, overflow_p,
5598 : jump_target);
5599 208338 : if (*non_constant_p)
5600 : return NULL_TREE;
5601 208326 : if (*jump_target)
5602 : return NULL_TREE;
5603 : /* Don't fold an out-of-bound access. */
5604 208326 : if (!tree_int_cst_le (t, nelts))
5605 : return NULL_TREE;
5606 208326 : rhs = cp_fold_convert (ssizetype, rhs);
5607 : /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
5608 : constexpr int A[1]; ... (char *)&A[0] + 1 */
5609 208326 : if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
5610 208326 : rhs, TYPE_SIZE_UNIT (type))))
5611 : return NULL_TREE;
5612 : /* Make sure to treat the second operand of POINTER_PLUS_EXPR
5613 : as signed. */
5614 208294 : rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
5615 208294 : TYPE_SIZE_UNIT (type));
5616 208294 : t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
5617 208294 : t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
5618 : t, NULL_TREE, NULL_TREE);
5619 208294 : t = cp_build_addr_expr (t, tf_warning_or_error);
5620 208294 : t = cp_fold_convert (orig_type, t);
5621 208294 : return cxx_eval_constant_expression (ctx, t, vc_prvalue,
5622 : non_constant_p, overflow_p,
5623 208294 : jump_target);
5624 : }
5625 :
5626 : return NULL_TREE;
5627 : }
5628 :
5629 : /* Try to fold expressions like
5630 : (struct S *) (&a[0].D.2378 + 12)
5631 : into
5632 : &MEM <struct T> [(void *)&a + 12B]
5633 : This is something normally done by gimple_fold_stmt_to_constant_1
5634 : on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
5635 : dereference the address because some details are lost.
5636 : For pointer comparisons we want such folding though so that
5637 : match.pd address_compare optimization works. */
5638 :
5639 : static tree
5640 12042380 : cxx_maybe_fold_addr_pointer_plus (tree t)
5641 : {
5642 24084766 : while (CONVERT_EXPR_P (t)
5643 12755041 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
5644 712655 : t = TREE_OPERAND (t, 0);
5645 12042380 : if (TREE_CODE (t) != POINTER_PLUS_EXPR)
5646 : return NULL_TREE;
5647 10332931 : tree op0 = TREE_OPERAND (t, 0);
5648 10332931 : tree op1 = TREE_OPERAND (t, 1);
5649 10332931 : if (TREE_CODE (op1) != INTEGER_CST)
5650 : return NULL_TREE;
5651 10332931 : while (CONVERT_EXPR_P (op0)
5652 20662314 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
5653 10329383 : op0 = TREE_OPERAND (op0, 0);
5654 10332931 : if (TREE_CODE (op0) != ADDR_EXPR)
5655 : return NULL_TREE;
5656 10332931 : op1 = fold_convert (ptr_type_node, op1);
5657 10332931 : tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
5658 10332931 : return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
5659 : }
5660 :
5661 : /* Subroutine of cxx_eval_constant_expression.
5662 : Like cxx_eval_unary_expression, except for binary expressions. */
5663 :
5664 : static tree
5665 112345121 : cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
5666 : value_cat lval,
5667 : bool *non_constant_p, bool *overflow_p,
5668 : tree *jump_target)
5669 : {
5670 112345121 : tree r = NULL_TREE;
5671 112345121 : tree orig_lhs = TREE_OPERAND (t, 0);
5672 112345121 : tree orig_rhs = TREE_OPERAND (t, 1);
5673 112345121 : tree lhs, rhs;
5674 :
5675 112345121 : if (TREE_CODE (t) == POINTER_PLUS_EXPR
5676 12625627 : && CONVERT_EXPR_P (orig_lhs)
5677 6626580 : && (lhs = TREE_OPERAND (orig_lhs, 0))
5678 6626580 : && INDIRECT_TYPE_P (TREE_TYPE (lhs))
5679 6626580 : && (TREE_CODE (orig_lhs) != NOP_EXPR || !REINTERPRET_CAST_P (orig_lhs))
5680 118971672 : && is_properly_derived_from (TREE_TYPE (TREE_TYPE (orig_lhs)),
5681 6626551 : TREE_TYPE (TREE_TYPE (lhs))))
5682 : /* fold_unary_loc and match.pd can optimize
5683 : (type *) (ptr p+ off) into ((type *) ptr) p+ off, which can break
5684 : static_cast constexpr diagnostics, because ptr before the p+
5685 : cast to type * can be invalid while the original valid.
5686 : Evaluate it as (type *) (ptr p+ off) instead. */
5687 : {
5688 42 : tree cast = copy_node (orig_lhs);
5689 42 : tree pplus = copy_node (t);
5690 42 : TREE_OPERAND (cast, 0) = pplus;
5691 42 : TREE_OPERAND (pplus, 0) = lhs;
5692 42 : TREE_TYPE (pplus) = TREE_TYPE (lhs);
5693 42 : lhs = cxx_eval_constant_expression (ctx, cast, vc_prvalue,
5694 : non_constant_p, overflow_p,
5695 : jump_target);
5696 42 : if (lhs != cast)
5697 : {
5698 24 : ggc_free (cast);
5699 24 : ggc_free (pplus);
5700 : }
5701 42 : if (*non_constant_p)
5702 : return t;
5703 42 : return lhs;
5704 : }
5705 :
5706 112345079 : lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue,
5707 : non_constant_p, overflow_p,
5708 : jump_target);
5709 : /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
5710 : subtraction. */
5711 112345077 : if (*non_constant_p)
5712 : return t;
5713 90450300 : if (*jump_target)
5714 : return NULL_TREE;
5715 90450205 : rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue,
5716 : non_constant_p, overflow_p,
5717 : jump_target);
5718 90450205 : if (*non_constant_p)
5719 : return t;
5720 89283766 : if (*jump_target)
5721 : return NULL_TREE;
5722 :
5723 89283760 : location_t loc = EXPR_LOCATION (t);
5724 89283760 : enum tree_code code = TREE_CODE (t);
5725 89283760 : tree type = TREE_TYPE (t);
5726 :
5727 89283760 : if (code == EQ_EXPR || code == NE_EXPR)
5728 : {
5729 18244545 : bool is_code_eq = (code == EQ_EXPR);
5730 :
5731 18244545 : if (TREE_CODE (lhs) == PTRMEM_CST
5732 217 : && TREE_CODE (rhs) == PTRMEM_CST)
5733 : {
5734 76 : tree lmem = PTRMEM_CST_MEMBER (lhs);
5735 76 : tree rmem = PTRMEM_CST_MEMBER (rhs);
5736 76 : bool eq;
5737 76 : if (TREE_CODE (lmem) == TREE_CODE (rmem)
5738 76 : && TREE_CODE (lmem) == FIELD_DECL
5739 76 : && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
5740 103 : && same_type_p (DECL_CONTEXT (lmem),
5741 : DECL_CONTEXT (rmem)))
5742 : /* If both refer to (possibly different) members of the same union
5743 : (12.3), they compare equal. */
5744 : eq = true;
5745 : else
5746 49 : eq = cp_tree_equal (lhs, rhs);
5747 76 : r = constant_boolean_node (eq == is_code_eq, type);
5748 76 : }
5749 18244469 : else if ((TREE_CODE (lhs) == PTRMEM_CST
5750 18244328 : || TREE_CODE (rhs) == PTRMEM_CST)
5751 18244469 : && (null_member_pointer_value_p (lhs)
5752 141 : || null_member_pointer_value_p (rhs)))
5753 141 : r = constant_boolean_node (!is_code_eq, type);
5754 18244328 : else if (TREE_CODE (lhs) == PTRMEM_CST)
5755 0 : lhs = cplus_expand_constant (lhs);
5756 18244328 : else if (TREE_CODE (rhs) == PTRMEM_CST)
5757 0 : rhs = cplus_expand_constant (rhs);
5758 18244328 : else if (REFLECT_EXPR_P (lhs) && REFLECT_EXPR_P (rhs))
5759 : {
5760 3926 : const bool eq = compare_reflections (lhs, rhs);
5761 3926 : r = constant_boolean_node (eq == is_code_eq, type);
5762 : }
5763 : }
5764 0 : if (r == NULL_TREE
5765 89279617 : && TREE_CODE_CLASS (code) == tcc_comparison
5766 39127482 : && POINTER_TYPE_P (TREE_TYPE (lhs)))
5767 : {
5768 6021190 : if (tree lhso = cxx_maybe_fold_addr_pointer_plus (lhs))
5769 5018685 : lhs = fold_convert (TREE_TYPE (lhs), lhso);
5770 6021190 : if (tree rhso = cxx_maybe_fold_addr_pointer_plus (rhs))
5771 5314246 : rhs = fold_convert (TREE_TYPE (rhs), rhso);
5772 : }
5773 10848376 : if (code == POINTER_PLUS_EXPR && !*non_constant_p
5774 100132136 : && integer_zerop (lhs) && !integer_zerop (rhs))
5775 : {
5776 155 : if (!ctx->quiet)
5777 45 : error ("arithmetic involving a null pointer in %qE", lhs);
5778 155 : *non_constant_p = true;
5779 155 : return t;
5780 : }
5781 89283605 : else if (code == POINTER_PLUS_EXPR)
5782 : {
5783 10848221 : r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
5784 : overflow_p, jump_target);
5785 10848221 : if (*jump_target)
5786 : return NULL_TREE;
5787 : }
5788 78435384 : else if (code == SPACESHIP_EXPR)
5789 : {
5790 27365 : r = genericize_spaceship (loc, type, lhs, rhs);
5791 27365 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
5792 27365 : overflow_p, jump_target);
5793 : }
5794 :
5795 89256240 : if (r == NULL_TREE)
5796 : {
5797 89043803 : if (ctx->manifestly_const_eval == mce_true
5798 68045300 : && (flag_constexpr_fp_except
5799 68045297 : || TREE_CODE (type) != REAL_TYPE))
5800 : {
5801 67991582 : auto ofcc = make_temp_override (folding_cxx_constexpr, true);
5802 67991582 : r = fold_binary_initializer_loc (loc, code, type, lhs, rhs);
5803 67991582 : }
5804 : else
5805 21052221 : r = fold_binary_loc (loc, code, type, lhs, rhs);
5806 : }
5807 :
5808 89043803 : if (r == NULL_TREE
5809 8971823 : && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
5810 100 : && TREE_CODE (lhs) == INTEGER_CST
5811 98 : && TREE_CODE (rhs) == INTEGER_CST
5812 98228063 : && wi::neg_p (wi::to_wide (rhs)))
5813 : {
5814 : /* For diagnostics and -fpermissive emulate previous behavior of
5815 : handling shifts by negative amount. */
5816 98 : tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
5817 98 : if (nrhs)
5818 119 : r = fold_binary_loc (loc,
5819 : code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
5820 : type, lhs, nrhs);
5821 : }
5822 :
5823 89256240 : if (r == NULL_TREE)
5824 : {
5825 8971725 : if (lhs == orig_lhs && rhs == orig_rhs)
5826 : r = t;
5827 : else
5828 3152255 : r = build2_loc (loc, code, type, lhs, rhs);
5829 : }
5830 80284515 : else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
5831 433 : *non_constant_p = true;
5832 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
5833 : a local array in a constexpr function. */
5834 89256240 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
5835 71698318 : if (!ptr)
5836 71698318 : VERIFY_CONSTANT (r);
5837 : return r;
5838 : }
5839 :
5840 : /* Subroutine of cxx_eval_constant_expression.
5841 : Attempt to evaluate condition expressions. */
5842 :
5843 : static tree
5844 39283619 : cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
5845 : value_cat lval,
5846 : bool *non_constant_p, bool *overflow_p,
5847 : tree *jump_target)
5848 : {
5849 39283619 : tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5850 : vc_prvalue,
5851 : non_constant_p, overflow_p,
5852 : jump_target);
5853 39283619 : if (*jump_target)
5854 : return NULL_TREE;
5855 39283595 : VERIFY_CONSTANT (val);
5856 36974701 : if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
5857 : {
5858 : /* Evaluate the condition as if it was
5859 : if (__builtin_is_constant_evaluated ()), i.e. defer it if not
5860 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
5861 : without manifestly_const_eval even expressions or parts thereof which
5862 : will later be manifestly const_eval evaluated), otherwise fold it to
5863 : true. */
5864 1069011 : if (ctx->manifestly_const_eval == mce_unknown)
5865 : {
5866 965285 : *non_constant_p = true;
5867 965285 : return t;
5868 : }
5869 103726 : val = constant_boolean_node (ctx->manifestly_const_eval == mce_true,
5870 : boolean_type_node);
5871 : }
5872 : /* Don't VERIFY_CONSTANT the other operands. */
5873 36009416 : const bool zero_p = integer_zerop (val);
5874 36009416 : if (zero_p)
5875 22879923 : val = TREE_OPERAND (t, 2);
5876 : else
5877 13129493 : val = TREE_OPERAND (t, 1);
5878 36009416 : if (TREE_CODE (t) == IF_STMT && !val)
5879 9949698 : val = void_node;
5880 :
5881 : /* P2564: If we aren't in immediate function context (including a manifestly
5882 : constant-evaluated expression), check any uses of immediate functions in
5883 : the arm we're discarding. But don't do this inside a call; we already
5884 : checked when parsing the function. */
5885 36009416 : if (ctx->manifestly_const_eval != mce_true
5886 5085655 : && !in_immediate_context ()
5887 4988063 : && !ctx->call
5888 36818118 : && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2),
5889 808702 : ctx->manifestly_const_eval))
5890 : {
5891 7 : *non_constant_p = true;
5892 7 : return t;
5893 : }
5894 :
5895 : /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still
5896 : serve as the initializer for the same object as the outer TARGET_EXPR,
5897 : as in
5898 : A a = true ? A{} : A{};
5899 : so strip the inner TARGET_EXPR so we don't materialize a temporary. */
5900 36009409 : if (TREE_CODE (val) == TARGET_EXPR)
5901 5341 : val = TARGET_EXPR_INITIAL (val);
5902 36009409 : return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
5903 36009409 : overflow_p, jump_target);
5904 : }
5905 :
5906 : /* Subroutine of cxx_eval_constant_expression.
5907 : Attempt to evaluate vector condition expressions. Unlike
5908 : cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
5909 : ternary arithmetics operation, where all 3 arguments have to be
5910 : evaluated as constants and then folding computes the result from
5911 : them. */
5912 :
5913 : static tree
5914 11755 : cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
5915 : bool *non_constant_p, bool *overflow_p,
5916 : tree *jump_target)
5917 : {
5918 11755 : tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5919 : vc_prvalue,
5920 : non_constant_p, overflow_p,
5921 : jump_target);
5922 11755 : if (*jump_target)
5923 : return NULL_TREE;
5924 11755 : VERIFY_CONSTANT (arg1);
5925 8227 : tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
5926 : vc_prvalue,
5927 : non_constant_p, overflow_p,
5928 : jump_target);
5929 8227 : if (*jump_target)
5930 : return NULL_TREE;
5931 8227 : VERIFY_CONSTANT (arg2);
5932 7097 : tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
5933 : vc_prvalue,
5934 : non_constant_p, overflow_p,
5935 : jump_target);
5936 7097 : if (*jump_target)
5937 : return NULL_TREE;
5938 7097 : VERIFY_CONSTANT (arg3);
5939 7097 : location_t loc = EXPR_LOCATION (t);
5940 7097 : tree type = TREE_TYPE (t);
5941 7097 : tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5942 7097 : if (r == NULL_TREE)
5943 : {
5944 0 : if (arg1 == TREE_OPERAND (t, 0)
5945 0 : && arg2 == TREE_OPERAND (t, 1)
5946 0 : && arg3 == TREE_OPERAND (t, 2))
5947 : r = t;
5948 : else
5949 0 : r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5950 : }
5951 7097 : VERIFY_CONSTANT (r);
5952 : return r;
5953 : }
5954 :
5955 : /* Returns less than, equal to, or greater than zero if KEY is found to be
5956 : less than, to match, or to be greater than the constructor_elt's INDEX. */
5957 :
5958 : static int
5959 439901 : array_index_cmp (tree key, tree index)
5960 : {
5961 439901 : gcc_assert (TREE_CODE (key) == INTEGER_CST);
5962 :
5963 439901 : switch (TREE_CODE (index))
5964 : {
5965 436963 : case INTEGER_CST:
5966 436963 : return tree_int_cst_compare (key, index);
5967 2938 : case RANGE_EXPR:
5968 2938 : {
5969 2938 : tree lo = TREE_OPERAND (index, 0);
5970 2938 : tree hi = TREE_OPERAND (index, 1);
5971 2938 : if (tree_int_cst_lt (key, lo))
5972 : return -1;
5973 2642 : else if (tree_int_cst_lt (hi, key))
5974 : return 1;
5975 : else
5976 2642 : return 0;
5977 : }
5978 0 : default:
5979 0 : gcc_unreachable ();
5980 : }
5981 : }
5982 :
5983 : /* Extract a single INTEGER_CST from RAW_DATA_CST RAW_DATA at
5984 : relative index OFF. */
5985 :
5986 : static tree
5987 29559 : raw_data_cst_elt (tree raw_data, unsigned int off)
5988 : {
5989 29559 : return build_int_cst (TREE_TYPE (raw_data),
5990 29559 : TYPE_UNSIGNED (TREE_TYPE (raw_data))
5991 59118 : ? (HOST_WIDE_INT)
5992 29073 : RAW_DATA_UCHAR_ELT (raw_data, off)
5993 : : (HOST_WIDE_INT)
5994 486 : RAW_DATA_SCHAR_ELT (raw_data, off));
5995 : }
5996 :
5997 : /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
5998 : if none. If INSERT is true, insert a matching element rather than fail. */
5999 :
6000 : static HOST_WIDE_INT
6001 12443315 : find_array_ctor_elt (tree ary, tree dindex, bool insert)
6002 : {
6003 12443315 : if (tree_int_cst_sgn (dindex) < 0)
6004 : return -1;
6005 :
6006 12443315 : unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex);
6007 12443315 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary);
6008 12443315 : unsigned HOST_WIDE_INT len = vec_safe_length (elts);
6009 :
6010 16717152 : unsigned HOST_WIDE_INT end = len;
6011 16717152 : unsigned HOST_WIDE_INT begin = 0;
6012 :
6013 : /* If the last element of the CONSTRUCTOR has its own index, we can assume
6014 : that the same is true of the other elements and index directly. */
6015 11885620 : if (end > 0)
6016 : {
6017 11656669 : tree cindex = (*elts)[end - 1].index;
6018 11656669 : if (cindex == NULL_TREE)
6019 : {
6020 : /* Verify that if the last index is missing, all indexes
6021 : are missing and there is no RAW_DATA_CST. */
6022 21794 : if (flag_checking)
6023 220133 : for (unsigned int j = 0; j < len - 1; ++j)
6024 198339 : gcc_assert ((*elts)[j].index == NULL_TREE
6025 : && TREE_CODE ((*elts)[j].value) != RAW_DATA_CST);
6026 21794 : if (i < end)
6027 21794 : return i;
6028 : else
6029 : {
6030 0 : begin = end;
6031 0 : if (i == end)
6032 : /* If the element is to be added right at the end,
6033 : make sure it is added with cleared index too. */
6034 4831532 : dindex = NULL_TREE;
6035 0 : else if (insert)
6036 : /* Otherwise, in order not to break the assumption
6037 : that CONSTRUCTOR either has all indexes or none,
6038 : we need to add indexes to all elements. */
6039 0 : for (unsigned int j = 0; j < len; ++j)
6040 0 : (*elts)[j].index = build_int_cst (TREE_TYPE (dindex), j);
6041 : }
6042 : }
6043 11634875 : else if (TREE_CODE (cindex) == INTEGER_CST
6044 11634875 : && compare_tree_int (cindex, end - 1) == 0)
6045 : {
6046 11424081 : tree value = (*elts)[end - 1].value;
6047 11424081 : if (i < end)
6048 : {
6049 7590079 : if (i == end - 1 && TREE_CODE (value) == RAW_DATA_CST)
6050 : begin = end - 1;
6051 : else
6052 7589989 : return i;
6053 : }
6054 3834002 : else if (TREE_CODE (value) == RAW_DATA_CST
6055 3866158 : && wi::to_offset (dindex) < (wi::to_offset (cindex)
6056 32156 : + RAW_DATA_LENGTH (value)))
6057 16078 : begin = end - 1;
6058 : else
6059 3817924 : begin = end;
6060 : }
6061 : }
6062 :
6063 : /* Otherwise, find a matching index by means of a binary search. */
6064 5036311 : while (begin != end)
6065 : {
6066 361418 : unsigned HOST_WIDE_INT middle = (begin + end) / 2;
6067 361418 : constructor_elt &elt = (*elts)[middle];
6068 361418 : tree idx = elt.index;
6069 :
6070 361418 : int cmp = array_index_cmp (dindex, idx);
6071 361418 : if (cmp > 0
6072 66757 : && TREE_CODE (elt.value) == RAW_DATA_CST
6073 445226 : && wi::to_offset (dindex) < (wi::to_offset (idx)
6074 83808 : + RAW_DATA_LENGTH (elt.value)))
6075 29417 : cmp = 0;
6076 361418 : if (cmp < 0)
6077 : end = middle;
6078 193979 : else if (cmp > 0)
6079 37340 : begin = middle + 1;
6080 : else
6081 : {
6082 156639 : if (insert && TREE_CODE (elt.value) == RAW_DATA_CST)
6083 : {
6084 : /* We need to split the RAW_DATA_CST elt. */
6085 122 : constructor_elt e;
6086 122 : gcc_checking_assert (TREE_CODE (idx) != RANGE_EXPR);
6087 244 : unsigned int off = (wi::to_offset (dindex)
6088 244 : - wi::to_offset (idx)).to_uhwi ();
6089 122 : tree value = elt.value;
6090 122 : unsigned int len = RAW_DATA_LENGTH (value);
6091 122 : if (off > 1 && len >= off + 3)
6092 22 : value = copy_node (elt.value);
6093 122 : if (off)
6094 : {
6095 33 : if (off > 1)
6096 33 : RAW_DATA_LENGTH (elt.value) = off;
6097 : else
6098 0 : elt.value = raw_data_cst_elt (elt.value, 0);
6099 33 : e.index = size_binop (PLUS_EXPR, elt.index,
6100 : build_int_cst (TREE_TYPE (elt.index),
6101 : off));
6102 33 : e.value = NULL_TREE;
6103 33 : ++middle;
6104 33 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
6105 : }
6106 122 : (*elts)[middle].value = raw_data_cst_elt (value, off);
6107 122 : if (len >= off + 2)
6108 : {
6109 111 : e.index = (*elts)[middle].index;
6110 111 : e.index = size_binop (PLUS_EXPR, e.index,
6111 : build_one_cst (TREE_TYPE (e.index)));
6112 111 : if (len >= off + 3)
6113 : {
6114 111 : RAW_DATA_LENGTH (value) -= off + 1;
6115 111 : RAW_DATA_POINTER (value) += off + 1;
6116 111 : e.value = value;
6117 : }
6118 : else
6119 0 : e.value = raw_data_cst_elt (value, off + 1);
6120 111 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
6121 : }
6122 122 : return middle;
6123 : }
6124 35871 : if (insert && TREE_CODE (idx) == RANGE_EXPR)
6125 : {
6126 : /* We need to split the range. */
6127 361 : constructor_elt e;
6128 361 : tree lo = TREE_OPERAND (idx, 0);
6129 361 : tree hi = TREE_OPERAND (idx, 1);
6130 361 : tree value = elt.value;
6131 361 : dindex = fold_convert (sizetype, dindex);
6132 361 : if (tree_int_cst_lt (lo, dindex))
6133 : {
6134 : /* There are still some lower elts; shorten the range. */
6135 194 : tree new_hi = int_const_binop (MINUS_EXPR, dindex,
6136 97 : size_one_node);
6137 97 : if (tree_int_cst_equal (lo, new_hi))
6138 : /* Only one element left, no longer a range. */
6139 42 : elt.index = lo;
6140 : else
6141 55 : TREE_OPERAND (idx, 1) = new_hi;
6142 : /* Append the element we want to insert. */
6143 97 : ++middle;
6144 97 : e.index = dindex;
6145 97 : e.value = unshare_constructor (value);
6146 97 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
6147 : }
6148 : else
6149 : /* No lower elts, the range elt is now ours. */
6150 264 : elt.index = dindex;
6151 :
6152 361 : if (tree_int_cst_lt (dindex, hi))
6153 : {
6154 : /* There are still some higher elts; append a range. */
6155 506 : tree new_lo = int_const_binop (PLUS_EXPR, dindex,
6156 253 : size_one_node);
6157 253 : if (tree_int_cst_equal (new_lo, hi))
6158 : e.index = hi;
6159 : else
6160 153 : e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
6161 253 : e.value = unshare_constructor (value);
6162 253 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
6163 : }
6164 : }
6165 156517 : return middle;
6166 : }
6167 : }
6168 :
6169 4674893 : if (insert)
6170 : {
6171 4544241 : constructor_elt e = { dindex, NULL_TREE };
6172 4544241 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e);
6173 4544241 : return end;
6174 : }
6175 :
6176 : return -1;
6177 : }
6178 :
6179 : /* Return a pointer to the constructor_elt of CTOR which matches INDEX. If no
6180 : matching constructor_elt exists, then add one to CTOR.
6181 :
6182 : As an optimization, if POS_HINT is non-negative then it is used as a guess
6183 : for the (integer) index of the matching constructor_elt within CTOR.
6184 :
6185 : If POS_HINT is -2, it means do not insert. */
6186 :
6187 : static constructor_elt *
6188 42688981 : get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
6189 : {
6190 : /* Check the hint first. */
6191 4629497 : if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)
6192 47318478 : && CONSTRUCTOR_ELT (ctor, pos_hint)->index == index)
6193 : return CONSTRUCTOR_ELT (ctor, pos_hint);
6194 :
6195 38059496 : bool insertp = (pos_hint != -2);
6196 38059496 : tree type = TREE_TYPE (ctor);
6197 38059496 : if (TREE_CODE (type) == VECTOR_TYPE && index == NULL_TREE)
6198 : {
6199 27296 : gcc_assert (insertp);
6200 27296 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE);
6201 27296 : return &CONSTRUCTOR_ELTS (ctor)->last();
6202 : }
6203 38032200 : else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
6204 : {
6205 6243922 : if (TREE_CODE (index) == RANGE_EXPR)
6206 : {
6207 : /* Support for RANGE_EXPR index lookups is currently limited to
6208 : accessing an existing element via POS_HINT, or appending a new
6209 : element to the end of CTOR. ??? Support for other access
6210 : patterns may also be needed. */
6211 3 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
6212 3 : if (vec_safe_length (elts))
6213 : {
6214 3 : tree lo = TREE_OPERAND (index, 0);
6215 3 : gcc_assert (array_index_cmp (elts->last().index, lo) < 0);
6216 : }
6217 3 : gcc_assert (insertp);
6218 3 : CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE);
6219 3 : return &elts->last();
6220 : }
6221 :
6222 6243919 : HOST_WIDE_INT i = find_array_ctor_elt (ctor, index, insertp);
6223 6243919 : if (i < 0)
6224 : {
6225 2711 : gcc_assert (!insertp);
6226 : return nullptr;
6227 : }
6228 6241208 : constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i);
6229 6241208 : if (!insertp && cep->index && TREE_CODE (cep->index) == RANGE_EXPR)
6230 : {
6231 : /* Split a range even if we aren't inserting new entries. */
6232 0 : gcc_assert (!insertp);
6233 0 : i = find_array_ctor_elt (ctor, index, /*insert*/true);
6234 0 : gcc_assert (i >= 0);
6235 0 : cep = CONSTRUCTOR_ELT (ctor, i);
6236 : }
6237 6241208 : gcc_assert (cep->index == NULL_TREE
6238 : || TREE_CODE (cep->index) != RANGE_EXPR);
6239 : return cep;
6240 : }
6241 : else
6242 : {
6243 31788278 : gcc_assert (TREE_CODE (index) == FIELD_DECL
6244 : && (same_type_ignoring_top_level_qualifiers_p
6245 : (DECL_CONTEXT (index), TREE_TYPE (ctor))));
6246 :
6247 : /* We must keep the CONSTRUCTOR's ELTS in FIELD order.
6248 : Usually we meet initializers in that order, but it is
6249 : possible for base types to be placed not in program
6250 : order. */
6251 31788278 : tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
6252 31788278 : unsigned HOST_WIDE_INT idx = 0;
6253 31788278 : constructor_elt *cep = NULL;
6254 :
6255 : /* Check if we're changing the active member of a union. */
6256 584383 : if (TREE_CODE (type) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)
6257 32168077 : && CONSTRUCTOR_ELT (ctor, 0)->index != index)
6258 12483 : vec_safe_truncate (CONSTRUCTOR_ELTS (ctor), 0);
6259 : /* If the bit offset of INDEX is larger than that of the last
6260 : constructor_elt, then we can just immediately append a new
6261 : constructor_elt to the end of CTOR. */
6262 48422474 : else if (CONSTRUCTOR_NELTS (ctor)
6263 44581454 : && tree_int_cst_compare (bit_position (index),
6264 43614120 : bit_position (CONSTRUCTOR_ELTS (ctor)
6265 21807060 : ->last().index)) > 0)
6266 : {
6267 6140198 : idx = CONSTRUCTOR_NELTS (ctor);
6268 6140198 : goto insert;
6269 : }
6270 :
6271 : /* Otherwise, we need to iterate over CTOR to find or insert INDEX
6272 : appropriately. */
6273 :
6274 30444966 : for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor), idx, &cep);
6275 4796886 : idx++, fields = DECL_CHAIN (fields))
6276 : {
6277 20463748 : if (index == cep->index)
6278 15624936 : goto found;
6279 :
6280 : /* The field we're initializing must be on the field
6281 : list. Look to see if it is present before the
6282 : field the current ELT initializes. */
6283 51214328 : for (; fields != cep->index; fields = DECL_CHAIN (fields))
6284 46417442 : if (index == fields)
6285 41926 : goto insert;
6286 : }
6287 : /* We fell off the end of the CONSTRUCTOR, so insert a new
6288 : entry at the end. */
6289 :
6290 16163342 : insert:
6291 16163342 : if (!insertp)
6292 : return nullptr;
6293 :
6294 16163339 : {
6295 16163339 : constructor_elt ce = { index, NULL_TREE };
6296 :
6297 16163339 : vec_safe_insert (CONSTRUCTOR_ELTS (ctor), idx, ce);
6298 16163339 : cep = CONSTRUCTOR_ELT (ctor, idx);
6299 : }
6300 42688981 : found:;
6301 :
6302 : return cep;
6303 : }
6304 : }
6305 :
6306 : /* Under the control of CTX, issue a detailed diagnostic for
6307 : an out-of-bounds subscript INDEX into the expression ARRAY. */
6308 :
6309 : static void
6310 601 : diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index)
6311 : {
6312 601 : if (!ctx->quiet)
6313 : {
6314 120 : tree arraytype = TREE_TYPE (array);
6315 :
6316 : /* Convert the unsigned array subscript to a signed integer to avoid
6317 : printing huge numbers for small negative values. */
6318 120 : tree sidx = fold_convert (ssizetype, index);
6319 120 : STRIP_ANY_LOCATION_WRAPPER (array);
6320 120 : if (DECL_P (array))
6321 : {
6322 79 : auto_diagnostic_group d;
6323 79 : if (TYPE_DOMAIN (arraytype))
6324 73 : error_at (loc, "array subscript value %qE is outside the bounds "
6325 : "of array %qD of type %qT", sidx, array, arraytype);
6326 : else
6327 6 : error_at (loc, "nonzero array subscript %qE is used with array %qD of "
6328 : "type %qT with unknown bounds", sidx, array, arraytype);
6329 79 : inform (DECL_SOURCE_LOCATION (array), "declared here");
6330 79 : }
6331 41 : else if (TYPE_DOMAIN (arraytype))
6332 38 : error_at (loc, "array subscript value %qE is outside the bounds "
6333 : "of array type %qT", sidx, arraytype);
6334 : else
6335 3 : error_at (loc, "nonzero array subscript %qE is used with array of type %qT "
6336 : "with unknown bounds", sidx, arraytype);
6337 : }
6338 601 : }
6339 :
6340 : /* Return the number of elements for TYPE (which is an ARRAY_TYPE or
6341 : a VECTOR_TYPE). */
6342 :
6343 : static tree
6344 21009824 : get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
6345 : bool *non_constant_p, bool *overflow_p,
6346 : tree *jump_target)
6347 : {
6348 21009824 : tree nelts;
6349 21009824 : if (TREE_CODE (type) == ARRAY_TYPE)
6350 : {
6351 21009824 : if (TYPE_DOMAIN (type))
6352 21009564 : nelts = array_type_nelts_top (type);
6353 : else
6354 260 : nelts = size_zero_node;
6355 : }
6356 0 : else if (VECTOR_TYPE_P (type))
6357 0 : nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
6358 : else
6359 0 : gcc_unreachable ();
6360 :
6361 : /* For VLAs, the number of elements won't be an integer constant. */
6362 21009824 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
6363 : non_constant_p, overflow_p,
6364 : jump_target);
6365 21009824 : return nelts;
6366 : }
6367 :
6368 : /* Extract element INDEX consisting of CHARS_PER_ELT chars from
6369 : STRING_CST STRING. */
6370 :
6371 : static tree
6372 1975077 : extract_string_elt (tree string, unsigned chars_per_elt, unsigned index)
6373 : {
6374 1975077 : tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string)));
6375 1975077 : tree r;
6376 :
6377 1975077 : if (chars_per_elt == 1)
6378 1760338 : r = build_int_cst (type, TREE_STRING_POINTER (string)[index]);
6379 : else
6380 : {
6381 214739 : const unsigned char *ptr
6382 214739 : = ((const unsigned char *)TREE_STRING_POINTER (string)
6383 214739 : + index * chars_per_elt);
6384 214739 : r = native_interpret_expr (type, ptr, chars_per_elt);
6385 : }
6386 1975077 : return r;
6387 : }
6388 :
6389 : /* Subroutine of cxx_eval_array_reference. T is an ARRAY_REF; evaluate the
6390 : subscript, diagnose any problems with it, and return the result. */
6391 :
6392 : static tree
6393 21210497 : eval_and_check_array_index (const constexpr_ctx *ctx,
6394 : tree t, bool allow_one_past,
6395 : bool *non_constant_p, bool *overflow_p,
6396 : tree *jump_target)
6397 : {
6398 21210497 : location_t loc = cp_expr_loc_or_input_loc (t);
6399 21210497 : tree ary = TREE_OPERAND (t, 0);
6400 21210497 : t = TREE_OPERAND (t, 1);
6401 21210497 : tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue,
6402 : non_constant_p, overflow_p,
6403 : jump_target);
6404 21210497 : if (*jump_target)
6405 : return NULL_TREE;
6406 21210497 : VERIFY_CONSTANT (index);
6407 :
6408 21009032 : if (!tree_fits_shwi_p (index)
6409 21009032 : || tree_int_cst_sgn (index) < 0)
6410 : {
6411 112 : diag_array_subscript (loc, ctx, ary, index);
6412 112 : *non_constant_p = true;
6413 112 : return t;
6414 : }
6415 :
6416 21008920 : tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
6417 : overflow_p, jump_target);
6418 21008920 : if (*jump_target)
6419 : return NULL_TREE;
6420 21008920 : VERIFY_CONSTANT (nelts);
6421 21008836 : if (allow_one_past
6422 21008836 : ? !tree_int_cst_le (index, nelts)
6423 14196660 : : !tree_int_cst_lt (index, nelts))
6424 : {
6425 489 : diag_array_subscript (loc, ctx, ary, index);
6426 489 : *non_constant_p = true;
6427 489 : return t;
6428 : }
6429 :
6430 : return index;
6431 : }
6432 :
6433 : /* Subroutine of cxx_eval_constant_expression.
6434 : Attempt to reduce a reference to an array slot. */
6435 :
6436 : static tree
6437 15557274 : cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
6438 : value_cat lval,
6439 : bool *non_constant_p, bool *overflow_p,
6440 : tree *jump_target)
6441 : {
6442 15557274 : tree oldary = TREE_OPERAND (t, 0);
6443 15557274 : tree ary = cxx_eval_constant_expression (ctx, oldary,
6444 : lval,
6445 : non_constant_p, overflow_p,
6446 : jump_target);
6447 15557274 : if (*non_constant_p)
6448 : return t;
6449 15314933 : if (*jump_target)
6450 : return NULL_TREE;
6451 15314933 : if (!lval
6452 8501310 : && TREE_CODE (ary) == VIEW_CONVERT_EXPR
6453 144212 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
6454 15459145 : && (TYPE_MAIN_VARIANT (TREE_TYPE (t))
6455 144212 : == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))))
6456 144212 : ary = TREE_OPERAND (ary, 0);
6457 :
6458 15314933 : tree oldidx = TREE_OPERAND (t, 1);
6459 15314933 : tree index = eval_and_check_array_index (ctx, t, lval,
6460 : non_constant_p, overflow_p,
6461 : jump_target);
6462 15314933 : if (*non_constant_p)
6463 : return t;
6464 15112864 : if (*jump_target)
6465 : return NULL_TREE;
6466 :
6467 15112864 : if (lval && ary == oldary && index == oldidx)
6468 : return t;
6469 10071596 : else if (lval == vc_discard)
6470 : return t;
6471 10071596 : else if (lval)
6472 1770654 : return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
6473 :
6474 8300942 : unsigned len = 0, elem_nchars = 1;
6475 8300942 : tree elem_type = TREE_TYPE (TREE_TYPE (ary));
6476 8300942 : if (TREE_CODE (ary) == CONSTRUCTOR)
6477 6192802 : len = CONSTRUCTOR_NELTS (ary);
6478 2108140 : else if (TREE_CODE (ary) == STRING_CST)
6479 : {
6480 1963942 : elem_nchars = (TYPE_PRECISION (elem_type)
6481 1963942 : / TYPE_PRECISION (char_type_node));
6482 1963942 : len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
6483 : }
6484 144198 : else if (TREE_CODE (ary) == VECTOR_CST)
6485 : /* We don't create variable-length VECTOR_CSTs. */
6486 144198 : len = VECTOR_CST_NELTS (ary).to_constant ();
6487 : else
6488 : {
6489 : /* We can't do anything with other tree codes, so use
6490 : VERIFY_CONSTANT to complain and fail. */
6491 0 : VERIFY_CONSTANT (ary);
6492 0 : gcc_unreachable ();
6493 : }
6494 :
6495 8300942 : bool found;
6496 8300942 : HOST_WIDE_INT i = 0;
6497 8300942 : if (TREE_CODE (ary) == CONSTRUCTOR)
6498 : {
6499 6192802 : HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
6500 6192802 : found = (ix >= 0);
6501 6192802 : if (found)
6502 6065516 : i = ix;
6503 : }
6504 : else
6505 : {
6506 2108140 : i = tree_to_shwi (index);
6507 2108140 : found = (i < len);
6508 : }
6509 :
6510 8300942 : if (found)
6511 : {
6512 8173205 : tree r;
6513 8173205 : if (TREE_CODE (ary) == CONSTRUCTOR)
6514 : {
6515 6065516 : r = (*CONSTRUCTOR_ELTS (ary))[i].value;
6516 6065516 : if (TREE_CODE (r) == RAW_DATA_CST)
6517 : {
6518 29437 : tree ridx = (*CONSTRUCTOR_ELTS (ary))[i].index;
6519 29437 : gcc_checking_assert (ridx);
6520 29437 : unsigned int off
6521 29437 : = (wi::to_offset (index) - wi::to_offset (ridx)).to_uhwi ();
6522 29437 : r = raw_data_cst_elt (r, off);
6523 : }
6524 : }
6525 2107689 : else if (TREE_CODE (ary) == VECTOR_CST)
6526 144198 : r = VECTOR_CST_ELT (ary, i);
6527 : else
6528 1963491 : r = extract_string_elt (ary, elem_nchars, i);
6529 :
6530 2137126 : if (r)
6531 : /* Don't VERIFY_CONSTANT here. */
6532 : return r;
6533 :
6534 : /* Otherwise the element doesn't have a value yet. */
6535 : }
6536 :
6537 : /* Not found. */
6538 :
6539 127737 : if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
6540 90 : return build_constructor (elem_type, NULL);
6541 :
6542 127647 : if (TREE_CODE (ary) == CONSTRUCTOR
6543 127647 : && CONSTRUCTOR_NO_CLEARING (ary))
6544 : {
6545 : /* 'ary' is part of the aggregate initializer we're currently
6546 : building; if there's no initializer for this element yet,
6547 : that's an error. */
6548 51 : if (!ctx->quiet)
6549 16 : error ("accessing uninitialized array element");
6550 51 : *non_constant_p = true;
6551 51 : return t;
6552 : }
6553 :
6554 : /* If it's within the array bounds but doesn't have an explicit
6555 : initializer, it's initialized from {}. But use build_value_init
6556 : directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */
6557 127596 : tree val;
6558 127596 : constexpr_ctx new_ctx;
6559 127596 : if (CP_AGGREGATE_TYPE_P (elem_type))
6560 : {
6561 500 : tree empty_ctor = build_constructor (init_list_type_node, NULL);
6562 500 : val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
6563 : }
6564 : else
6565 127096 : val = build_value_init (elem_type, tf_warning_or_error);
6566 :
6567 : /* Create a new constructor only if we don't already have a suitable one. */
6568 127596 : const bool new_ctor = (!SCALAR_TYPE_P (elem_type)
6569 128122 : && (!ctx->ctor
6570 45 : || !same_type_ignoring_top_level_qualifiers_p
6571 45 : (elem_type, TREE_TYPE (ctx->ctor))));
6572 : if (new_ctor)
6573 : {
6574 517 : new_ctx = *ctx;
6575 : /* We clear the object here. We used to replace it with T, but that
6576 : caused problems (101371, 108158); and anyway, T is the initializer,
6577 : not the target object. */
6578 517 : new_ctx.object = NULL_TREE;
6579 517 : new_ctx.ctor = build_constructor (elem_type, NULL);
6580 517 : ctx = &new_ctx;
6581 : }
6582 127596 : t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
6583 : overflow_p, jump_target);
6584 127596 : if (new_ctor && t != ctx->ctor)
6585 496 : free_constructor (ctx->ctor);
6586 : return t;
6587 : }
6588 :
6589 : /* Subroutine of cxx_eval_constant_expression.
6590 : Attempt to reduce a field access of a value of class type. */
6591 :
6592 : static tree
6593 116103042 : cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
6594 : value_cat lval,
6595 : bool *non_constant_p, bool *overflow_p,
6596 : tree *jump_target)
6597 : {
6598 116103042 : unsigned HOST_WIDE_INT i;
6599 116103042 : tree field;
6600 116103042 : tree value;
6601 116103042 : tree part = TREE_OPERAND (t, 1);
6602 116103042 : tree orig_whole = TREE_OPERAND (t, 0);
6603 116103042 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6604 : lval,
6605 : non_constant_p, overflow_p,
6606 : jump_target);
6607 116103042 : if (*non_constant_p)
6608 : return t;
6609 90048146 : if (*jump_target)
6610 : return NULL_TREE;
6611 90048140 : if (INDIRECT_REF_P (whole)
6612 90048140 : && integer_zerop (TREE_OPERAND (whole, 0)))
6613 : {
6614 177 : if (!ctx->quiet)
6615 39 : error ("dereferencing a null pointer in %qE", orig_whole);
6616 177 : *non_constant_p = true;
6617 177 : return t;
6618 : }
6619 :
6620 90047963 : if (TREE_CODE (whole) == PTRMEM_CST)
6621 1651 : whole = cplus_expand_constant (whole);
6622 90047963 : if (whole == orig_whole)
6623 : return t;
6624 60968950 : if (lval == vc_discard)
6625 : return t;
6626 60968926 : if (lval)
6627 21630899 : return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
6628 : whole, part, NULL_TREE);
6629 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6630 : CONSTRUCTOR. */
6631 39338027 : if (TREE_CODE (whole) != CONSTRUCTOR)
6632 : {
6633 0 : if (!ctx->quiet)
6634 0 : error ("%qE is not a constant expression", orig_whole);
6635 0 : *non_constant_p = true;
6636 0 : return t;
6637 : }
6638 39336533 : if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole))
6639 39339703 : && DECL_MUTABLE_P (part))
6640 : {
6641 144 : if (!ctx->quiet)
6642 16 : error ("mutable %qD is not usable in a constant expression", part);
6643 144 : *non_constant_p = true;
6644 144 : return t;
6645 : }
6646 :
6647 39337883 : bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole));
6648 59174381 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6649 : {
6650 : /* Use name match for PMF fields, as a variant will have a
6651 : different FIELD_DECL with a different type. */
6652 58948506 : if (pmf ? DECL_NAME (field) == DECL_NAME (part)
6653 : : field == part)
6654 : {
6655 39112008 : if (value == void_node)
6656 6 : goto uninit;
6657 39112002 : if (value)
6658 : {
6659 39111984 : STRIP_ANY_LOCATION_WRAPPER (value);
6660 39111984 : return value;
6661 : }
6662 : else
6663 : /* We're in the middle of initializing it. */
6664 : break;
6665 : }
6666 : }
6667 225893 : if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE)
6668 : {
6669 112 : if (CONSTRUCTOR_NELTS (whole) > 0)
6670 : {
6671 : /* DR 1188 says we don't have to deal with this. */
6672 97 : if (!ctx->quiet)
6673 : {
6674 20 : constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0);
6675 20 : if (cep->value == NULL_TREE)
6676 9 : error ("accessing uninitialized member %qD", part);
6677 : else
6678 11 : error ("accessing %qD member instead of active %qD member "
6679 : "in constant expression", part, cep->index);
6680 : }
6681 97 : *non_constant_p = true;
6682 97 : return t;
6683 : }
6684 15 : else if (!CONSTRUCTOR_NO_CLEARING (whole))
6685 : {
6686 : /* Value-initialized union, check if looking at the first member. */
6687 12 : tree first = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (whole)));
6688 12 : if (first != part)
6689 : {
6690 9 : if (!ctx->quiet)
6691 3 : error ("accessing %qD member instead of initialized %qD "
6692 : "member in constant expression", part, first);
6693 9 : *non_constant_p = true;
6694 9 : return t;
6695 : }
6696 : }
6697 : }
6698 :
6699 : /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
6700 : classes never get represented; throw together a value now. */
6701 225787 : if (is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
6702 209209 : return build_constructor (TREE_TYPE (t), NULL);
6703 :
6704 16578 : gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
6705 :
6706 16578 : if (CONSTRUCTOR_NO_CLEARING (whole))
6707 : {
6708 112 : uninit:
6709 : /* 'whole' is part of the aggregate initializer we're currently
6710 : building; if there's no initializer for this member yet, that's an
6711 : error. */
6712 118 : if (!ctx->quiet)
6713 23 : error ("accessing uninitialized member %qD", part);
6714 118 : *non_constant_p = true;
6715 118 : return t;
6716 : }
6717 :
6718 : /* If there's no explicit init for this field, it's value-initialized. */
6719 :
6720 16466 : if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
6721 : {
6722 : /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR
6723 : and copy the flags. */
6724 15869 : constructor_elt *e = get_or_insert_ctor_field (whole, part);
6725 15869 : e->value = value = build_constructor (TREE_TYPE (part), NULL);
6726 15869 : CONSTRUCTOR_ZERO_PADDING_BITS (value)
6727 15869 : = CONSTRUCTOR_ZERO_PADDING_BITS (whole);
6728 15869 : return value;
6729 : }
6730 :
6731 597 : value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
6732 597 : return cxx_eval_constant_expression (ctx, value,
6733 : lval,
6734 : non_constant_p, overflow_p,
6735 597 : jump_target);
6736 : }
6737 :
6738 : /* Subroutine of cxx_eval_constant_expression.
6739 : Attempt to reduce a field access of a value of class type that is
6740 : expressed as a BIT_FIELD_REF. */
6741 :
6742 : static tree
6743 40745 : cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
6744 : value_cat lval,
6745 : bool *non_constant_p, bool *overflow_p,
6746 : tree *jump_target)
6747 : {
6748 40745 : tree orig_whole = TREE_OPERAND (t, 0);
6749 40745 : tree retval, fldval, utype, mask;
6750 40745 : bool fld_seen = false;
6751 40745 : HOST_WIDE_INT istart, isize;
6752 40745 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6753 : lval,
6754 : non_constant_p, overflow_p,
6755 : jump_target);
6756 40745 : tree start, field, value;
6757 40745 : unsigned HOST_WIDE_INT i;
6758 :
6759 40745 : if (*jump_target)
6760 : return NULL_TREE;
6761 40745 : if (whole == orig_whole)
6762 : return t;
6763 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6764 : CONSTRUCTOR. */
6765 40596 : if (!*non_constant_p
6766 40596 : && TREE_CODE (whole) != VECTOR_CST
6767 0 : && TREE_CODE (whole) != CONSTRUCTOR)
6768 : {
6769 0 : if (!ctx->quiet)
6770 0 : error ("%qE is not a constant expression", orig_whole);
6771 0 : *non_constant_p = true;
6772 : }
6773 40596 : if (*non_constant_p)
6774 : return t;
6775 :
6776 40596 : if (TREE_CODE (whole) == VECTOR_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)))
6777 : {
6778 40596 : if (tree r = fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
6779 : TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)))
6780 : return r;
6781 0 : if (!ctx->quiet)
6782 0 : error ("%qE is not a constant expression", orig_whole);
6783 0 : *non_constant_p = true;
6784 0 : return t;
6785 : }
6786 :
6787 0 : start = TREE_OPERAND (t, 2);
6788 0 : istart = tree_to_shwi (start);
6789 0 : isize = tree_to_shwi (TREE_OPERAND (t, 1));
6790 0 : utype = TREE_TYPE (t);
6791 0 : if (!TYPE_UNSIGNED (utype))
6792 0 : utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
6793 0 : retval = build_int_cst (utype, 0);
6794 0 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6795 : {
6796 0 : tree bitpos = bit_position (field);
6797 0 : STRIP_ANY_LOCATION_WRAPPER (value);
6798 0 : if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
6799 : return value;
6800 0 : if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
6801 0 : && TREE_CODE (value) == INTEGER_CST
6802 0 : && tree_fits_shwi_p (bitpos)
6803 0 : && tree_fits_shwi_p (DECL_SIZE (field)))
6804 : {
6805 0 : HOST_WIDE_INT bit = tree_to_shwi (bitpos);
6806 0 : HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
6807 0 : HOST_WIDE_INT shift;
6808 0 : if (bit >= istart && bit + sz <= istart + isize)
6809 : {
6810 0 : fldval = fold_convert (utype, value);
6811 0 : mask = build_int_cst_type (utype, -1);
6812 0 : mask = fold_build2 (LSHIFT_EXPR, utype, mask,
6813 : size_int (TYPE_PRECISION (utype) - sz));
6814 0 : mask = fold_build2 (RSHIFT_EXPR, utype, mask,
6815 : size_int (TYPE_PRECISION (utype) - sz));
6816 0 : fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
6817 0 : shift = bit - istart;
6818 0 : if (BYTES_BIG_ENDIAN)
6819 : shift = TYPE_PRECISION (utype) - shift - sz;
6820 0 : fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
6821 : size_int (shift));
6822 0 : retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
6823 0 : fld_seen = true;
6824 : }
6825 : }
6826 : }
6827 0 : if (fld_seen)
6828 0 : return fold_convert (TREE_TYPE (t), retval);
6829 0 : gcc_unreachable ();
6830 : return error_mark_node;
6831 : }
6832 :
6833 : /* Helper for cxx_eval_bit_cast.
6834 : Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From
6835 : types and types of all subobjects have is_union_v<T>, is_pointer_v<T>,
6836 : is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static
6837 : data members of reference type. */
6838 :
6839 : static bool
6840 56278 : check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
6841 : tree orig_type)
6842 : {
6843 57278 : if (TREE_CODE (type) == UNION_TYPE)
6844 : {
6845 63 : if (!ctx->quiet)
6846 : {
6847 21 : if (type == orig_type)
6848 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6849 : "a union type", "__builtin_bit_cast", type);
6850 : else
6851 15 : error_at (loc, "%qs is not a constant expression because %qT "
6852 : "contains a union type", "__builtin_bit_cast",
6853 : orig_type);
6854 : }
6855 : return true;
6856 : }
6857 : if (TREE_CODE (type) == POINTER_TYPE)
6858 : {
6859 57 : if (!ctx->quiet)
6860 : {
6861 18 : if (type == orig_type)
6862 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6863 : "a pointer type", "__builtin_bit_cast", type);
6864 : else
6865 12 : error_at (loc, "%qs is not a constant expression because %qT "
6866 : "contains a pointer type", "__builtin_bit_cast",
6867 : orig_type);
6868 : }
6869 : return true;
6870 : }
6871 : if (TREE_CODE (type) == REFERENCE_TYPE)
6872 : {
6873 0 : if (!ctx->quiet)
6874 : {
6875 0 : if (type == orig_type)
6876 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6877 : "a reference type", "__builtin_bit_cast", type);
6878 : else
6879 0 : error_at (loc, "%qs is not a constant expression because %qT "
6880 : "contains a reference type", "__builtin_bit_cast",
6881 : orig_type);
6882 : }
6883 : return true;
6884 : }
6885 39310 : if (TYPE_PTRMEM_P (type))
6886 : {
6887 36 : if (!ctx->quiet)
6888 : {
6889 12 : if (type == orig_type)
6890 12 : error_at (loc, "%qs is not a constant expression because %qT is "
6891 : "a pointer to member type", "__builtin_bit_cast",
6892 : type);
6893 : else
6894 0 : error_at (loc, "%qs is not a constant expression because %qT "
6895 : "contains a pointer to member type",
6896 : "__builtin_bit_cast", orig_type);
6897 : }
6898 : return true;
6899 : }
6900 57122 : if (TYPE_VOLATILE (type))
6901 : {
6902 0 : if (!ctx->quiet)
6903 : {
6904 0 : if (type == orig_type)
6905 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6906 : "volatile", "__builtin_bit_cast", type);
6907 : else
6908 0 : error_at (loc, "%qs is not a constant expression because %qT "
6909 : "contains a volatile subobject",
6910 : "__builtin_bit_cast", orig_type);
6911 : }
6912 : return true;
6913 : }
6914 57122 : if (TREE_CODE (type) == RECORD_TYPE)
6915 2294014 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6916 2254812 : if (TREE_CODE (field) == FIELD_DECL
6917 2254812 : && check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
6918 : return true;
6919 57032 : if (TREE_CODE (type) == ARRAY_TYPE)
6920 1000 : return check_bit_cast_type (ctx, loc, TREE_TYPE (type), orig_type);
6921 : return false;
6922 : }
6923 :
6924 : /* Helper function for cxx_eval_bit_cast. For unsigned char or
6925 : std::byte members of CONSTRUCTOR (recursively) if they contain
6926 : some indeterminate bits (as set in MASK), remove the ctor elts,
6927 : mark the CONSTRUCTOR as CONSTRUCTOR_NO_CLEARING and clear the
6928 : bits in MASK. */
6929 :
6930 : static void
6931 9631 : clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask)
6932 : {
6933 9631 : if (TREE_CODE (t) != CONSTRUCTOR)
6934 : return;
6935 :
6936 : unsigned i, j = 0;
6937 : tree index, value;
6938 23564 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)
6939 : {
6940 13933 : tree type = TREE_TYPE (value);
6941 13933 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
6942 27427 : && DECL_BIT_FIELD_TYPE (index) != NULL_TREE)
6943 : {
6944 270 : if (is_byte_access_type_not_plain_char (DECL_BIT_FIELD_TYPE (index)))
6945 : {
6946 135 : HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (index));
6947 135 : gcc_assert (fldsz != 0);
6948 135 : HOST_WIDE_INT pos = int_byte_position (index);
6949 135 : HOST_WIDE_INT bpos
6950 135 : = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (index));
6951 135 : bpos %= BITS_PER_UNIT;
6952 135 : HOST_WIDE_INT end
6953 135 : = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
6954 135 : gcc_assert (end == 1 || end == 2);
6955 135 : unsigned char *p = mask + pos;
6956 135 : unsigned char mask_save[2];
6957 135 : mask_save[0] = mask[pos];
6958 135 : mask_save[1] = end == 2 ? mask[pos + 1] : 0;
6959 135 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
6960 : sorry_at (loc, "PDP11 bit-field handling unsupported"
6961 : " in %qs", "__builtin_bit_cast");
6962 135 : else if (BYTES_BIG_ENDIAN)
6963 : {
6964 : /* Big endian. */
6965 : if (bpos + fldsz <= BITS_PER_UNIT)
6966 : *p &= ~(((1 << fldsz) - 1)
6967 : << (BITS_PER_UNIT - bpos - fldsz));
6968 : else
6969 : {
6970 : gcc_assert (bpos);
6971 : *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
6972 : p++;
6973 : fldsz -= BITS_PER_UNIT - bpos;
6974 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
6975 : *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
6976 : }
6977 : }
6978 : else
6979 : {
6980 : /* Little endian. */
6981 135 : if (bpos + fldsz <= BITS_PER_UNIT)
6982 135 : *p &= ~(((1 << fldsz) - 1) << bpos);
6983 : else
6984 : {
6985 0 : gcc_assert (bpos);
6986 0 : *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
6987 0 : p++;
6988 0 : fldsz -= BITS_PER_UNIT - bpos;
6989 0 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
6990 0 : *p &= ~((1 << fldsz) - 1);
6991 : }
6992 : }
6993 135 : if (mask_save[0] != mask[pos]
6994 99 : || (end == 2 && mask_save[1] != mask[pos + 1]))
6995 : {
6996 36 : CONSTRUCTOR_NO_CLEARING (t) = 1;
6997 36 : continue;
6998 : }
6999 : }
7000 : }
7001 13663 : else if (is_byte_access_type_not_plain_char (type))
7002 : {
7003 228 : HOST_WIDE_INT pos;
7004 228 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7005 132 : pos = tree_to_shwi (index);
7006 : else
7007 96 : pos = int_byte_position (index);
7008 228 : if (mask[pos])
7009 : {
7010 48 : CONSTRUCTOR_NO_CLEARING (t) = 1;
7011 48 : mask[pos] = 0;
7012 48 : continue;
7013 : }
7014 : }
7015 13849 : if (TREE_CODE (value) == CONSTRUCTOR)
7016 : {
7017 7292 : HOST_WIDE_INT pos;
7018 7292 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7019 144 : pos = tree_to_shwi (index)
7020 72 : * tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))));
7021 : else
7022 7220 : pos = int_byte_position (index);
7023 7292 : clear_uchar_or_std_byte_in_mask (loc, value, mask + pos);
7024 : }
7025 13849 : if (i != j)
7026 : {
7027 180 : CONSTRUCTOR_ELT (t, j)->index = index;
7028 180 : CONSTRUCTOR_ELT (t, j)->value = value;
7029 : }
7030 13849 : ++j;
7031 : }
7032 19262 : if (CONSTRUCTOR_NELTS (t) != j)
7033 84 : vec_safe_truncate (CONSTRUCTOR_ELTS (t), j);
7034 : }
7035 :
7036 : /* Subroutine of cxx_eval_constant_expression.
7037 : Attempt to evaluate a BIT_CAST_EXPR. */
7038 :
7039 : static tree
7040 4025 : cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
7041 : bool *overflow_p, tree *jump_target)
7042 : {
7043 4025 : if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
7044 4025 : TREE_TYPE (t))
7045 12733 : || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0),
7046 3944 : EXPR_LOCATION (t)),
7047 3944 : TREE_TYPE (TREE_OPERAND (t, 0)),
7048 3944 : TREE_TYPE (TREE_OPERAND (t, 0))))
7049 : {
7050 156 : *non_constant_p = true;
7051 156 : return t;
7052 : }
7053 :
7054 3869 : tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue,
7055 : non_constant_p, overflow_p,
7056 : jump_target);
7057 3869 : if (*non_constant_p)
7058 : return t;
7059 2820 : if (*jump_target)
7060 : return NULL_TREE;
7061 :
7062 2820 : location_t loc = EXPR_LOCATION (t);
7063 2820 : if (BITS_PER_UNIT != 8 || CHAR_BIT != 8)
7064 : {
7065 : if (!ctx->quiet)
7066 : sorry_at (loc, "%qs cannot be constant evaluated on the target",
7067 : "__builtin_bit_cast");
7068 : *non_constant_p = true;
7069 : return t;
7070 : }
7071 :
7072 2820 : if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))))
7073 : {
7074 0 : if (!ctx->quiet)
7075 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7076 : "type is too large", "__builtin_bit_cast");
7077 0 : *non_constant_p = true;
7078 0 : return t;
7079 : }
7080 :
7081 2820 : HOST_WIDE_INT len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t)));
7082 2820 : if (len < 0 || (int) len != len)
7083 : {
7084 0 : if (!ctx->quiet)
7085 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7086 : "type is too large", "__builtin_bit_cast");
7087 0 : *non_constant_p = true;
7088 0 : return t;
7089 : }
7090 :
7091 2820 : unsigned char buf[64];
7092 2820 : unsigned char *ptr, *mask;
7093 2820 : size_t alen = (size_t) len * 2;
7094 2820 : if (alen <= sizeof (buf))
7095 : ptr = buf;
7096 : else
7097 329 : ptr = XNEWVEC (unsigned char, alen);
7098 2820 : mask = ptr + (size_t) len;
7099 : /* At the beginning consider everything indeterminate. */
7100 2820 : memset (mask, ~0, (size_t) len);
7101 :
7102 2820 : if (native_encode_initializer (op, ptr, len, 0, mask) != len)
7103 : {
7104 0 : if (!ctx->quiet)
7105 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7106 : "argument cannot be encoded", "__builtin_bit_cast");
7107 0 : *non_constant_p = true;
7108 0 : if (ptr != buf)
7109 0 : XDELETE (ptr);
7110 : return t;
7111 : }
7112 :
7113 2820 : tree r = NULL_TREE;
7114 2820 : if (can_native_interpret_type_p (TREE_TYPE (t)))
7115 : {
7116 481 : r = native_interpret_expr (TREE_TYPE (t), ptr, len);
7117 481 : if (is_byte_access_type_not_plain_char (TREE_TYPE (t)))
7118 : {
7119 52 : gcc_assert (len == 1);
7120 52 : if (mask[0])
7121 : {
7122 27 : memset (mask, 0, len);
7123 27 : r = build_constructor (TREE_TYPE (r), NULL);
7124 27 : CONSTRUCTOR_NO_CLEARING (r) = 1;
7125 : }
7126 : }
7127 : }
7128 2339 : else if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
7129 : {
7130 2339 : r = native_interpret_aggregate (TREE_TYPE (t), ptr, 0, len);
7131 2339 : if (r != NULL_TREE)
7132 : {
7133 2339 : clear_type_padding_in_mask (TREE_TYPE (t), mask);
7134 2339 : clear_uchar_or_std_byte_in_mask (loc, r, mask);
7135 2339 : if (CHECKING_P)
7136 : {
7137 2339 : tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue,
7138 : non_constant_p, overflow_p,
7139 : jump_target);
7140 2339 : gcc_checking_assert (e == r && !*jump_target);
7141 : r = e;
7142 : }
7143 : }
7144 : }
7145 :
7146 2820 : if (r != NULL_TREE)
7147 : {
7148 92041 : for (int i = 0; i < len; i++)
7149 89311 : if (mask[i])
7150 : {
7151 90 : if (!ctx->quiet)
7152 30 : error_at (loc, "%qs accessing uninitialized byte at offset %d",
7153 : "__builtin_bit_cast", i);
7154 90 : *non_constant_p = true;
7155 90 : r = t;
7156 90 : break;
7157 : }
7158 2820 : if (ptr != buf)
7159 329 : XDELETE (ptr);
7160 : return r;
7161 : }
7162 :
7163 0 : if (!ctx->quiet)
7164 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
7165 : "argument cannot be interpreted", "__builtin_bit_cast");
7166 0 : *non_constant_p = true;
7167 0 : if (ptr != buf)
7168 0 : XDELETE (ptr);
7169 : return t;
7170 : }
7171 :
7172 : /* Subroutine of cxx_eval_constant_expression.
7173 : Evaluate a short-circuited logical expression T in the context
7174 : of a given constexpr CALL. BAILOUT_VALUE is the value for
7175 : early return. CONTINUE_VALUE is used here purely for
7176 : sanity check purposes. */
7177 :
7178 : static tree
7179 18483962 : cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
7180 : tree bailout_value, tree continue_value,
7181 : bool *non_constant_p, bool *overflow_p,
7182 : tree *jump_target)
7183 : {
7184 18483962 : tree r;
7185 18483962 : tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
7186 : vc_prvalue, non_constant_p,
7187 : overflow_p, jump_target);
7188 18483960 : if (*jump_target)
7189 : return NULL_TREE;
7190 18483951 : VERIFY_CONSTANT (lhs);
7191 13696833 : if (tree_int_cst_equal (lhs, bailout_value))
7192 : return lhs;
7193 11660270 : gcc_assert (tree_int_cst_equal (lhs, continue_value));
7194 11660270 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
7195 : vc_prvalue, non_constant_p,
7196 : overflow_p, jump_target);
7197 11660270 : if (*jump_target)
7198 : return NULL_TREE;
7199 11660270 : VERIFY_CONSTANT (r);
7200 : return r;
7201 : }
7202 :
7203 : /* REF is a COMPONENT_REF designating a particular field. V is a vector of
7204 : CONSTRUCTOR elements to initialize (part of) an object containing that
7205 : field. Return a pointer to the constructor_elt corresponding to the
7206 : initialization of the field. */
7207 :
7208 : static constructor_elt *
7209 0 : base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
7210 : {
7211 0 : tree aggr = TREE_OPERAND (ref, 0);
7212 0 : tree field = TREE_OPERAND (ref, 1);
7213 0 : HOST_WIDE_INT i;
7214 0 : constructor_elt *ce;
7215 :
7216 0 : gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
7217 :
7218 0 : if (TREE_CODE (aggr) == COMPONENT_REF)
7219 : {
7220 0 : constructor_elt *base_ce
7221 0 : = base_field_constructor_elt (v, aggr);
7222 0 : v = CONSTRUCTOR_ELTS (base_ce->value);
7223 : }
7224 :
7225 0 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
7226 0 : if (ce->index == field)
7227 0 : return ce;
7228 :
7229 0 : gcc_unreachable ();
7230 : return NULL;
7231 : }
7232 :
7233 : /* Some of the expressions fed to the constexpr mechanism are calls to
7234 : constructors, which have type void. In that case, return the type being
7235 : initialized by the constructor. */
7236 :
7237 : static tree
7238 610082107 : initialized_type (tree t)
7239 : {
7240 611746188 : if (TYPE_P (t))
7241 : return t;
7242 611745724 : tree type = TREE_TYPE (t);
7243 611745724 : if (TREE_CODE (t) == CALL_EXPR)
7244 : {
7245 : /* A constructor call has void type, so we need to look deeper. */
7246 74131355 : tree fn = get_function_named_in_call (t);
7247 74124876 : if (fn && TREE_CODE (fn) == FUNCTION_DECL
7248 148129738 : && DECL_CXX_CONSTRUCTOR_P (fn))
7249 4097008 : type = DECL_CONTEXT (fn);
7250 : }
7251 537614369 : else if (TREE_CODE (t) == COMPOUND_EXPR)
7252 1664081 : return initialized_type (TREE_OPERAND (t, 1));
7253 535950288 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
7254 883071 : type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
7255 610081643 : return cv_unqualified (type);
7256 : }
7257 :
7258 : /* We're about to initialize element INDEX of an array or class from VALUE.
7259 : Set up NEW_CTX appropriately by adjusting .object to refer to the
7260 : subobject and creating a new CONSTRUCTOR if the element is itself
7261 : a class or array. */
7262 :
7263 : static void
7264 4200518 : init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
7265 : tree index, tree &value)
7266 : {
7267 4200518 : new_ctx = *ctx;
7268 :
7269 4200518 : if (index && TREE_CODE (index) != INTEGER_CST
7270 3763260 : && TREE_CODE (index) != FIELD_DECL
7271 3 : && TREE_CODE (index) != RANGE_EXPR)
7272 : /* This won't have an element in the new CONSTRUCTOR. */
7273 : return;
7274 :
7275 4200518 : tree type = initialized_type (value);
7276 4200518 : if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
7277 : /* A non-aggregate member doesn't get its own CONSTRUCTOR. */
7278 : return;
7279 :
7280 1696095 : tree ctxtype = NULL_TREE;
7281 1696095 : if (ctx->ctor)
7282 1696078 : ctxtype = TREE_TYPE (ctx->ctor);
7283 17 : else if (ctx->object)
7284 14 : ctxtype = TREE_TYPE (ctx->object);
7285 : else
7286 : {
7287 : /* This can happen if the enclosing object is also an empty subobject
7288 : (c++/125315). */
7289 3 : gcc_checking_assert (is_empty_field (index));
7290 : return;
7291 : }
7292 :
7293 1696092 : if (VECTOR_TYPE_P (type)
7294 7417 : && VECTOR_TYPE_P (ctxtype)
7295 2596 : && index == NULL_TREE)
7296 : /* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
7297 : vector is constructed from smaller vectors, doesn't get its own
7298 : CONSTRUCTOR either. */
7299 : return;
7300 :
7301 : /* The sub-aggregate initializer might contain a placeholder;
7302 : update object to refer to the subobject and ctor to refer to
7303 : the (newly created) sub-initializer. */
7304 1693496 : if (ctx->object)
7305 : {
7306 1530867 : if (index == NULL_TREE || TREE_CODE (index) == RANGE_EXPR)
7307 : /* There's no well-defined subobject for this index. */
7308 3 : new_ctx.object = NULL_TREE;
7309 : else
7310 1530864 : new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
7311 : }
7312 :
7313 1693496 : if (is_empty_field (index)
7314 1693496 : && TREE_CODE (ctxtype) != UNION_TYPE)
7315 : /* Leave ctor null for an empty subobject of a non-union class, they aren't
7316 : represented in the result of evaluation. */
7317 1518130 : new_ctx.ctor = NULL_TREE;
7318 : else
7319 : {
7320 175366 : tree elt = build_constructor (type, NULL);
7321 175366 : CONSTRUCTOR_NO_CLEARING (elt) = true;
7322 175366 : new_ctx.ctor = elt;
7323 : }
7324 :
7325 1693496 : if (TREE_CODE (value) == TARGET_EXPR)
7326 : /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */
7327 120255 : value = TARGET_EXPR_INITIAL (value);
7328 : }
7329 :
7330 : /* We're about to process an initializer for a class or array TYPE. Make
7331 : sure that CTX is set up appropriately. */
7332 :
7333 : static void
7334 3390722 : verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
7335 : {
7336 : /* We don't bother building a ctor for an empty base subobject. */
7337 3390722 : if (is_empty_class (type))
7338 : return;
7339 :
7340 : /* We're in the middle of an initializer that might involve placeholders;
7341 : our caller should have created a CONSTRUCTOR for us to put the
7342 : initializer into. We will either return that constructor or T. */
7343 1890823 : gcc_assert (ctx->ctor);
7344 1890823 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
7345 : (type, TREE_TYPE (ctx->ctor)));
7346 : /* We used to check that ctx->ctor was empty, but that isn't the case when
7347 : the object is zero-initialized before calling the constructor. */
7348 1890823 : if (ctx->object)
7349 : {
7350 1675681 : tree otype = TREE_TYPE (ctx->object);
7351 1675681 : gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)
7352 : /* Handle flexible array members. */
7353 : || (TREE_CODE (otype) == ARRAY_TYPE
7354 : && TYPE_DOMAIN (otype) == NULL_TREE
7355 : && TREE_CODE (type) == ARRAY_TYPE
7356 : && (same_type_ignoring_top_level_qualifiers_p
7357 : (TREE_TYPE (type), TREE_TYPE (otype)))));
7358 : }
7359 1890823 : gcc_assert (!ctx->object || !DECL_P (ctx->object)
7360 : || ctx->global->get_value (ctx->object) == ctx->ctor);
7361 : }
7362 :
7363 : /* Subroutine of cxx_eval_constant_expression.
7364 : The expression tree T denotes a C-style array or a C-style
7365 : aggregate. Reduce it to a constant expression. */
7366 :
7367 : static tree
7368 3389818 : cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
7369 : value_cat lval,
7370 : bool *non_constant_p, bool *overflow_p,
7371 : tree *jump_target)
7372 : {
7373 3389818 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
7374 3389818 : bool changed = false;
7375 3389818 : gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
7376 3389818 : tree type = TREE_TYPE (t);
7377 :
7378 3389818 : constexpr_ctx new_ctx;
7379 3389818 : if (TYPE_PTRMEMFUNC_P (type) || VECTOR_TYPE_P (type))
7380 : {
7381 : /* We don't really need the ctx->ctor business for a PMF or
7382 : vector, but it's simpler to use the same code. */
7383 56001 : new_ctx = *ctx;
7384 56001 : new_ctx.ctor = build_constructor (type, NULL);
7385 56001 : new_ctx.object = NULL_TREE;
7386 56001 : ctx = &new_ctx;
7387 3389818 : };
7388 3389818 : verify_ctor_sanity (ctx, type);
7389 3389818 : vec<constructor_elt, va_gc> **p = nullptr;
7390 3389818 : if (ctx->ctor)
7391 : {
7392 3389801 : p = &CONSTRUCTOR_ELTS (ctx->ctor);
7393 6776153 : vec_alloc (*p, vec_safe_length (v));
7394 3389801 : if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t))
7395 16083 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1;
7396 : }
7397 :
7398 3389818 : unsigned i;
7399 3389818 : tree index, value;
7400 3389818 : bool constant_p = true;
7401 3389818 : bool side_effects_p = false;
7402 6859275 : FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
7403 : {
7404 4194081 : tree orig_value = value;
7405 4194081 : init_subob_ctx (ctx, new_ctx, index, value);
7406 : /* Like in cxx_eval_store_expression, omit entries for empty fields. */
7407 4194081 : bool no_slot = new_ctx.ctor == NULL_TREE;
7408 4194081 : int pos_hint = -1;
7409 4194081 : if (!ctx->ctor)
7410 : /* The enclosing object could be an empty subobject so we have no
7411 : CONSTRUCTOR (c++/125336). */
7412 17 : gcc_checking_assert (is_empty_class (type));
7413 4194064 : else if (new_ctx.ctor != ctx->ctor && !no_slot)
7414 : {
7415 : /* If we built a new CONSTRUCTOR, attach it now so that other
7416 : initializers can refer to it. */
7417 169228 : constructor_elt *cep = get_or_insert_ctor_field (ctx->ctor, index);
7418 169228 : cep->value = new_ctx.ctor;
7419 169228 : pos_hint = cep - (*p)->begin();
7420 169228 : }
7421 4024836 : else if (TREE_CODE (type) == UNION_TYPE)
7422 : /* Otherwise if we're constructing a non-aggregate union member, set
7423 : the active union member now so that we can later detect and diagnose
7424 : if its initializer attempts to activate another member. */
7425 1089 : get_or_insert_ctor_field (ctx->ctor, index);
7426 4194081 : tree elt = cxx_eval_constant_expression (&new_ctx, value,
7427 : lval,
7428 : non_constant_p, overflow_p,
7429 : jump_target);
7430 4194081 : if (*jump_target)
7431 : return NULL_TREE;
7432 : /* Don't VERIFY_CONSTANT here. */
7433 4194075 : if (ctx->quiet && *non_constant_p)
7434 : break;
7435 3469457 : if (elt != orig_value)
7436 1245240 : changed = true;
7437 :
7438 3469457 : if (!TREE_CONSTANT (elt))
7439 955753 : constant_p = false;
7440 3469457 : if (TREE_SIDE_EFFECTS (elt))
7441 281 : side_effects_p = true;
7442 3469457 : if (index && TREE_CODE (index) == COMPONENT_REF)
7443 : {
7444 : /* This is an initialization of a vfield inside a base
7445 : subaggregate that we already initialized; push this
7446 : initialization into the previous initialization. */
7447 0 : constructor_elt *inner = base_field_constructor_elt (*p, index);
7448 0 : inner->value = elt;
7449 0 : changed = true;
7450 0 : }
7451 3469457 : else if (no_slot)
7452 : /* This is an initializer for an empty field; now that we've
7453 : checked that it's constant, we can ignore it. */
7454 : changed = true;
7455 1952493 : else if (ctx->ctor)
7456 : {
7457 1952493 : if (TREE_CODE (type) == UNION_TYPE
7458 1952493 : && (*p)->last().index != index)
7459 : /* The initializer erroneously changed the active union member that
7460 : we're initializing. */
7461 7 : gcc_assert (*non_constant_p);
7462 : else
7463 : {
7464 : /* The initializer might have mutated the underlying CONSTRUCTOR,
7465 : so recompute the location of the target constructer_elt. */
7466 1952486 : constructor_elt *cep
7467 1952486 : = get_or_insert_ctor_field (ctx->ctor, index, pos_hint);
7468 1952486 : cep->value = elt;
7469 : }
7470 :
7471 : /* Adding or replacing an element might change the ctor's flags. */
7472 1952493 : TREE_CONSTANT (ctx->ctor) = constant_p;
7473 1952493 : TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
7474 : }
7475 : }
7476 3389812 : if (*non_constant_p)
7477 : return t;
7478 2665127 : if (!changed)
7479 : {
7480 267697 : if (VECTOR_TYPE_P (type))
7481 14408 : t = fold (t);
7482 : return t;
7483 : }
7484 2397430 : t = ctx->ctor;
7485 2397430 : if (!t)
7486 8 : t = build_constructor (type, NULL);
7487 : /* We're done building this CONSTRUCTOR, so now we can interpret an
7488 : element without an explicit initializer as value-initialized. */
7489 2397430 : CONSTRUCTOR_NO_CLEARING (t) = false;
7490 2397430 : TREE_CONSTANT (t) = constant_p;
7491 2397430 : TREE_SIDE_EFFECTS (t) = side_effects_p;
7492 2397430 : if (VECTOR_TYPE_P (type))
7493 11444 : t = fold (t);
7494 : return t;
7495 : }
7496 :
7497 : /* Subroutine of cxx_eval_constant_expression.
7498 : The expression tree T is a VEC_INIT_EXPR which denotes the desired
7499 : initialization of a non-static data member of array type. Reduce it to a
7500 : CONSTRUCTOR.
7501 :
7502 : Note that apart from value-initialization (when VALUE_INIT is true),
7503 : this is only intended to support value-initialization and the
7504 : initializations done by defaulted constructors for classes with
7505 : non-static data members of array type. In this case, VEC_INIT_EXPR_INIT
7506 : will either be NULL_TREE for the default constructor, or a COMPONENT_REF
7507 : for the copy/move constructor. */
7508 :
7509 : static tree
7510 904 : cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
7511 : bool value_init, value_cat lval,
7512 : bool *non_constant_p, bool *overflow_p,
7513 : tree *jump_target)
7514 : {
7515 904 : tree elttype = TREE_TYPE (atype);
7516 904 : verify_ctor_sanity (ctx, atype);
7517 904 : vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
7518 904 : bool pre_init = false;
7519 904 : unsigned HOST_WIDE_INT i;
7520 904 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7521 :
7522 904 : if (init && TREE_CODE (init) == CONSTRUCTOR)
7523 0 : return cxx_eval_bare_aggregate (ctx, init, lval,
7524 0 : non_constant_p, overflow_p, jump_target);
7525 :
7526 : /* We already checked access when building the VEC_INIT_EXPR. */
7527 904 : deferring_access_check_sentinel acs (dk_deferred);
7528 :
7529 : /* For the default constructor, build up a call to the default
7530 : constructor of the element type. We only need to handle class types
7531 : here, as for a constructor to be constexpr, all members must be
7532 : initialized, which for a defaulted default constructor means they must
7533 : be of a class type with a constexpr default constructor. */
7534 904 : if (TREE_CODE (elttype) == ARRAY_TYPE)
7535 : /* We only do this at the lowest level. */;
7536 850 : else if (value_init)
7537 : {
7538 336 : init = build_value_init (elttype, complain);
7539 336 : pre_init = true;
7540 : }
7541 514 : else if (!init)
7542 : {
7543 402 : releasing_vec argvec;
7544 402 : init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
7545 : &argvec, elttype, LOOKUP_NORMAL,
7546 : complain);
7547 402 : init = build_aggr_init_expr (elttype, init);
7548 402 : pre_init = true;
7549 402 : }
7550 :
7551 904 : bool zeroed_out = false;
7552 904 : if (!CONSTRUCTOR_NO_CLEARING (ctx->ctor))
7553 : {
7554 : /* We're initializing an array object that had been zero-initialized
7555 : earlier. Truncate ctx->ctor, and propagate its zeroed state by
7556 : clearing CONSTRUCTOR_NO_CLEARING on each of the aggregate element
7557 : initializers we append to it. */
7558 156 : gcc_checking_assert (initializer_zerop (ctx->ctor));
7559 156 : zeroed_out = true;
7560 156 : vec_safe_truncate (*p, 0);
7561 : }
7562 :
7563 904 : tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
7564 : overflow_p, jump_target);
7565 904 : if (*jump_target)
7566 : return NULL_TREE;
7567 904 : unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
7568 6674 : for (i = 0; i < max; ++i)
7569 : {
7570 6437 : tree idx = build_int_cst (size_type_node, i);
7571 6437 : tree eltinit;
7572 6437 : bool reuse = false;
7573 6437 : constexpr_ctx new_ctx;
7574 6901 : init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
7575 6437 : bool no_slot = new_ctx.ctor == NULL_TREE;
7576 6437 : if (new_ctx.ctor != ctx->ctor && !no_slot)
7577 : {
7578 6138 : if (zeroed_out)
7579 5445 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = false;
7580 6138 : CONSTRUCTOR_APPEND_ELT (*p, idx, new_ctx.ctor);
7581 : }
7582 6437 : if (TREE_CODE (elttype) == ARRAY_TYPE)
7583 : {
7584 : /* A multidimensional array; recurse. */
7585 186 : if (value_init || init == NULL_TREE)
7586 : {
7587 176 : eltinit = NULL_TREE;
7588 176 : reuse = i == 0;
7589 : }
7590 : else
7591 10 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7592 186 : eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit,
7593 : value_init, lval, non_constant_p,
7594 : overflow_p, jump_target);
7595 : }
7596 6251 : else if (pre_init)
7597 : {
7598 : /* Initializing an element using value or default initialization
7599 : we just pre-built above. */
7600 5973 : if (init == void_node)
7601 : /* Trivial default-init, don't do anything to the CONSTRUCTOR. */
7602 10 : return ctx->ctor;
7603 5963 : eltinit = init;
7604 5963 : if (CLASS_TYPE_P (elttype) && new_ctx.object)
7605 : /* Clarify what object is being initialized (118285). */
7606 5665 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7607 5963 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7608 : non_constant_p, overflow_p,
7609 : jump_target);
7610 5963 : reuse = i == 0;
7611 : }
7612 : else
7613 : {
7614 : /* Copying an element. */
7615 278 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7616 278 : if (!lvalue_p (init))
7617 232 : eltinit = move (eltinit);
7618 278 : eltinit = (perform_implicit_conversion_flags
7619 278 : (elttype, eltinit, complain,
7620 : LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
7621 271 : if (CLASS_TYPE_P (elttype)
7622 271 : && new_ctx.object
7623 526 : && !error_operand_p (eltinit))
7624 : /* Clarify what object is being initialized (118285). */
7625 244 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7626 278 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7627 : non_constant_p, overflow_p,
7628 : jump_target);
7629 : }
7630 6427 : if (*jump_target)
7631 : return NULL_TREE;
7632 6427 : if (*non_constant_p)
7633 : break;
7634 6249 : if (no_slot)
7635 : {
7636 : /* This is an initializer for an empty subobject; now that we've
7637 : checked that it's constant, we can ignore it. */
7638 0 : gcc_checking_assert (i == 0);
7639 : break;
7640 : }
7641 6249 : else if (new_ctx.ctor != ctx->ctor)
7642 : {
7643 : /* We appended this element above; update the value. */
7644 5957 : gcc_assert ((*p)->last().index == idx);
7645 5957 : (*p)->last().value = eltinit;
7646 : }
7647 : else
7648 292 : CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
7649 : /* Reuse the result of cxx_eval_constant_expression call
7650 : from the first iteration to all others if it is a constant
7651 : initializer that doesn't require relocations. */
7652 6249 : if (reuse
7653 6249 : && max > 1
7654 6249 : && (eltinit == NULL_TREE
7655 632 : || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
7656 632 : == null_pointer_node)))
7657 : {
7658 479 : if (new_ctx.ctor != ctx->ctor)
7659 201 : eltinit = new_ctx.ctor;
7660 479 : tree range = build2 (RANGE_EXPR, size_type_node,
7661 : build_int_cst (size_type_node, 1),
7662 479 : build_int_cst (size_type_node, max - 1));
7663 479 : CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
7664 479 : break;
7665 : }
7666 5770 : else if (i == 0)
7667 234 : vec_safe_reserve (*p, max);
7668 : }
7669 :
7670 894 : if (!*non_constant_p)
7671 : {
7672 716 : init = ctx->ctor;
7673 716 : CONSTRUCTOR_NO_CLEARING (init) = false;
7674 : }
7675 894 : return init;
7676 : }
7677 :
7678 : static tree
7679 790 : cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
7680 : value_cat lval,
7681 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
7682 : {
7683 790 : tree atype = TREE_TYPE (t);
7684 790 : tree init = VEC_INIT_EXPR_INIT (t);
7685 790 : bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
7686 790 : if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
7687 : ;
7688 83 : else if (CONSTRUCTOR_NELTS (init) == 0
7689 83 : && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
7690 : {
7691 : /* Handle {} as value-init. */
7692 : init = NULL_TREE;
7693 : value_init = true;
7694 : }
7695 : else
7696 : {
7697 : /* This is a more complicated case, like needing to loop over trailing
7698 : elements; call build_vec_init and evaluate the result. */
7699 72 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7700 72 : constexpr_ctx new_ctx = *ctx;
7701 72 : if (!ctx->object)
7702 : {
7703 : /* We want to have an initialization target for an VEC_INIT_EXPR.
7704 : If we don't already have one in CTX, use the VEC_INIT_EXPR_SLOT. */
7705 57 : new_ctx.object = VEC_INIT_EXPR_SLOT (t);
7706 57 : tree ctor = new_ctx.ctor = build_constructor (atype, NULL);
7707 57 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
7708 57 : ctx->global->put_value (new_ctx.object, ctor);
7709 57 : ctx = &new_ctx;
7710 : }
7711 72 : init = expand_vec_init_expr (ctx->object, t, complain);
7712 72 : return cxx_eval_constant_expression (ctx, init, lval, non_constant_p,
7713 : overflow_p, jump_target);
7714 : }
7715 718 : tree r = cxx_eval_vec_init_1 (ctx, atype, init, value_init,
7716 : lval, non_constant_p, overflow_p, jump_target);
7717 718 : if (*non_constant_p)
7718 : return t;
7719 : else
7720 566 : return r;
7721 : }
7722 :
7723 : /* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
7724 : where the desired type is an array of unknown bounds because the variable
7725 : has had its bounds deduced since the wrapping expression was created. */
7726 :
7727 : static bool
7728 445601775 : same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
7729 : {
7730 445601775 : while (TREE_CODE (type1) == ARRAY_TYPE
7731 144752 : && TREE_CODE (type2) == ARRAY_TYPE
7732 445601779 : && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
7733 : {
7734 2 : type1 = TREE_TYPE (type1);
7735 2 : type2 = TREE_TYPE (type2);
7736 : }
7737 445601775 : return same_type_ignoring_top_level_qualifiers_p (type1, type2);
7738 : }
7739 :
7740 : /* Try to determine the currently active union member for an expression
7741 : with UNION_TYPE. If it can be determined, return the FIELD_DECL,
7742 : otherwise return NULL_TREE. */
7743 :
7744 : static tree
7745 86 : cxx_union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target)
7746 : {
7747 86 : constexpr_ctx new_ctx = *ctx;
7748 86 : new_ctx.quiet = true;
7749 86 : bool non_constant_p = false, overflow_p = false;
7750 86 : tree ctor = cxx_eval_constant_expression (&new_ctx, t, vc_prvalue,
7751 : &non_constant_p,
7752 : &overflow_p, jump_target);
7753 86 : if (*jump_target)
7754 : return NULL_TREE;
7755 86 : if (TREE_CODE (ctor) == CONSTRUCTOR
7756 32 : && CONSTRUCTOR_NELTS (ctor) == 1
7757 20 : && CONSTRUCTOR_ELT (ctor, 0)->index
7758 106 : && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL)
7759 : return CONSTRUCTOR_ELT (ctor, 0)->index;
7760 : return NULL_TREE;
7761 : }
7762 :
7763 : /* Helper function for cxx_fold_indirect_ref_1, called recursively. */
7764 :
7765 : static tree
7766 15257535 : cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
7767 : tree op, unsigned HOST_WIDE_INT off, bool *empty_base,
7768 : tree *jump_target)
7769 : {
7770 24734527 : tree optype = TREE_TYPE (op);
7771 24734527 : unsigned HOST_WIDE_INT const_nunits;
7772 24734527 : if (off == 0 && similar_type_p (optype, type))
7773 : return op;
7774 15252791 : else if (cxx_dialect >= cxx26
7775 9344423 : && VAR_P (op)
7776 5326992 : && DECL_VTABLE_OR_VTT_P (op)
7777 15646 : && same_type_ignoring_top_level_qualifiers_p (type,
7778 : ptrdiff_type_node)
7779 15254136 : && POINTER_TYPE_P (strip_array_types (optype)))
7780 : {
7781 : /* We often read some virtual table elements using ptrdiff_t rather
7782 : than pointer type. */
7783 1345 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc,
7784 : strip_array_types (optype),
7785 : op, off, empty_base,
7786 : jump_target))
7787 1345 : return fold_convert (type, ret);
7788 : }
7789 15251446 : else if (TREE_CODE (optype) == COMPLEX_TYPE
7790 15251446 : && similar_type_p (type, TREE_TYPE (optype)))
7791 : {
7792 : /* *(foo *)&complexfoo => __real__ complexfoo */
7793 0 : if (off == 0)
7794 0 : return build1_loc (loc, REALPART_EXPR, type, op);
7795 : /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
7796 0 : else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
7797 0 : return build1_loc (loc, IMAGPART_EXPR, type, op);
7798 : }
7799 : /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF<vectorfoo,...> */
7800 15251446 : else if (VECTOR_TYPE_P (optype)
7801 0 : && similar_type_p (type, TREE_TYPE (optype))
7802 15251446 : && TYPE_VECTOR_SUBPARTS (optype).is_constant (&const_nunits))
7803 : {
7804 0 : unsigned HOST_WIDE_INT part_width = tree_to_uhwi (TYPE_SIZE_UNIT (type));
7805 0 : unsigned HOST_WIDE_INT max_offset = part_width * const_nunits;
7806 0 : if (off < max_offset && off % part_width == 0)
7807 : {
7808 0 : tree index = bitsize_int (off * BITS_PER_UNIT);
7809 0 : return build3_loc (loc, BIT_FIELD_REF, type, op,
7810 0 : TYPE_SIZE (type), index);
7811 : }
7812 : }
7813 : /* ((foo *)&fooarray)[x] => fooarray[x] */
7814 15251446 : else if (TREE_CODE (optype) == ARRAY_TYPE
7815 9476992 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
7816 24728438 : && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
7817 : {
7818 9476992 : tree type_domain = TYPE_DOMAIN (optype);
7819 9476992 : tree min_val = size_zero_node;
7820 9476992 : if (type_domain && TYPE_MIN_VALUE (type_domain))
7821 9476787 : min_val = TYPE_MIN_VALUE (type_domain);
7822 9476992 : unsigned HOST_WIDE_INT el_sz
7823 9476992 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
7824 9476992 : unsigned HOST_WIDE_INT idx = off / el_sz;
7825 9476992 : unsigned HOST_WIDE_INT rem = off % el_sz;
7826 9476992 : if (tree_fits_uhwi_p (min_val))
7827 : {
7828 9476992 : tree index = size_int (idx + tree_to_uhwi (min_val));
7829 9476992 : op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
7830 : NULL_TREE, NULL_TREE);
7831 9476992 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
7832 9476992 : empty_base, jump_target);
7833 : }
7834 : }
7835 : /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
7836 5774454 : else if (TREE_CODE (optype) == RECORD_TYPE
7837 5774454 : || TREE_CODE (optype) == UNION_TYPE)
7838 : {
7839 5766127 : if (TREE_CODE (optype) == UNION_TYPE)
7840 : /* For unions prefer the currently active member. */
7841 86 : if (tree field = cxx_union_active_member (ctx, op, jump_target))
7842 : {
7843 20 : unsigned HOST_WIDE_INT el_sz
7844 20 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7845 20 : if (off < el_sz)
7846 : {
7847 20 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7848 : op, field, NULL_TREE);
7849 20 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7850 : off, empty_base,
7851 : jump_target))
7852 : return ret;
7853 : }
7854 : }
7855 :
7856 : /* Handle conversion to "as base" type. */
7857 5766113 : if (CLASS_TYPE_P (optype)
7858 11532062 : && CLASSTYPE_AS_BASE (optype) == type)
7859 : return op;
7860 :
7861 : /* Handle conversion to an empty base class, which is represented with a
7862 : NOP_EXPR. Do this before spelunking into the non-empty subobjects,
7863 : which is likely to be a waste of time (109678). */
7864 5760033 : if (is_empty_class (type)
7865 5418832 : && CLASS_TYPE_P (optype)
7866 11178859 : && lookup_base (optype, type, ba_any, NULL, tf_none, off))
7867 : {
7868 2634119 : if (empty_base)
7869 2634119 : *empty_base = true;
7870 : return op;
7871 : }
7872 :
7873 3125914 : for (tree field = TYPE_FIELDS (optype);
7874 44745146 : field; field = DECL_CHAIN (field))
7875 44697561 : if (TREE_CODE (field) == FIELD_DECL
7876 3138496 : && TREE_TYPE (field) != error_mark_node
7877 47836057 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (field))))
7878 : {
7879 3138492 : tree pos = byte_position (field);
7880 3138492 : if (!tree_fits_uhwi_p (pos))
7881 0 : continue;
7882 3138492 : unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos);
7883 3138492 : unsigned HOST_WIDE_INT el_sz;
7884 3138492 : if (DECL_FIELD_IS_BASE (field)
7885 787684 : && CLASS_TYPE_P (optype)
7886 3926176 : && CLASSTYPE_VBASECLASSES (optype))
7887 7765 : el_sz = tree_to_uhwi (DECL_SIZE_UNIT (field));
7888 : else
7889 3130727 : el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7890 3138492 : if (upos <= off && off < upos + el_sz)
7891 : {
7892 3125765 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7893 : op, field, NULL_TREE);
7894 3125765 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7895 : off - upos,
7896 : empty_base,
7897 : jump_target))
7898 : return ret;
7899 : }
7900 : }
7901 : }
7902 :
7903 : return NULL_TREE;
7904 : }
7905 :
7906 : /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
7907 : match. We want to be less strict for simple *& folding; if we have a
7908 : non-const temporary that we access through a const pointer, that should
7909 : work. We handle this here rather than change fold_indirect_ref_1
7910 : because we're dealing with things like ADDR_EXPR of INTEGER_CST which
7911 : don't really make sense outside of constant expression evaluation. Also
7912 : we want to allow folding to COMPONENT_REF, which could cause trouble
7913 : with TBAA in fold_indirect_ref_1. */
7914 :
7915 : static tree
7916 196569904 : cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
7917 : tree op0, bool *empty_base, tree *jump_target)
7918 : {
7919 196569904 : tree sub = op0;
7920 196569904 : tree subtype;
7921 :
7922 : /* STRIP_NOPS, but stop if REINTERPRET_CAST_P. */
7923 405094773 : while (CONVERT_EXPR_P (sub) || TREE_CODE (sub) == NON_LVALUE_EXPR
7924 529099867 : || TREE_CODE (sub) == VIEW_CONVERT_EXPR)
7925 : {
7926 133468847 : if (TREE_CODE (sub) == NOP_EXPR
7927 133468847 : && REINTERPRET_CAST_P (sub))
7928 : return NULL_TREE;
7929 133468847 : sub = TREE_OPERAND (sub, 0);
7930 : }
7931 :
7932 196569904 : subtype = TREE_TYPE (sub);
7933 196569904 : if (!INDIRECT_TYPE_P (subtype))
7934 : return NULL_TREE;
7935 :
7936 : /* Canonicalizes the given OBJ/OFF pair by iteratively absorbing
7937 : the innermost component into the offset until it would make the
7938 : offset positive, so that cxx_fold_indirect_ref_1 can identify
7939 : more folding opportunities. */
7940 208700260 : auto canonicalize_obj_off = [] (tree& obj, tree& off) {
7941 12130405 : if (cxx_dialect >= cxx26)
7942 : {
7943 : /* For C++26, we need to fold *(B *)(&x.D.1234 + 32) used
7944 : to access virtual base members. */
7945 7261537 : tree nobj = obj;
7946 7261537 : while (TREE_CODE (nobj) == COMPONENT_REF
7947 7298046 : && DECL_FIELD_IS_BASE (TREE_OPERAND (nobj, 1)))
7948 36509 : nobj = TREE_OPERAND (nobj, 0);
7949 7261537 : if (nobj != obj
7950 28612 : && CLASS_TYPE_P (TREE_TYPE (nobj))
7951 7290149 : && CLASSTYPE_VBASECLASSES (TREE_TYPE (nobj)))
7952 2537 : while (obj != nobj)
7953 : {
7954 1424 : tree field = TREE_OPERAND (obj, 1);
7955 1424 : tree pos = byte_position (field);
7956 1424 : off = int_const_binop (PLUS_EXPR, off, pos);
7957 1424 : obj = TREE_OPERAND (obj, 0);
7958 : }
7959 : }
7960 15244439 : while (TREE_CODE (obj) == COMPONENT_REF
7961 : /* We need to preserve union member accesses so that we can
7962 : later properly diagnose accessing the wrong member. */
7963 6442039 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (obj, 0))) == RECORD_TYPE
7964 21461769 : && (tree_int_cst_sign_bit (off) || integer_zerop (off)))
7965 : {
7966 3303042 : tree field = TREE_OPERAND (obj, 1);
7967 3303042 : tree pos = byte_position (field);
7968 3303042 : if (integer_zerop (off) && integer_nonzerop (pos))
7969 : /* If the offset is already 0, keep going as long as the
7970 : component is at position 0. */
7971 : break;
7972 3114034 : off = int_const_binop (PLUS_EXPR, off, pos);
7973 3114034 : obj = TREE_OPERAND (obj, 0);
7974 : }
7975 12130405 : };
7976 :
7977 196569855 : if (TREE_CODE (sub) == ADDR_EXPR)
7978 : {
7979 87825217 : tree op = TREE_OPERAND (sub, 0);
7980 87825217 : tree optype = TREE_TYPE (op);
7981 :
7982 : /* *&CONST_DECL -> to the value of the const decl. */
7983 87825217 : if (TREE_CODE (op) == CONST_DECL)
7984 0 : return DECL_INITIAL (op);
7985 : /* *&p => p; make sure to handle *&"str"[cst] here. */
7986 87825217 : if (similar_type_p (optype, type))
7987 : {
7988 83908020 : tree fop = fold_read_from_constant_string (op);
7989 83908020 : if (fop)
7990 : return fop;
7991 : else
7992 83700345 : return op;
7993 : }
7994 : else
7995 : {
7996 3917197 : tree off = integer_zero_node;
7997 3917197 : canonicalize_obj_off (op, off);
7998 3917197 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op,
7999 : tree_to_uhwi (off), empty_base,
8000 : jump_target);
8001 : }
8002 : }
8003 108744638 : else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
8004 108744638 : && tree_fits_uhwi_p (TREE_OPERAND (sub, 1)))
8005 : {
8006 8810883 : tree op00 = TREE_OPERAND (sub, 0);
8007 8810883 : tree off = TREE_OPERAND (sub, 1);
8008 :
8009 8810883 : STRIP_NOPS (op00);
8010 8810883 : if (TREE_CODE (op00) == ADDR_EXPR)
8011 : {
8012 8213208 : tree obj = TREE_OPERAND (op00, 0);
8013 8213208 : canonicalize_obj_off (obj, off);
8014 8213208 : return cxx_fold_indirect_ref_1 (ctx, loc, type, obj,
8015 : tree_to_uhwi (off), empty_base,
8016 : jump_target);
8017 : }
8018 : }
8019 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
8020 99933755 : else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
8021 99933755 : && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
8022 : {
8023 0 : tree type_domain;
8024 0 : tree min_val = size_zero_node;
8025 0 : tree newsub
8026 0 : = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL,
8027 : jump_target);
8028 0 : if (*jump_target)
8029 : return NULL_TREE;
8030 0 : if (newsub)
8031 : sub = newsub;
8032 : else
8033 0 : sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
8034 0 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
8035 0 : if (type_domain && TYPE_MIN_VALUE (type_domain))
8036 0 : min_val = TYPE_MIN_VALUE (type_domain);
8037 0 : return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
8038 0 : NULL_TREE);
8039 : }
8040 :
8041 : return NULL_TREE;
8042 : }
8043 :
8044 : static tree
8045 103846674 : cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
8046 : value_cat lval,
8047 : bool *non_constant_p, bool *overflow_p,
8048 : tree *jump_target)
8049 : {
8050 103846674 : tree orig_op0 = TREE_OPERAND (t, 0);
8051 103846674 : bool empty_base = false;
8052 :
8053 : /* We can handle a MEM_REF like an INDIRECT_REF, if MEM_REF's second
8054 : operand is an integer-zero. Otherwise reject the MEM_REF for now. */
8055 :
8056 103846674 : if (TREE_CODE (t) == MEM_REF
8057 103846674 : && (!TREE_OPERAND (t, 1) || !integer_zerop (TREE_OPERAND (t, 1))))
8058 : {
8059 9 : gcc_assert (ctx->quiet);
8060 9 : *non_constant_p = true;
8061 9 : return t;
8062 : }
8063 :
8064 : /* First try to simplify it directly. */
8065 103846665 : tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
8066 : orig_op0, &empty_base, jump_target);
8067 103846665 : if (*jump_target)
8068 : return NULL_TREE;
8069 103846665 : if (!r)
8070 : {
8071 : /* If that didn't work, evaluate the operand first. */
8072 99835946 : tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
8073 : vc_prvalue, non_constant_p,
8074 : overflow_p, jump_target);
8075 99835946 : if (*jump_target)
8076 : return NULL_TREE;
8077 : /* Don't VERIFY_CONSTANT here. */
8078 99835934 : if (*non_constant_p)
8079 : return t;
8080 :
8081 78868712 : if (!lval && integer_zerop (op0))
8082 : {
8083 73 : if (!ctx->quiet)
8084 12 : error ("dereferencing a null pointer");
8085 73 : *non_constant_p = true;
8086 73 : return t;
8087 : }
8088 :
8089 78868639 : r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0,
8090 : &empty_base, jump_target);
8091 78868639 : if (*jump_target)
8092 : return NULL_TREE;
8093 78868639 : if (r == NULL_TREE)
8094 : {
8095 : /* We couldn't fold to a constant value. Make sure it's not
8096 : something we should have been able to fold. */
8097 703745 : tree sub = op0;
8098 703745 : STRIP_NOPS (sub);
8099 703745 : if (TREE_CODE (sub) == ADDR_EXPR)
8100 : {
8101 4034 : gcc_assert (!similar_type_p
8102 : (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
8103 : /* DR 1188 says we don't have to deal with this. */
8104 4034 : if (!ctx->quiet)
8105 : {
8106 9 : auto_diagnostic_group d;
8107 15 : error_at (cp_expr_loc_or_input_loc (t),
8108 : "accessing value of %qT object through a %qT "
8109 : "glvalue in a constant expression",
8110 9 : TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t));
8111 9 : tree ob = build_fold_indirect_ref (sub);
8112 9 : if (DECL_P (ob))
8113 : {
8114 9 : if (DECL_ARTIFICIAL (ob))
8115 2 : inform (DECL_SOURCE_LOCATION (ob),
8116 2 : "%qT object created here", TREE_TYPE (ob));
8117 : else
8118 7 : inform (DECL_SOURCE_LOCATION (ob),
8119 : "%q#D declared here", ob);
8120 : }
8121 9 : }
8122 4034 : *non_constant_p = true;
8123 4034 : return t;
8124 : }
8125 :
8126 699711 : if (lval == vc_glvalue && op0 != orig_op0)
8127 84261 : return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
8128 615450 : if (!lval)
8129 500586 : VERIFY_CONSTANT (t);
8130 : return t;
8131 : }
8132 : }
8133 :
8134 82175613 : r = cxx_eval_constant_expression (ctx, r,
8135 : lval, non_constant_p, overflow_p,
8136 : jump_target);
8137 82175611 : if (*jump_target)
8138 : return NULL_TREE;
8139 82175611 : if (*non_constant_p)
8140 : return t;
8141 :
8142 : /* If we're pulling out the value of an empty base, just return an empty
8143 : CONSTRUCTOR. */
8144 73119044 : if (empty_base && !lval)
8145 : {
8146 19629 : r = build_constructor (TREE_TYPE (t), NULL);
8147 19629 : TREE_CONSTANT (r) = true;
8148 : }
8149 :
8150 : return r;
8151 : }
8152 :
8153 : /* Complain about R, a DECL that is accessed outside its lifetime. */
8154 :
8155 : static void
8156 45 : outside_lifetime_error (location_t loc, tree r)
8157 : {
8158 45 : auto_diagnostic_group d;
8159 45 : if (DECL_NAME (r) == heap_deleted_identifier)
8160 : {
8161 : /* Provide a more accurate message for deleted variables. */
8162 14 : error_at (loc, "use of allocated storage after deallocation "
8163 : "in a constant expression");
8164 14 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8165 : }
8166 : else
8167 : {
8168 31 : error_at (loc, "accessing %qE outside its lifetime", r);
8169 31 : inform (DECL_SOURCE_LOCATION (r), "declared here");
8170 : }
8171 45 : }
8172 :
8173 : /* Complain about R, a VAR_DECL, not being usable in a constant expression.
8174 : FUNDEF_P is true if we're checking a constexpr function body.
8175 : Shared between potential_constant_expression and
8176 : cxx_eval_constant_expression. */
8177 :
8178 : static void
8179 354 : non_const_var_error (location_t loc, tree r, bool fundef_p)
8180 : {
8181 354 : auto_diagnostic_group d;
8182 354 : tree type = TREE_TYPE (r);
8183 354 : if (DECL_NAME (r) == heap_uninit_identifier
8184 354 : || DECL_NAME (r) == heap_identifier
8185 351 : || DECL_NAME (r) == heap_vec_uninit_identifier
8186 705 : || DECL_NAME (r) == heap_vec_identifier)
8187 : {
8188 3 : if (constexpr_error (loc, fundef_p, "the content of uninitialized "
8189 : "storage is not usable in a constant expression"))
8190 3 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8191 : return;
8192 : }
8193 351 : if (DECL_NAME (r) == heap_deleted_identifier)
8194 : {
8195 0 : if (constexpr_error (loc, fundef_p, "use of allocated storage after "
8196 : "deallocation in a constant expression"))
8197 0 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
8198 : return;
8199 : }
8200 351 : if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
8201 : "a constant expression", r))
8202 : return;
8203 : /* Avoid error cascade. */
8204 344 : if (DECL_INITIAL (r) == error_mark_node)
8205 : return;
8206 330 : if (DECL_DECLARED_CONSTEXPR_P (r))
8207 3 : inform (DECL_SOURCE_LOCATION (r),
8208 : "%qD used in its own initializer", r);
8209 327 : else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
8210 : {
8211 225 : if (!CP_TYPE_CONST_P (type))
8212 196 : inform (DECL_SOURCE_LOCATION (r),
8213 : "%q#D is not const", r);
8214 29 : else if (CP_TYPE_VOLATILE_P (type))
8215 0 : inform (DECL_SOURCE_LOCATION (r),
8216 : "%q#D is volatile", r);
8217 29 : else if (!DECL_INITIAL (r)
8218 9 : || !TREE_CONSTANT (DECL_INITIAL (r))
8219 37 : || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
8220 29 : inform (DECL_SOURCE_LOCATION (r),
8221 : "%qD was not initialized with a constant "
8222 : "expression", r);
8223 : else
8224 0 : gcc_unreachable ();
8225 : }
8226 102 : else if (TYPE_REF_P (type))
8227 9 : inform (DECL_SOURCE_LOCATION (r),
8228 : "%qD was not initialized with a constant "
8229 : "expression", r);
8230 : else
8231 : {
8232 93 : if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
8233 93 : inform (DECL_SOURCE_LOCATION (r),
8234 : "%qD was not declared %<constexpr%>", r);
8235 : else
8236 0 : inform (DECL_SOURCE_LOCATION (r),
8237 : "%qD does not have integral or enumeration type",
8238 : r);
8239 : }
8240 354 : }
8241 :
8242 : /* Subroutine of cxx_eval_constant_expression.
8243 : Like cxx_eval_unary_expression, except for trinary expressions. */
8244 :
8245 : static tree
8246 43640 : cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
8247 : value_cat lval,
8248 : bool *non_constant_p, bool *overflow_p,
8249 : tree *jump_target)
8250 : {
8251 43640 : int i;
8252 43640 : tree args[3];
8253 43640 : tree val;
8254 :
8255 168053 : for (i = 0; i < 3; i++)
8256 : {
8257 126582 : args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
8258 : lval,
8259 : non_constant_p, overflow_p,
8260 : jump_target);
8261 126582 : if (*jump_target)
8262 : return NULL_TREE;
8263 126582 : VERIFY_CONSTANT (args[i]);
8264 : }
8265 :
8266 41471 : val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
8267 : args[0], args[1], args[2]);
8268 41471 : if (val == NULL_TREE)
8269 : return t;
8270 41471 : VERIFY_CONSTANT (val);
8271 : return val;
8272 : }
8273 :
8274 : /* True if T was declared in a function declared to be constexpr, and
8275 : therefore potentially constant in C++14. */
8276 :
8277 : bool
8278 89642652 : var_in_constexpr_fn (tree t)
8279 : {
8280 89642652 : tree ctx = DECL_CONTEXT (t);
8281 89642652 : return (ctx && TREE_CODE (ctx) == FUNCTION_DECL
8282 170744484 : && DECL_DECLARED_CONSTEXPR_P (ctx));
8283 : }
8284 :
8285 : /* True if a function might be constexpr: either a function that was
8286 : declared constexpr, or a C++17 lambda op(). */
8287 :
8288 : bool
8289 736898679 : maybe_constexpr_fn (tree t)
8290 : {
8291 736898679 : return (DECL_DECLARED_CONSTEXPR_P (t)
8292 225844181 : || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t))
8293 954129459 : || (flag_implicit_constexpr
8294 96 : && DECL_DECLARED_INLINE_P (STRIP_TEMPLATE (t))));
8295 : }
8296 :
8297 : /* True if T was declared in a function that might be constexpr: either a
8298 : function that was declared constexpr, or a C++17 lambda op(). */
8299 :
8300 : bool
8301 66844144 : var_in_maybe_constexpr_fn (tree t)
8302 : {
8303 133687641 : return (DECL_FUNCTION_SCOPE_P (t)
8304 122161151 : && maybe_constexpr_fn (DECL_CONTEXT (t)));
8305 : }
8306 :
8307 : /* We're assigning INIT to TARGET. In do_build_copy_constructor and
8308 : build_over_call we implement trivial copy of a class with tail padding using
8309 : assignment of character arrays, which is valid in normal code, but not in
8310 : constexpr evaluation. We don't need to worry about clobbering tail padding
8311 : in constexpr evaluation, so strip the type punning. */
8312 :
8313 : static void
8314 103531991 : maybe_simplify_trivial_copy (tree &target, tree &init)
8315 : {
8316 103531991 : if (TREE_CODE (target) == MEM_REF
8317 36160 : && TREE_CODE (init) == MEM_REF
8318 35992 : && TREE_TYPE (target) == TREE_TYPE (init)
8319 35992 : && TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
8320 103567983 : && TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
8321 : {
8322 35992 : target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
8323 35992 : init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
8324 : }
8325 103531991 : }
8326 :
8327 : /* Returns true if REF, which is a COMPONENT_REF, has any fields
8328 : of constant type. This does not check for 'mutable', so the
8329 : caller is expected to be mindful of that. */
8330 :
8331 : static bool
8332 419 : cref_has_const_field (tree ref)
8333 : {
8334 488 : while (TREE_CODE (ref) == COMPONENT_REF)
8335 : {
8336 479 : if (CP_TYPE_CONST_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
8337 : return true;
8338 69 : ref = TREE_OPERAND (ref, 0);
8339 : }
8340 : return false;
8341 : }
8342 :
8343 : /* Return true if we are modifying something that is const during constant
8344 : expression evaluation. CODE is the code of the statement, OBJ is the
8345 : object in question, MUTABLE_P is true if one of the subobjects were
8346 : declared mutable. */
8347 :
8348 : static bool
8349 107275982 : modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
8350 : {
8351 : /* If this is initialization, there's no problem. */
8352 107275982 : if (code == INIT_EXPR)
8353 : return false;
8354 :
8355 : /* [basic.type.qualifier] "A const object is an object of type
8356 : const T or a non-mutable subobject of a const object." */
8357 30009029 : if (mutable_p)
8358 : return false;
8359 :
8360 30008287 : if (TREE_READONLY (obj))
8361 : return true;
8362 :
8363 29953590 : if (CP_TYPE_CONST_P (TREE_TYPE (obj)))
8364 : {
8365 : /* Although a COMPONENT_REF may have a const type, we should
8366 : only consider it modifying a const object when any of the
8367 : field components is const. This can happen when using
8368 : constructs such as const_cast<const T &>(m), making something
8369 : const even though it wasn't declared const. */
8370 33749 : if (TREE_CODE (obj) == COMPONENT_REF)
8371 419 : return cref_has_const_field (obj);
8372 : else
8373 : return true;
8374 : }
8375 :
8376 : return false;
8377 : }
8378 :
8379 : /* Evaluate an INIT_EXPR or MODIFY_EXPR or MODOP_EXPR. MODOP_EXPR means
8380 : we are evaluating __builtin_start_lifetime (init is in the second
8381 : operand rather than third, like for INIT_EXPR and MODIFY_EXPR). */
8382 :
8383 : static tree
8384 103531991 : cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
8385 : value_cat lval,
8386 : bool *non_constant_p, bool *overflow_p,
8387 : tree *jump_target)
8388 : {
8389 103531991 : constexpr_ctx new_ctx = *ctx;
8390 :
8391 103531991 : tree init = TREE_OPERAND (t, 1);
8392 :
8393 : /* First we figure out where we're storing to. */
8394 103531991 : tree target = TREE_OPERAND (t, 0);
8395 :
8396 103531991 : maybe_simplify_trivial_copy (target, init);
8397 :
8398 103531991 : tree type = TREE_TYPE (target);
8399 103531991 : bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) != INIT_EXPR;
8400 72679587 : if (preeval && !TREE_CLOBBER_P (init) && TREE_CODE (t) != MODOP_EXPR)
8401 : {
8402 : /* Ignore var = .DEFERRED_INIT (); for now, until PR121965 is fixed. */
8403 71612621 : if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
8404 41740733 : && TREE_CODE (init) == CALL_EXPR
8405 6802994 : && CALL_EXPR_FN (init) == NULL_TREE
8406 71612629 : && CALL_EXPR_IFN (init) == IFN_DEFERRED_INIT)
8407 8 : return void_node;
8408 :
8409 : /* Evaluate the value to be stored without knowing what object it will be
8410 : stored in, so that any side-effects happen first. */
8411 71612613 : if (!SCALAR_TYPE_P (type))
8412 205685 : new_ctx.ctor = new_ctx.object = NULL_TREE;
8413 71612613 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8414 : non_constant_p, overflow_p,
8415 : jump_target);
8416 71612609 : if (*jump_target)
8417 : return NULL_TREE;
8418 71612341 : if (*non_constant_p)
8419 : return t;
8420 : }
8421 :
8422 94357462 : bool evaluated = false;
8423 94357462 : if (lval == vc_glvalue)
8424 : {
8425 : /* If we want to return a reference to the target, we need to evaluate it
8426 : as a whole; otherwise, only evaluate the innermost piece to avoid
8427 : building up unnecessary *_REFs. */
8428 0 : target = cxx_eval_constant_expression (ctx, target, lval,
8429 : non_constant_p, overflow_p,
8430 : jump_target);
8431 0 : evaluated = true;
8432 0 : if (*jump_target)
8433 : return NULL_TREE;
8434 0 : if (*non_constant_p)
8435 : return t;
8436 : }
8437 :
8438 : /* Find the underlying variable. */
8439 94357462 : releasing_vec refs;
8440 94357462 : tree object = NULL_TREE;
8441 : /* If we're modifying a const object, save it. */
8442 94357462 : tree const_object_being_modified = NULL_TREE;
8443 94357462 : bool mutable_p = false;
8444 : /* If we see a union, we can't ignore clobbers. */
8445 94357462 : int seen_union = 0;
8446 319463841 : for (tree probe = target; object == NULL_TREE; )
8447 : {
8448 225106834 : switch (TREE_CODE (probe))
8449 : {
8450 36392236 : case BIT_FIELD_REF:
8451 36392236 : case COMPONENT_REF:
8452 36392236 : case ARRAY_REF:
8453 36392236 : {
8454 36392236 : tree ob = TREE_OPERAND (probe, 0);
8455 36392236 : tree elt = TREE_OPERAND (probe, 1);
8456 36392236 : if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt))
8457 : mutable_p = true;
8458 36392236 : if (TREE_CODE (probe) == ARRAY_REF)
8459 : {
8460 5894819 : elt = eval_and_check_array_index (ctx, probe, false,
8461 : non_constant_p, overflow_p,
8462 : jump_target);
8463 5894819 : if (*jump_target)
8464 69 : return NULL_TREE;
8465 5894819 : if (*non_constant_p)
8466 : return t;
8467 : }
8468 : /* We don't check modifying_const_object_p for ARRAY_REFs. Given
8469 : "int a[10]", an ARRAY_REF "a[2]" can be "const int", even though
8470 : the array isn't const. Instead, check "a" in the next iteration;
8471 : that will detect modifying "const int a[10]". */
8472 30497417 : else if (evaluated
8473 12918975 : && modifying_const_object_p (TREE_CODE (t), probe,
8474 : mutable_p)
8475 30498031 : && const_object_being_modified == NULL_TREE)
8476 : const_object_being_modified = probe;
8477 :
8478 : /* Track named member accesses for unions to validate modifications
8479 : that change active member. */
8480 36392167 : if (!evaluated && TREE_CODE (probe) == COMPONENT_REF)
8481 17578442 : vec_safe_push (refs, probe);
8482 : else
8483 18813725 : vec_safe_push (refs, NULL_TREE);
8484 :
8485 36392167 : vec_safe_push (refs, elt);
8486 36392167 : vec_safe_push (refs, TREE_TYPE (probe));
8487 36392167 : probe = ob;
8488 36392167 : if (TREE_CODE (TREE_TYPE (ob)) == UNION_TYPE)
8489 585736 : ++seen_union;
8490 : }
8491 36392167 : break;
8492 :
8493 30 : case REALPART_EXPR:
8494 30 : gcc_assert (refs->is_empty ());
8495 30 : vec_safe_push (refs, NULL_TREE);
8496 30 : vec_safe_push (refs, probe);
8497 30 : vec_safe_push (refs, TREE_TYPE (probe));
8498 30 : probe = TREE_OPERAND (probe, 0);
8499 30 : break;
8500 :
8501 31 : case IMAGPART_EXPR:
8502 31 : gcc_assert (refs->is_empty ());
8503 31 : vec_safe_push (refs, NULL_TREE);
8504 31 : vec_safe_push (refs, probe);
8505 31 : vec_safe_push (refs, TREE_TYPE (probe));
8506 31 : probe = TREE_OPERAND (probe, 0);
8507 31 : break;
8508 :
8509 188714537 : default:
8510 188714537 : if (evaluated)
8511 : object = probe;
8512 : else
8513 : {
8514 94357530 : tree pvar = tree_strip_any_location_wrapper (probe);
8515 94357530 : if (VAR_P (pvar) && DECL_ANON_UNION_VAR_P (pvar))
8516 : {
8517 : /* Stores to DECL_ANON_UNION_VAR_P var are allowed to change
8518 : active union member. */
8519 101 : probe = DECL_VALUE_EXPR (pvar);
8520 101 : break;
8521 : }
8522 94357429 : probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue,
8523 : non_constant_p, overflow_p,
8524 : jump_target);
8525 94357429 : evaluated = true;
8526 94357429 : if (*jump_target)
8527 : return NULL_TREE;
8528 94357429 : if (*non_constant_p)
8529 : return t;
8530 : }
8531 : break;
8532 : }
8533 : }
8534 :
8535 94357007 : if (modifying_const_object_p (TREE_CODE (t), object, mutable_p)
8536 94357007 : && const_object_being_modified == NULL_TREE)
8537 94357007 : const_object_being_modified = object;
8538 :
8539 94357007 : if (DECL_P (object)
8540 94355121 : && TREE_CLOBBER_P (init)
8541 95446532 : && DECL_NAME (object) == heap_deleted_identifier)
8542 : /* Ignore clobbers of deleted allocations for now; we'll get a better error
8543 : message later when operator delete is called. */
8544 15 : return void_node;
8545 :
8546 : /* And then find/build up our initializer for the path to the subobject
8547 : we're initializing. */
8548 94356992 : tree *valp;
8549 94356992 : if (DECL_P (object))
8550 94355106 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8551 : else
8552 : valp = NULL;
8553 94356992 : if (!valp)
8554 : {
8555 : /* A constant-expression cannot modify objects from outside the
8556 : constant-expression. */
8557 11466 : if (!ctx->quiet)
8558 : {
8559 31 : auto_diagnostic_group d;
8560 31 : if (DECL_P (object) && DECL_NAME (object) == heap_deleted_identifier)
8561 : {
8562 0 : error ("modification of allocated storage after deallocation "
8563 : "is not a constant expression");
8564 0 : inform (DECL_SOURCE_LOCATION (object), "allocated here");
8565 : }
8566 31 : else if (DECL_P (object) && ctx->global->is_outside_lifetime (object))
8567 : {
8568 14 : if (TREE_CLOBBER_P (init))
8569 6 : error ("destroying %qE outside its lifetime", object);
8570 : else
8571 8 : error ("modification of %qE outside its lifetime "
8572 : "is not a constant expression", object);
8573 14 : inform (DECL_SOURCE_LOCATION (object), "declared here");
8574 : }
8575 : else
8576 : {
8577 17 : if (TREE_CLOBBER_P (init))
8578 6 : error ("destroying %qE from outside current evaluation "
8579 : "is not a constant expression", object);
8580 : else
8581 11 : error ("modification of %qE from outside current evaluation "
8582 : "is not a constant expression", object);
8583 : }
8584 31 : }
8585 11466 : *non_constant_p = true;
8586 11466 : return t;
8587 : }
8588 :
8589 : /* Handle explicit end-of-lifetime. */
8590 94345526 : if (TREE_CLOBBER_P (init))
8591 : {
8592 1089459 : if (CLOBBER_KIND (init) >= CLOBBER_OBJECT_END
8593 1089459 : && refs->is_empty ())
8594 : {
8595 303811 : ctx->global->destroy_value (object, (CLOBBER_KIND (init)
8596 : > CLOBBER_OBJECT_END));
8597 303811 : return void_node;
8598 : }
8599 :
8600 771512 : if (!seen_union && !*valp
8601 796046 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
8602 10363 : return void_node;
8603 :
8604 : /* Ending the lifetime of a const object is OK. */
8605 : const_object_being_modified = NULL_TREE;
8606 : }
8607 :
8608 94031352 : type = TREE_TYPE (object);
8609 94031352 : bool no_zero_init = true;
8610 94031352 : bool zero_padding_bits = false;
8611 :
8612 188062704 : auto_vec<tree *> ctors;
8613 188062704 : releasing_vec indexes;
8614 188062704 : auto_vec<int> index_pos_hints;
8615 94031352 : bool activated_union_member_p = false;
8616 94031352 : bool empty_base = false;
8617 130101076 : while (!refs->is_empty ())
8618 : {
8619 36361449 : if (*valp == NULL_TREE)
8620 : {
8621 2943817 : *valp = build_constructor (type, NULL);
8622 2943817 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8623 2943817 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8624 : }
8625 33417632 : else if (STRIP_ANY_LOCATION_WRAPPER (*valp),
8626 33417632 : TREE_CODE (*valp) == STRING_CST)
8627 : {
8628 : /* An array was initialized with a string constant, and now
8629 : we're writing into one of its elements. Explode the
8630 : single initialization into a set of element
8631 : initializations. */
8632 11432 : gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
8633 :
8634 11432 : tree string = *valp;
8635 11432 : tree elt_type = TREE_TYPE (type);
8636 11432 : unsigned chars_per_elt = (TYPE_PRECISION (elt_type)
8637 11432 : / TYPE_PRECISION (char_type_node));
8638 11432 : unsigned num_elts = TREE_STRING_LENGTH (string) / chars_per_elt;
8639 11432 : tree ary_ctor = build_constructor (type, NULL);
8640 :
8641 11432 : vec_safe_reserve (CONSTRUCTOR_ELTS (ary_ctor), num_elts);
8642 34450 : for (unsigned ix = 0; ix != num_elts; ix++)
8643 : {
8644 11586 : constructor_elt elt =
8645 : {
8646 11586 : build_int_cst (size_type_node, ix),
8647 11586 : extract_string_elt (string, chars_per_elt, ix)
8648 11586 : };
8649 11586 : CONSTRUCTOR_ELTS (ary_ctor)->quick_push (elt);
8650 : }
8651 :
8652 11432 : *valp = ary_ctor;
8653 : }
8654 :
8655 36361449 : enum tree_code code = TREE_CODE (type);
8656 36361449 : tree reftype = refs->pop();
8657 36361449 : tree index = refs->pop();
8658 36361449 : bool is_access_expr = refs->pop() != NULL_TREE;
8659 :
8660 36361449 : if (code == COMPLEX_TYPE)
8661 : {
8662 61 : if (TREE_CODE (*valp) == COMPLEX_CST)
8663 51 : *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp),
8664 51 : TREE_IMAGPART (*valp));
8665 10 : else if (TREE_CODE (*valp) == CONSTRUCTOR
8666 2 : && CONSTRUCTOR_NELTS (*valp) == 0
8667 12 : && CONSTRUCTOR_NO_CLEARING (*valp))
8668 : {
8669 2 : tree r = build_constructor (reftype, NULL);
8670 2 : CONSTRUCTOR_NO_CLEARING (r) = 1;
8671 2 : *valp = build2 (COMPLEX_EXPR, type, r, r);
8672 : }
8673 61 : gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR);
8674 61 : ctors.safe_push (valp);
8675 61 : vec_safe_push (indexes, index);
8676 61 : valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR);
8677 61 : gcc_checking_assert (refs->is_empty ());
8678 : type = reftype;
8679 287033 : break;
8680 : }
8681 :
8682 : /* If the value of object is already zero-initialized, any new ctors for
8683 : subobjects will also be zero-initialized. Similarly with zeroing of
8684 : padding bits. */
8685 36361388 : no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
8686 36361388 : zero_padding_bits = CONSTRUCTOR_ZERO_PADDING_BITS (*valp);
8687 :
8688 36361388 : if (code == RECORD_TYPE && is_empty_field (index))
8689 : /* Don't build a sub-CONSTRUCTOR for an empty base or field, as they
8690 : have no data and might have an offset lower than previously declared
8691 : fields, which confuses the middle-end. The code below will notice
8692 : that we don't have a CONSTRUCTOR for our inner target and just
8693 : return init. */
8694 : {
8695 : empty_base = true;
8696 : break;
8697 : }
8698 :
8699 : /* If a union is zero-initialized, its first non-static named data member
8700 : is zero-initialized (and therefore active). */
8701 36074416 : if (code == UNION_TYPE
8702 36074416 : && !no_zero_init
8703 36074416 : && CONSTRUCTOR_NELTS (*valp) == 0)
8704 4079 : if (tree first = next_aggregate_field (TYPE_FIELDS (type)))
8705 4079 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (*valp), first, NULL_TREE);
8706 :
8707 : /* Check for implicit change of active member for a union. */
8708 :
8709 : /* LWG3436, CWG2675, c++/121068: The array object model is confused. For
8710 : now allow initializing an array element to activate the array. */
8711 36126765 : auto only_array_refs = [](const releasing_vec &refs)
8712 : {
8713 52354 : for (unsigned i = 1; i < refs->length(); i += 3)
8714 35 : if (TREE_CODE ((*refs)[i]) != INTEGER_CST)
8715 : return false;
8716 : return true;
8717 : };
8718 :
8719 36074416 : if (code == UNION_TYPE
8720 584222 : && (CONSTRUCTOR_NELTS (*valp) == 0
8721 381748 : || CONSTRUCTOR_ELT (*valp, 0)->index != index)
8722 : /* An INIT_EXPR of the last member in an access chain is always OK,
8723 : but still check implicit change of members earlier on; see
8724 : cpp2a/constexpr-union6.C. */
8725 36289367 : && !(TREE_CODE (t) == INIT_EXPR && only_array_refs (refs)))
8726 : {
8727 162632 : bool has_active_member = CONSTRUCTOR_NELTS (*valp) != 0;
8728 162632 : tree inner = strip_array_types (reftype);
8729 :
8730 162632 : if (has_active_member && cxx_dialect < cxx20)
8731 : {
8732 58 : if (!ctx->quiet)
8733 19 : error_at (cp_expr_loc_or_input_loc (t),
8734 : "change of the active member of a union "
8735 : "from %qD to %qD is not a constant expression "
8736 : "before C++20",
8737 19 : CONSTRUCTOR_ELT (*valp, 0)->index,
8738 : index);
8739 58 : *non_constant_p = true;
8740 : }
8741 162574 : else if ((!is_access_expr
8742 47066 : || (TREE_CLOBBER_P (init)
8743 0 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8744 47066 : || (TREE_CODE (t) != INIT_EXPR
8745 47054 : && CLASS_TYPE_P (inner)
8746 479 : && !type_has_non_deleted_trivial_default_ctor (inner)))
8747 162659 : && TREE_CODE (t) != MODOP_EXPR)
8748 : {
8749 : /* Diagnose changing active union member after initialization
8750 : without a valid member access expression, as described in
8751 : [class.union.general] p5. */
8752 115517 : if (!ctx->quiet)
8753 : {
8754 33 : auto_diagnostic_group d;
8755 33 : if (has_active_member)
8756 24 : error_at (cp_expr_loc_or_input_loc (t),
8757 : "accessing %qD member instead of initialized "
8758 : "%qD member in constant expression",
8759 24 : index, CONSTRUCTOR_ELT (*valp, 0)->index);
8760 : else
8761 9 : error_at (cp_expr_loc_or_input_loc (t),
8762 : "accessing uninitialized member %qD",
8763 : index);
8764 33 : if (is_access_expr)
8765 3 : inform (DECL_SOURCE_LOCATION (index),
8766 : "%qD does not implicitly begin its lifetime "
8767 : "because %qT does not have a non-deleted "
8768 : "trivial default constructor, use "
8769 : "%<std::construct_at%> instead",
8770 : index, inner);
8771 : else
8772 30 : inform (DECL_SOURCE_LOCATION (index),
8773 : "initializing %qD requires a member access "
8774 : "expression as the left operand of the assignment",
8775 : index);
8776 33 : }
8777 115517 : *non_constant_p = true;
8778 : }
8779 47057 : else if (has_active_member && CONSTRUCTOR_NO_CLEARING (*valp))
8780 : {
8781 : /* Diagnose changing the active union member while the union
8782 : is in the process of being initialized. */
8783 18 : if (!ctx->quiet)
8784 6 : error_at (cp_expr_loc_or_input_loc (t),
8785 : "change of the active member of a union "
8786 : "from %qD to %qD during initialization",
8787 6 : CONSTRUCTOR_ELT (*valp, 0)->index,
8788 : index);
8789 18 : *non_constant_p = true;
8790 : }
8791 : no_zero_init = true;
8792 : }
8793 :
8794 : /* Ending the lifetime of the active union member means the union no
8795 : longer has an active member. */
8796 584222 : if (code == UNION_TYPE && refs->is_empty ()
8797 100427 : && TREE_CLOBBER_P (init)
8798 36082470 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8799 : {
8800 1978 : vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0);
8801 4692 : return void_node;
8802 : }
8803 :
8804 36072438 : ctors.safe_push (valp);
8805 36072438 : vec_safe_push (indexes, index);
8806 :
8807 : /* Avoid adding an _elt for a clobber when the whole CONSTRUCTOR is
8808 : uninitialized. */
8809 34160574 : int pos = (!seen_union && TREE_CLOBBER_P (init)
8810 1775203 : && CONSTRUCTOR_NO_CLEARING (*valp)
8811 37653687 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END) ? -2 : -1;
8812 36072438 : constructor_elt *cep
8813 36072438 : = get_or_insert_ctor_field (*valp, index, pos);
8814 36072438 : if (cep == nullptr)
8815 2714 : return void_node;
8816 36069724 : index_pos_hints.safe_push (cep - CONSTRUCTOR_ELTS (*valp)->begin());
8817 :
8818 36069724 : if (code == UNION_TYPE)
8819 : {
8820 582244 : activated_union_member_p = true;
8821 582244 : --seen_union;
8822 : }
8823 :
8824 36069724 : valp = &cep->value;
8825 36069724 : type = reftype;
8826 : }
8827 :
8828 : /* Change an "as-base" clobber to the real type;
8829 : we don't need to worry about padding in constexpr. */
8830 94026660 : tree itype = initialized_type (init);
8831 94026660 : if (IS_FAKE_BASE_TYPE (itype))
8832 5058 : itype = TYPE_CONTEXT (itype);
8833 :
8834 : /* For initialization of an empty base, the original target will be
8835 : *(base*)this, evaluation of which resolves to the object
8836 : argument, which has the derived type rather than the base type. */
8837 187766348 : if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p
8838 93739688 : (itype, type)))
8839 : {
8840 19002 : gcc_assert (is_empty_class (TREE_TYPE (target)));
8841 : empty_base = true;
8842 : }
8843 :
8844 : /* For __builtin_start_lifetime, if it is already within lifetime,
8845 : don't do anything. */
8846 94026660 : if (TREE_CODE (t) == MODOP_EXPR && *valp != NULL_TREE && *valp != void_node)
8847 : return void_node;
8848 :
8849 : /* Detect modifying a constant object in constexpr evaluation.
8850 : We have found a const object that is being modified. Figure out
8851 : if we need to issue an error. Consider
8852 :
8853 : struct A {
8854 : int n;
8855 : constexpr A() : n(1) { n = 2; } // #1
8856 : };
8857 : struct B {
8858 : const A a;
8859 : constexpr B() { a.n = 3; } // #2
8860 : };
8861 : constexpr B b{};
8862 :
8863 : #1 is OK, since we're modifying an object under construction, but
8864 : #2 is wrong, since "a" is const and has been fully constructed.
8865 : To track it, we use the TREE_READONLY bit in the object's CONSTRUCTOR
8866 : which means that the object is read-only. For the example above, the
8867 : *ctors stack at the point of #2 will look like:
8868 :
8869 : ctors[0] = {.a={.n=2}} TREE_READONLY = 0
8870 : ctors[1] = {.n=2} TREE_READONLY = 1
8871 :
8872 : and we're modifying "b.a", so we search the stack and see if the
8873 : constructor for "b.a" has already run. */
8874 94026628 : if (const_object_being_modified)
8875 : {
8876 86908 : bool fail = false;
8877 86908 : tree const_objtype
8878 86908 : = strip_array_types (TREE_TYPE (const_object_being_modified));
8879 86908 : if (!CLASS_TYPE_P (const_objtype))
8880 : fail = true;
8881 : else
8882 : {
8883 : /* [class.ctor]p5 "A constructor can be invoked for a const,
8884 : volatile, or const volatile object. const and volatile
8885 : semantics are not applied on an object under construction.
8886 : They come into effect when the constructor for the most
8887 : derived object ends." */
8888 260923 : for (tree *elt : ctors)
8889 87317 : if (same_type_ignoring_top_level_qualifiers_p
8890 87317 : (TREE_TYPE (const_object_being_modified), TREE_TYPE (*elt)))
8891 : {
8892 86803 : fail = TREE_READONLY (*elt);
8893 86803 : break;
8894 : }
8895 : }
8896 86803 : if (fail)
8897 : {
8898 200 : if (!ctx->quiet)
8899 65 : modifying_const_object_error (t, const_object_being_modified);
8900 200 : *non_constant_p = true;
8901 200 : return t;
8902 : }
8903 : }
8904 :
8905 94026428 : if (!preeval)
8906 : {
8907 : /* We're handling an INIT_EXPR of class type, so the value of the
8908 : initializer can depend on the object it's initializing. */
8909 :
8910 : /* Create a new CONSTRUCTOR in case evaluation of the initializer
8911 : wants to modify it. */
8912 30830635 : if (*valp == NULL_TREE)
8913 : {
8914 29729822 : *valp = build_constructor (type, NULL);
8915 29729822 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8916 29729822 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8917 : }
8918 30830635 : new_ctx.ctor = empty_base ? NULL_TREE : *valp;
8919 30830635 : new_ctx.object = target;
8920 : /* Avoid temporary materialization when initializing from a TARGET_EXPR.
8921 : We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because
8922 : expansion of those trees uses ctx instead. */
8923 30830635 : if (TREE_CODE (init) == TARGET_EXPR)
8924 3292049 : if (tree tinit = TARGET_EXPR_INITIAL (init))
8925 3292049 : init = tinit;
8926 30830635 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8927 : non_constant_p, overflow_p,
8928 : jump_target);
8929 30830635 : if (*jump_target)
8930 : return NULL_TREE;
8931 : /* The hash table might have moved since the get earlier, and the
8932 : initializer might have mutated the underlying CONSTRUCTORs, so we must
8933 : recompute VALP. */
8934 30830441 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8935 35308312 : for (unsigned i = 0; i < vec_safe_length (indexes); i++)
8936 : {
8937 4477871 : ctors[i] = valp;
8938 4477871 : constructor_elt *cep
8939 4477871 : = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]);
8940 4477871 : valp = &cep->value;
8941 : }
8942 : }
8943 :
8944 94026234 : if (*non_constant_p)
8945 : return t;
8946 :
8947 : /* Don't share a CONSTRUCTOR that might be changed later. */
8948 92165652 : init = unshare_constructor (init);
8949 :
8950 92165652 : gcc_checking_assert (!*valp
8951 : || *valp == void_node
8952 : || (same_type_ignoring_top_level_qualifiers_p
8953 : (TREE_TYPE (*valp), type)));
8954 92165652 : if (empty_base)
8955 : {
8956 : /* Just evaluate the initializer and return, since there's no actual data
8957 : to store, and we didn't build a CONSTRUCTOR. */
8958 294504 : if (!*valp)
8959 : {
8960 : /* But do make sure we have something in *valp. */
8961 0 : *valp = build_constructor (type, nullptr);
8962 0 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8963 0 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8964 : }
8965 : }
8966 91871148 : else if (TREE_CLOBBER_P (init))
8967 : {
8968 770593 : if (AGGREGATE_TYPE_P (type))
8969 : {
8970 542611 : if (*valp && TREE_CODE (*valp) == CONSTRUCTOR)
8971 542562 : CONSTRUCTOR_ELTS (*valp) = nullptr;
8972 : else
8973 49 : *valp = build_constructor (type, nullptr);
8974 542611 : TREE_CONSTANT (*valp) = true;
8975 542611 : TREE_SIDE_EFFECTS (*valp) = false;
8976 542611 : CONSTRUCTOR_NO_CLEARING (*valp) = true;
8977 542611 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8978 : }
8979 : else
8980 227982 : *valp = void_node;
8981 : }
8982 91100555 : else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
8983 28963933 : && TREE_CODE (init) == CONSTRUCTOR)
8984 : {
8985 : /* An outer ctx->ctor might be pointing to *valp, so replace
8986 : its contents. */
8987 4756417 : CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
8988 4756417 : TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
8989 4756417 : TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
8990 14269251 : CONSTRUCTOR_NO_CLEARING (*valp)
8991 4756417 : = CONSTRUCTOR_NO_CLEARING (init);
8992 14269251 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp)
8993 4756417 : = CONSTRUCTOR_ZERO_PADDING_BITS (init);
8994 : }
8995 : else
8996 86344138 : *valp = init;
8997 :
8998 : /* After initialization, 'const' semantics apply to the value of the
8999 : object. Make a note of this fact by marking the CONSTRUCTOR
9000 : TREE_READONLY. */
9001 92165652 : if (TREE_CODE (t) == INIT_EXPR
9002 69665032 : && !empty_base
9003 69370528 : && TREE_CODE (*valp) == CONSTRUCTOR
9004 96749137 : && TYPE_READONLY (type))
9005 : {
9006 35990 : tree target_type = TREE_TYPE (target);
9007 35990 : if (IS_FAKE_BASE_TYPE (target_type))
9008 0 : target_type = TYPE_CONTEXT (target_type);
9009 35990 : if (INDIRECT_REF_P (target)
9010 51144 : && (is_this_parameter
9011 15154 : (tree_strip_nop_conversions (TREE_OPERAND (target, 0)))))
9012 : /* We've just initialized '*this' (perhaps via the target
9013 : constructor of a delegating constructor). Leave it up to the
9014 : caller that set 'this' to set TREE_READONLY appropriately. */
9015 23 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
9016 : (target_type, type) || empty_base);
9017 : else
9018 35967 : TREE_READONLY (*valp) = true;
9019 : }
9020 :
9021 : /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing
9022 : CONSTRUCTORs, if any. */
9023 92165652 : bool c = TREE_CONSTANT (init);
9024 92165652 : bool s = TREE_SIDE_EFFECTS (init);
9025 92165652 : if (!indexes->is_empty ())
9026 : {
9027 20447805 : tree last = indexes->last ();
9028 20447805 : if (TREE_CODE (last) == REALPART_EXPR
9029 20447805 : || TREE_CODE (last) == IMAGPART_EXPR)
9030 : {
9031 : /* And canonicalize COMPLEX_EXPR into COMPLEX_CST if
9032 : possible. */
9033 61 : tree *cexpr = ctors.last ();
9034 61 : if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr),
9035 61 : TREE_OPERAND (*cexpr, 0),
9036 61 : TREE_OPERAND (*cexpr, 1)))
9037 53 : *cexpr = c;
9038 : else
9039 : {
9040 16 : TREE_CONSTANT (*cexpr)
9041 8 : = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0))
9042 8 : & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1)));
9043 16 : TREE_SIDE_EFFECTS (*cexpr)
9044 16 : = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0))
9045 8 : | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1)));
9046 : }
9047 61 : c = TREE_CONSTANT (*cexpr);
9048 61 : s = TREE_SIDE_EFFECTS (*cexpr);
9049 : }
9050 : }
9051 92165652 : if (!c || s || activated_union_member_p)
9052 63898525 : for (tree *elt : ctors)
9053 : {
9054 12545834 : if (TREE_CODE (*elt) != CONSTRUCTOR)
9055 0 : continue;
9056 12545834 : if (!c)
9057 10648433 : TREE_CONSTANT (*elt) = false;
9058 12545834 : if (s)
9059 0 : TREE_SIDE_EFFECTS (*elt) = true;
9060 : /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of
9061 : this union. */
9062 12545834 : if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE)
9063 465865 : CONSTRUCTOR_NO_CLEARING (*elt) = false;
9064 : }
9065 :
9066 92165652 : if (lval)
9067 : return target;
9068 : else
9069 588792 : return init;
9070 94357462 : }
9071 :
9072 : /* Evaluate a ++ or -- expression. */
9073 :
9074 : static tree
9075 8717186 : cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
9076 : value_cat lval,
9077 : bool *non_constant_p, bool *overflow_p,
9078 : tree *jump_target)
9079 : {
9080 8717186 : enum tree_code code = TREE_CODE (t);
9081 8717186 : tree type = TREE_TYPE (t);
9082 8717186 : tree op = TREE_OPERAND (t, 0);
9083 8717186 : tree offset = TREE_OPERAND (t, 1);
9084 8717186 : gcc_assert (TREE_CONSTANT (offset));
9085 :
9086 : /* OFFSET is constant, but perhaps not constant enough. We need to
9087 : e.g. bash FLOAT_EXPRs to REAL_CSTs. */
9088 8717186 : offset = fold_simple (offset);
9089 :
9090 : /* The operand as an lvalue. */
9091 8717186 : op = cxx_eval_constant_expression (ctx, op, vc_glvalue,
9092 : non_constant_p, overflow_p,
9093 : jump_target);
9094 8717186 : if (*jump_target)
9095 : return NULL_TREE;
9096 :
9097 : /* The operand as an rvalue. */
9098 8717186 : tree val
9099 8717186 : = cxx_eval_constant_expression (ctx, op, vc_prvalue,
9100 : non_constant_p, overflow_p,
9101 : jump_target);
9102 8717186 : if (*jump_target)
9103 : return NULL_TREE;
9104 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
9105 : a local array in a constexpr function. */
9106 8717186 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val));
9107 3525475 : if (!ptr)
9108 3525475 : VERIFY_CONSTANT (val);
9109 :
9110 : /* The modified value. */
9111 8657826 : bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
9112 8657826 : tree mod;
9113 8657826 : if (INDIRECT_TYPE_P (type))
9114 : {
9115 : /* The middle end requires pointers to use POINTER_PLUS_EXPR. */
9116 5191711 : offset = convert_to_ptrofftype (offset);
9117 5191711 : if (!inc)
9118 80832 : offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
9119 5191711 : mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
9120 : }
9121 3466115 : else if (c_promoting_integer_type_p (type)
9122 39611 : && !TYPE_UNSIGNED (type)
9123 3466325 : && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
9124 : {
9125 210 : offset = fold_convert (integer_type_node, offset);
9126 210 : mod = fold_convert (integer_type_node, val);
9127 241 : tree t = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, integer_type_node,
9128 : mod, offset);
9129 210 : mod = fold_convert (type, t);
9130 210 : if (TREE_OVERFLOW_P (mod) && !TREE_OVERFLOW_P (t))
9131 9 : TREE_OVERFLOW (mod) = false;
9132 : }
9133 : else
9134 3908138 : mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
9135 8657826 : if (!ptr)
9136 3466115 : VERIFY_CONSTANT (mod);
9137 :
9138 : /* Storing the modified value. */
9139 14502608 : tree store = build2_loc (cp_expr_loc_or_loc (t, input_location),
9140 : MODIFY_EXPR, type, op, mod);
9141 8657826 : mod = cxx_eval_constant_expression (ctx, store, lval,
9142 : non_constant_p, overflow_p,
9143 : jump_target);
9144 8657826 : ggc_free (store);
9145 8657826 : if (*jump_target)
9146 : return NULL_TREE;
9147 8657826 : if (*non_constant_p)
9148 : return t;
9149 :
9150 : /* And the value of the expression. */
9151 8583724 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
9152 : /* Prefix ops are lvalues, but the caller might want an rvalue;
9153 : lval has already been taken into account in the store above. */
9154 : return mod;
9155 : else
9156 : /* Postfix ops are rvalues. */
9157 420967 : return val;
9158 : }
9159 :
9160 : /* Subroutine of cxx_eval_statement_list. Determine whether the statement
9161 : STMT matches *jump_target. If we're looking for a case label and we see
9162 : the default label, note it in ctx->css_state. */
9163 :
9164 : static bool
9165 504206 : label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
9166 : {
9167 504206 : switch (TREE_CODE (*jump_target))
9168 : {
9169 145 : case LABEL_DECL:
9170 145 : if (TREE_CODE (stmt) == LABEL_EXPR
9171 145 : && LABEL_EXPR_LABEL (stmt) == *jump_target)
9172 52 : return true;
9173 : break;
9174 :
9175 502144 : case INTEGER_CST:
9176 502144 : if (TREE_CODE (stmt) == CASE_LABEL_EXPR)
9177 : {
9178 502117 : gcc_assert (ctx->css_state != NULL);
9179 502117 : if (!CASE_LOW (stmt))
9180 : {
9181 : /* default: should appear just once in a SWITCH_EXPR
9182 : body (excluding nested SWITCH_EXPR). */
9183 76278 : gcc_assert (*ctx->css_state != css_default_seen);
9184 : /* When evaluating SWITCH_EXPR body for the second time,
9185 : return true for the default: label. */
9186 76278 : if (*ctx->css_state == css_default_processing)
9187 : return true;
9188 39015 : *ctx->css_state = css_default_seen;
9189 : }
9190 425839 : else if (CASE_HIGH (stmt))
9191 : {
9192 20 : if (tree_int_cst_le (CASE_LOW (stmt), *jump_target)
9193 31 : && tree_int_cst_le (*jump_target, CASE_HIGH (stmt)))
9194 : return true;
9195 : }
9196 425819 : else if (tree_int_cst_equal (*jump_target, CASE_LOW (stmt)))
9197 : return true;
9198 : }
9199 : break;
9200 :
9201 : case BREAK_STMT:
9202 : case CONTINUE_STMT:
9203 : /* These two are handled directly in cxx_eval_loop_expr by testing
9204 : breaks (jump_target) or continues (jump_target). */
9205 : break;
9206 :
9207 : case VAR_DECL:
9208 : /* Uncaught exception. This is handled by TRY_BLOCK evaluation
9209 : and other places by testing throws (jump_target). */
9210 : break;
9211 :
9212 0 : default:
9213 0 : gcc_unreachable ();
9214 : }
9215 : return false;
9216 : }
9217 :
9218 : /* Evaluate a STATEMENT_LIST for side-effects. Handles various jump
9219 : semantics, for switch, break, continue, and return. */
9220 :
9221 : static tree
9222 48474297 : cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
9223 : bool *non_constant_p, bool *overflow_p,
9224 : tree *jump_target)
9225 : {
9226 : /* In a statement-expression we want to return the last value.
9227 : For empty statement expression return void_node. */
9228 48474297 : tree r = void_node;
9229 127283594 : for (tree_stmt_iterator i = tsi_start (t); !tsi_end_p (i); ++i)
9230 : {
9231 104657130 : tree stmt = *i;
9232 :
9233 : /* We've found a continue, so skip everything until we reach
9234 : the label its jumping to. */
9235 104657130 : if (continues (jump_target))
9236 : {
9237 2062 : if (label_matches (ctx, jump_target, stmt))
9238 : /* Found it. */
9239 52 : *jump_target = NULL_TREE;
9240 : else
9241 2010 : continue;
9242 : }
9243 104655120 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
9244 11293105 : continue;
9245 :
9246 93362015 : value_cat lval = vc_discard;
9247 : /* The result of a statement-expression is not wrapped in EXPR_STMT. */
9248 131399872 : if (tsi_one_before_end_p (i)
9249 38039095 : && !VOID_TYPE_P (TREE_TYPE (stmt)))
9250 : lval = vc_prvalue;
9251 :
9252 93362015 : r = cxx_eval_constant_expression (ctx, stmt, lval,
9253 : non_constant_p, overflow_p,
9254 : jump_target);
9255 93362011 : if (*non_constant_p)
9256 : break;
9257 83344269 : if (returns (jump_target)
9258 67603680 : || breaks (jump_target)
9259 78809297 : || throws (jump_target))
9260 : break;
9261 : }
9262 48474293 : return r;
9263 : }
9264 :
9265 : /* Evaluate a LOOP_EXPR for side-effects. Handles break and return
9266 : semantics; continue semantics are covered by cxx_eval_statement_list. */
9267 :
9268 : static tree
9269 6662927 : cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
9270 : bool *non_constant_p, bool *overflow_p,
9271 : tree *jump_target)
9272 : {
9273 6662927 : tree body, cond = NULL_TREE, expr = NULL_TREE;
9274 6662927 : tree cond_prep = NULL_TREE, cond_cleanup = NULL_TREE;
9275 6662927 : unsigned cond_cleanup_depth = 0;
9276 6662927 : int count = 0;
9277 6662927 : switch (TREE_CODE (t))
9278 : {
9279 3403 : case LOOP_EXPR:
9280 3403 : body = LOOP_EXPR_BODY (t);
9281 3403 : break;
9282 5362684 : case DO_STMT:
9283 5362684 : body = DO_BODY (t);
9284 5362684 : cond = DO_COND (t);
9285 5362684 : break;
9286 365919 : case WHILE_STMT:
9287 365919 : body = WHILE_BODY (t);
9288 365919 : cond = WHILE_COND (t);
9289 365919 : cond_prep = WHILE_COND_PREP (t);
9290 365919 : cond_cleanup = WHILE_COND_CLEANUP (t);
9291 365919 : count = -1;
9292 365919 : break;
9293 930921 : case FOR_STMT:
9294 930921 : if (FOR_INIT_STMT (t))
9295 0 : cxx_eval_constant_expression (ctx, FOR_INIT_STMT (t), vc_discard,
9296 : non_constant_p, overflow_p, jump_target);
9297 930921 : if (*non_constant_p)
9298 : return NULL_TREE;
9299 930921 : body = FOR_BODY (t);
9300 930921 : cond = FOR_COND (t);
9301 930921 : expr = FOR_EXPR (t);
9302 930921 : cond_prep = FOR_COND_PREP (t);
9303 930921 : cond_cleanup = FOR_COND_CLEANUP (t);
9304 930921 : count = -1;
9305 930921 : break;
9306 0 : default:
9307 0 : gcc_unreachable ();
9308 : }
9309 6662927 : if (cond_prep)
9310 12 : gcc_assert (TREE_CODE (cond_prep) == BIND_EXPR);
9311 31409789 : auto cleanup_cond = [&] {
9312 : /* Clean up the condition variable after each iteration. */
9313 24746862 : if (cond_cleanup_depth && !*non_constant_p)
9314 : {
9315 105 : auto_vec<tree, 4> cleanups (cond_cleanup_depth);
9316 105 : tree s = BIND_EXPR_BODY (cond_prep);
9317 105 : unsigned i;
9318 210 : for (i = cond_cleanup_depth; i; --i)
9319 : {
9320 105 : tree_stmt_iterator iter = tsi_last (s);
9321 105 : s = tsi_stmt (iter);
9322 105 : cleanups.quick_push (CLEANUP_EXPR (s));
9323 105 : s = CLEANUP_BODY (s);
9324 : }
9325 105 : tree c;
9326 420 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, c)
9327 105 : cxx_eval_constant_expression (ctx, c, vc_discard, non_constant_p,
9328 : overflow_p, jump_target);
9329 105 : }
9330 24746862 : if (cond_prep)
9331 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
9332 222 : decl; decl = DECL_CHAIN (decl))
9333 111 : destroy_value_checked (ctx, decl, non_constant_p);
9334 6662927 : };
9335 19416212 : do
9336 : {
9337 19416212 : if (count != -1)
9338 : {
9339 18119372 : if (body)
9340 18119372 : cxx_eval_constant_expression (ctx, body, vc_discard,
9341 : non_constant_p, overflow_p,
9342 : jump_target);
9343 18119372 : if (breaks (jump_target))
9344 : {
9345 35437 : *jump_target = NULL_TREE;
9346 35437 : break;
9347 : }
9348 :
9349 18083935 : if (TREE_CODE (t) != LOOP_EXPR && continues (jump_target))
9350 570 : *jump_target = NULL_TREE;
9351 :
9352 18083935 : if (expr)
9353 5464369 : cxx_eval_constant_expression (ctx, expr, vc_discard,
9354 : non_constant_p, overflow_p,
9355 : jump_target);
9356 18083935 : cleanup_cond ();
9357 : }
9358 :
9359 19380775 : if (cond_prep)
9360 : {
9361 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
9362 222 : decl; decl = DECL_CHAIN (decl))
9363 111 : ctx->global->clear_value (decl);
9364 111 : if (cond_cleanup)
9365 : {
9366 : /* If COND_CLEANUP is non-NULL, we need to evaluate DEPTH
9367 : nested STATEMENT_LISTs from inside of BIND_EXPR_BODY,
9368 : but defer the evaluation of CLEANUP_EXPRs of CLEANUP_STMT
9369 : at the end of those STATEMENT_LISTs. */
9370 111 : cond_cleanup_depth = 0;
9371 111 : tree s = BIND_EXPR_BODY (cond_prep);
9372 111 : for (unsigned depth = tree_to_uhwi (cond_cleanup);
9373 222 : depth; --depth)
9374 : {
9375 111 : for (tree_stmt_iterator i = tsi_start (s);
9376 321 : !tsi_end_p (i); ++i)
9377 : {
9378 321 : tree stmt = *i;
9379 321 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
9380 0 : continue;
9381 321 : if (tsi_one_before_end_p (i))
9382 : {
9383 : /* The last statement in the STATEMENT_LIST
9384 : has to be a CLEANUP_STMT (verified in
9385 : finish_loop_cond_prep). We want to
9386 : evaluate just its CLEANUP_BODY part but not
9387 : CLEANUP_EXPR part just yet. */
9388 105 : gcc_assert (TREE_CODE (stmt) == CLEANUP_STMT);
9389 : /* If the CLEANUP_STMT is not actually to be
9390 : evaluated, don't increment cond_cleanup_depth
9391 : so that we don't evaluate the CLEANUP_EXPR
9392 : for it later either. */
9393 105 : if (*jump_target)
9394 : {
9395 : depth = 1;
9396 : break;
9397 : }
9398 105 : ++cond_cleanup_depth;
9399 : /* If not in the innermost one, next iteration
9400 : will handle CLEANUP_BODY similarly. */
9401 105 : if (depth > 1)
9402 : {
9403 0 : s = CLEANUP_BODY (stmt);
9404 0 : break;
9405 : }
9406 : /* The innermost one can be evaluated normally. */
9407 105 : cxx_eval_constant_expression (ctx,
9408 105 : CLEANUP_BODY (stmt),
9409 : vc_discard,
9410 : non_constant_p,
9411 : overflow_p,
9412 : jump_target);
9413 105 : break;
9414 : }
9415 : /* And so should be evaluated statements which aren't
9416 : last in the STATEMENT_LIST. */
9417 216 : cxx_eval_constant_expression (ctx, stmt, vc_discard,
9418 : non_constant_p, overflow_p,
9419 : jump_target);
9420 216 : if (*non_constant_p
9421 210 : || returns (jump_target)
9422 210 : || breaks (jump_target)
9423 210 : || continues (jump_target)
9424 531 : || throws (jump_target))
9425 : {
9426 : depth = 1;
9427 : break;
9428 : }
9429 : }
9430 : }
9431 : }
9432 : else
9433 0 : cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (cond_prep),
9434 : vc_discard, non_constant_p,
9435 : overflow_p, jump_target);
9436 : }
9437 :
9438 19380775 : if (cond)
9439 : {
9440 19373257 : tree res
9441 19373257 : = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
9442 : non_constant_p, overflow_p,
9443 : jump_target);
9444 19373257 : if (res)
9445 : {
9446 19317856 : if (verify_constant (res, ctx->quiet, non_constant_p,
9447 : overflow_p))
9448 : break;
9449 19132202 : if (integer_zerop (res))
9450 : break;
9451 : }
9452 : else
9453 55401 : gcc_assert (*jump_target);
9454 : }
9455 :
9456 12810571 : if (++count >= constexpr_loop_limit)
9457 : {
9458 27 : if (!ctx->quiet)
9459 9 : error_at (cp_expr_loc_or_input_loc (t),
9460 : "%<constexpr%> loop iteration count exceeds limit of %d "
9461 : "(use %<-fconstexpr-loop-limit=%> to increase the limit)",
9462 : constexpr_loop_limit);
9463 27 : *non_constant_p = true;
9464 27 : break;
9465 : }
9466 : }
9467 38374612 : while (!returns (jump_target)
9468 12753524 : && !breaks (jump_target)
9469 12753524 : && !continues (jump_target)
9470 12753617 : && (!switches (jump_target) || count == 0)
9471 12753494 : && !throws (jump_target)
9472 25621243 : && !*non_constant_p);
9473 :
9474 6662927 : cleanup_cond ();
9475 :
9476 6662927 : return NULL_TREE;
9477 : }
9478 :
9479 : /* Evaluate a SWITCH_EXPR for side-effects. Handles switch and break jump
9480 : semantics. */
9481 :
9482 : static tree
9483 50118 : cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
9484 : bool *non_constant_p, bool *overflow_p,
9485 : tree *jump_target)
9486 : {
9487 50118 : tree cond
9488 50118 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
9489 50118 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
9490 : non_constant_p, overflow_p,
9491 : jump_target);
9492 50118 : if (*jump_target)
9493 : return NULL_TREE;
9494 50118 : VERIFY_CONSTANT (cond);
9495 49825 : if (TREE_CODE (cond) != INTEGER_CST)
9496 : {
9497 : /* If the condition doesn't reduce to an INTEGER_CST it isn't a usable
9498 : switch condition even if it's constant enough for other things
9499 : (c++/113545). */
9500 0 : gcc_checking_assert (ctx->quiet);
9501 0 : *non_constant_p = true;
9502 0 : return t;
9503 : }
9504 :
9505 49825 : *jump_target = cond;
9506 :
9507 49825 : tree body
9508 49825 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_BODY (t) : SWITCH_BODY (t);
9509 49825 : constexpr_ctx new_ctx = *ctx;
9510 49825 : constexpr_switch_state css = css_default_not_seen;
9511 49825 : new_ctx.css_state = &css;
9512 49825 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
9513 : non_constant_p, overflow_p, jump_target);
9514 87128 : if (switches (jump_target) && css == css_default_seen)
9515 : {
9516 : /* If the SWITCH_EXPR body has default: label, process it once again,
9517 : this time instructing label_matches to return true for default:
9518 : label on switches (jump_target). */
9519 37263 : css = css_default_processing;
9520 37263 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
9521 : non_constant_p, overflow_p, jump_target);
9522 : }
9523 49825 : if (breaks (jump_target) || switches (jump_target))
9524 21437 : *jump_target = NULL_TREE;
9525 : return NULL_TREE;
9526 : }
9527 :
9528 : /* Find the object of TYPE under initialization in CTX. */
9529 :
9530 : static tree
9531 16714 : lookup_placeholder (const constexpr_ctx *ctx, value_cat lval, tree type)
9532 : {
9533 16714 : if (!ctx)
9534 : return NULL_TREE;
9535 :
9536 : /* Prefer the outermost matching object, but don't cross
9537 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors. */
9538 16318 : if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
9539 574 : if (tree outer_ob = lookup_placeholder (ctx->parent, lval, type))
9540 : return outer_ob;
9541 :
9542 : /* We could use ctx->object unconditionally, but using ctx->ctor when we
9543 : can is a minor optimization. */
9544 16140 : if (!lval && ctx->ctor && same_type_p (TREE_TYPE (ctx->ctor), type))
9545 300 : return ctx->ctor;
9546 :
9547 15840 : if (!ctx->object)
9548 : return NULL_TREE;
9549 :
9550 : /* Since an object cannot have a field of its own type, we can search outward
9551 : from ctx->object to find the unique containing object of TYPE. */
9552 : tree ob = ctx->object;
9553 15816 : while (ob)
9554 : {
9555 15816 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type))
9556 : break;
9557 219 : if (handled_component_p (ob))
9558 217 : ob = TREE_OPERAND (ob, 0);
9559 : else
9560 : ob = NULL_TREE;
9561 : }
9562 :
9563 : /* Like in replace_placeholders_r. */
9564 15599 : return unshare_expr (ob);
9565 : }
9566 :
9567 : /* Complain about an attempt to evaluate inline assembly. If FUNDEF_P is
9568 : true, we're checking a constexpr function body. */
9569 :
9570 : static void
9571 35 : inline_asm_in_constexpr_error (location_t loc, bool fundef_p)
9572 : {
9573 35 : auto_diagnostic_group d;
9574 35 : if (constexpr_error (loc, fundef_p, "inline assembly is not a "
9575 : "constant expression"))
9576 35 : inform (loc, "only unevaluated inline assembly is allowed in a "
9577 : "%<constexpr%> function in C++20");
9578 35 : }
9579 :
9580 : /* We're getting the constant value of DECL in a manifestly constant-evaluated
9581 : context; maybe complain about that. */
9582 :
9583 : static void
9584 92564772 : maybe_warn_about_constant_value (location_t loc, tree decl)
9585 : {
9586 92564772 : static bool explained = false;
9587 92564772 : auto_diagnostic_group d;
9588 92564772 : if (cxx_dialect >= cxx17
9589 92395592 : && warn_interference_size
9590 92395592 : && !OPTION_SET_P (param_destruct_interfere_size)
9591 92395592 : && DECL_CONTEXT (decl) == std_node
9592 19054986 : && DECL_NAME (decl)
9593 19054980 : && id_equal (DECL_NAME (decl), "hardware_destructive_interference_size")
9594 16 : && (LOCATION_FILE (input_location) != main_input_filename
9595 10 : || module_exporting_p ())
9596 92564775 : && warning_at (loc, OPT_Winterference_size, "use of %qD", decl)
9597 92564781 : && !explained)
9598 : {
9599 6 : explained = true;
9600 6 : inform (loc, "its value can vary between compiler versions or "
9601 : "with different %<-mtune%> or %<-mcpu%> flags");
9602 6 : inform (loc, "if this use is part of a public ABI, change it to "
9603 : "instead use a constant variable you define");
9604 6 : inform (loc, "the default value for the current CPU tuning "
9605 : "is %d bytes", param_destruct_interfere_size);
9606 6 : inform (loc, "you can stabilize this value with %<--param "
9607 : "hardware_destructive_interference_size=%d%>, or disable "
9608 : "this warning with %<-Wno-interference-size%>",
9609 : param_destruct_interfere_size);
9610 : }
9611 92564772 : }
9612 :
9613 : /* For element type ELT_TYPE, return the appropriate type of the heap object
9614 : containing such element(s). COOKIE_SIZE is NULL or the size of cookie
9615 : in bytes. If COOKIE_SIZE is NULL, return array type
9616 : ELT_TYPE[FULL_SIZE / sizeof(ELT_TYPE)], otherwise return
9617 : struct { size_t[COOKIE_SIZE/sizeof(size_t)]; ELT_TYPE[N]; }
9618 : where N is computed such that the size of the struct fits into FULL_SIZE.
9619 : If ARG_SIZE is non-NULL, it is the first argument to the new operator.
9620 : It should be passed if ELT_TYPE is zero sized type in which case FULL_SIZE
9621 : will be also 0 and so it is not possible to determine the actual array
9622 : size. CTX, NON_CONSTANT_P and OVERFLOW_P are used during constant
9623 : expression evaluation of subexpressions of ARG_SIZE. */
9624 :
9625 : static tree
9626 119140 : build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type,
9627 : tree cookie_size, tree full_size, tree arg_size,
9628 : bool *non_constant_p, bool *overflow_p,
9629 : tree *jump_target)
9630 : {
9631 119140 : gcc_assert (cookie_size == NULL_TREE || tree_fits_uhwi_p (cookie_size));
9632 119140 : gcc_assert (tree_fits_uhwi_p (full_size));
9633 119140 : unsigned HOST_WIDE_INT csz = cookie_size ? tree_to_uhwi (cookie_size) : 0;
9634 119140 : if (arg_size)
9635 : {
9636 9 : STRIP_NOPS (arg_size);
9637 9 : if (cookie_size)
9638 : {
9639 0 : if (TREE_CODE (arg_size) != PLUS_EXPR)
9640 : arg_size = NULL_TREE;
9641 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 0)) == INTEGER_CST
9642 0 : && tree_int_cst_equal (cookie_size,
9643 0 : TREE_OPERAND (arg_size, 0)))
9644 : {
9645 0 : arg_size = TREE_OPERAND (arg_size, 1);
9646 0 : STRIP_NOPS (arg_size);
9647 : }
9648 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 1)) == INTEGER_CST
9649 0 : && tree_int_cst_equal (cookie_size,
9650 0 : TREE_OPERAND (arg_size, 1)))
9651 : {
9652 0 : arg_size = TREE_OPERAND (arg_size, 0);
9653 0 : STRIP_NOPS (arg_size);
9654 : }
9655 : else
9656 : arg_size = NULL_TREE;
9657 : }
9658 9 : if (arg_size && TREE_CODE (arg_size) == MULT_EXPR)
9659 : {
9660 9 : tree op0 = TREE_OPERAND (arg_size, 0);
9661 9 : tree op1 = TREE_OPERAND (arg_size, 1);
9662 9 : if (integer_zerop (op0))
9663 9 : arg_size
9664 9 : = cxx_eval_constant_expression (ctx, op1, vc_prvalue,
9665 : non_constant_p, overflow_p,
9666 : jump_target);
9667 0 : else if (integer_zerop (op1))
9668 0 : arg_size
9669 0 : = cxx_eval_constant_expression (ctx, op0, vc_prvalue,
9670 : non_constant_p, overflow_p,
9671 : jump_target);
9672 : else
9673 : arg_size = NULL_TREE;
9674 9 : if (*jump_target)
9675 : return NULL_TREE;
9676 : }
9677 : else
9678 : arg_size = NULL_TREE;
9679 : }
9680 :
9681 9 : unsigned HOST_WIDE_INT fsz = tree_to_uhwi (arg_size ? arg_size : full_size);
9682 119140 : if (!arg_size)
9683 : {
9684 119131 : unsigned HOST_WIDE_INT esz = int_size_in_bytes (elt_type);
9685 119131 : gcc_assert (fsz >= csz);
9686 119131 : fsz -= csz;
9687 119131 : if (esz)
9688 119131 : fsz /= esz;
9689 : }
9690 119140 : tree itype2 = build_index_type (size_int (fsz - 1));
9691 119140 : if (!cookie_size)
9692 119131 : return build_cplus_array_type (elt_type, itype2);
9693 9 : return build_new_constexpr_heap_type (elt_type, cookie_size, itype2);
9694 : }
9695 :
9696 : /* Handle the case when a cleanup of some expression throws. JMP_TARGET
9697 : indicates whether the cleanup threw or not, *JUMP_TARGET indicates whether
9698 : the expression which needed the cleanup threw. If both threw, diagnose
9699 : it and return NULL, otherwise return R. If only the cleanup threw, set
9700 : *JUMP_TARGET to the exception object from the cleanup. */
9701 :
9702 : static tree
9703 1763411 : merge_jump_target (location_t loc, const constexpr_ctx *ctx, tree r,
9704 : bool *non_constant_p, tree *jump_target, tree jmp_target)
9705 : {
9706 1763411 : if (!throws (&jmp_target))
9707 : return r;
9708 14 : if (throws (jump_target))
9709 : {
9710 : /* [except.throw]/9 - If the exception handling mechanism
9711 : handling an uncaught exception directly invokes a function
9712 : that exits via an exception, the function std::terminate is
9713 : invoked. */
9714 12 : if (!ctx->quiet)
9715 : {
9716 4 : auto_diagnostic_group d;
9717 4 : diagnose_std_terminate (loc, ctx, *jump_target);
9718 4 : inform (loc, "destructor exited with an exception");
9719 4 : }
9720 12 : *non_constant_p = true;
9721 12 : *jump_target = NULL_TREE;
9722 12 : return NULL_TREE;
9723 : }
9724 2 : *jump_target = jmp_target;
9725 2 : return r;
9726 : }
9727 :
9728 : /* Attempt to reduce the expression T to a constant value.
9729 : On failure, issue diagnostic and return error_mark_node. */
9730 : /* FIXME unify with c_fully_fold */
9731 : /* FIXME overflow_p is too global */
9732 :
9733 : tree
9734 3017915285 : cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
9735 : value_cat lval,
9736 : bool *non_constant_p, bool *overflow_p,
9737 : tree *jump_target)
9738 : {
9739 3017915285 : if (*jump_target)
9740 : {
9741 : /* If we are jumping, ignore all statements/expressions except those
9742 : that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies. */
9743 1622781 : switch (TREE_CODE (t))
9744 : {
9745 : case BIND_EXPR:
9746 : case STATEMENT_LIST:
9747 : case LOOP_EXPR:
9748 : case COND_EXPR:
9749 : case IF_STMT:
9750 : case DO_STMT:
9751 : case WHILE_STMT:
9752 : case FOR_STMT:
9753 : break;
9754 502144 : case LABEL_EXPR:
9755 502144 : case CASE_LABEL_EXPR:
9756 502144 : if (label_matches (ctx, jump_target, t))
9757 : /* Found it. */
9758 49785 : *jump_target = NULL_TREE;
9759 : return NULL_TREE;
9760 : default:
9761 : return NULL_TREE;
9762 : }
9763 : }
9764 3016538339 : if (error_operand_p (t))
9765 : {
9766 194 : *non_constant_p = true;
9767 194 : return t;
9768 : }
9769 :
9770 : /* Change the input location to the currently processed expression for
9771 : better error messages when a subexpression has no location. */
9772 3016538145 : location_t loc = cp_expr_loc_or_input_loc (t);
9773 6033070858 : iloc_sentinel sentinel (loc);
9774 :
9775 3016538145 : STRIP_ANY_LOCATION_WRAPPER (t);
9776 :
9777 3016538145 : if (CONSTANT_CLASS_P (t))
9778 : {
9779 461498251 : if (TREE_OVERFLOW (t))
9780 : {
9781 62 : if (!ctx->quiet)
9782 15 : permerror (input_location, "overflow in constant expression");
9783 62 : if (!flag_permissive || ctx->quiet)
9784 59 : *overflow_p = true;
9785 : }
9786 :
9787 461498251 : if (TREE_CODE (t) == INTEGER_CST
9788 439087869 : && TYPE_PTR_P (TREE_TYPE (t))
9789 : /* INTEGER_CST with pointer-to-method type is only used
9790 : for a virtual method in a pointer to member function.
9791 : Don't reject those. */
9792 2123290 : && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != METHOD_TYPE
9793 463621217 : && !integer_zerop (t))
9794 : {
9795 6 : if (!ctx->quiet)
9796 0 : error ("value %qE of type %qT is not a constant expression",
9797 0 : t, TREE_TYPE (t));
9798 6 : *non_constant_p = true;
9799 : }
9800 :
9801 : return t;
9802 : }
9803 :
9804 : /* Avoid excessively long constexpr evaluations. */
9805 2555039894 : if (++ctx->global->constexpr_ops_count >= constexpr_ops_limit)
9806 : {
9807 9 : if (!ctx->quiet)
9808 3 : error_at (loc,
9809 : "%<constexpr%> evaluation operation count exceeds limit of "
9810 : "%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
9811 : constexpr_ops_limit);
9812 9 : ctx->global->constexpr_ops_count = INTTYPE_MINIMUM (HOST_WIDE_INT);
9813 9 : *non_constant_p = true;
9814 9 : return t;
9815 : }
9816 :
9817 2555039885 : constexpr_ctx new_ctx;
9818 2555039885 : tree r = t;
9819 :
9820 2555039885 : tree_code tcode = TREE_CODE (t);
9821 2555039885 : switch (tcode)
9822 : {
9823 59460720 : case RESULT_DECL:
9824 59460720 : if (lval)
9825 : return t;
9826 : /* We ask for an rvalue for the RESULT_DECL when indirecting
9827 : through an invisible reference, or in named return value
9828 : optimization. */
9829 147136 : if (tree v = ctx->global->get_value (t))
9830 : return v;
9831 : else
9832 : {
9833 3 : if (!ctx->quiet)
9834 0 : error ("%qE is not a constant expression", t);
9835 3 : *non_constant_p = true;
9836 : }
9837 3 : break;
9838 :
9839 299246200 : case VAR_DECL:
9840 299246200 : if (DECL_HAS_VALUE_EXPR_P (t))
9841 : {
9842 9235502 : if (is_normal_capture_proxy (t)
9843 9235502 : && current_function_decl == DECL_CONTEXT (t))
9844 : {
9845 : /* Function parms aren't constexpr within the function
9846 : definition, so don't try to look at the closure. But if the
9847 : captured variable is constant, try to evaluate it directly. */
9848 629513 : r = DECL_CAPTURED_VARIABLE (t);
9849 : }
9850 : else
9851 8605989 : r = DECL_VALUE_EXPR (t);
9852 :
9853 9235502 : tree type = TREE_TYPE (t);
9854 9235502 : if (TYPE_REF_P (type) != TYPE_REF_P (TREE_TYPE (r)))
9855 : {
9856 : /* Adjust r to match the reference-ness of t. */
9857 258367 : if (TYPE_REF_P (type))
9858 254176 : r = build_address (r);
9859 : else
9860 4191 : r = convert_from_reference (r);
9861 : }
9862 9235502 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
9863 9235502 : overflow_p, jump_target);
9864 : }
9865 : /* fall through */
9866 300777514 : case CONST_DECL:
9867 : /* We used to not check lval for CONST_DECL, but darwin.cc uses
9868 : CONST_DECL for aggregate constants. */
9869 300777514 : if (lval)
9870 : return t;
9871 213771013 : else if (t == ctx->object)
9872 1025698 : return ctx->ctor;
9873 212745315 : if (VAR_P (t))
9874 : {
9875 201978499 : if (tree v = ctx->global->get_value (t))
9876 : {
9877 : r = v;
9878 : break;
9879 : }
9880 136712974 : if (ctx->global->is_outside_lifetime (t))
9881 : {
9882 137 : if (!ctx->quiet)
9883 39 : outside_lifetime_error (loc, t);
9884 137 : *non_constant_p = true;
9885 137 : break;
9886 : }
9887 : }
9888 147479653 : if (ctx->manifestly_const_eval == mce_true)
9889 92564772 : maybe_warn_about_constant_value (loc, t);
9890 147479653 : if (COMPLETE_TYPE_P (TREE_TYPE (t))
9891 147479653 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9892 : {
9893 : /* If the class is empty, we aren't actually loading anything. */
9894 253311 : r = build_constructor (TREE_TYPE (t), NULL);
9895 253311 : TREE_CONSTANT (r) = true;
9896 : }
9897 147226342 : else if (ctx->strict)
9898 146877256 : r = decl_really_constant_value (t, /*unshare_p=*/false);
9899 : else
9900 349086 : r = decl_constant_value (t, /*unshare_p=*/false);
9901 147476956 : if (TREE_CODE (r) == TARGET_EXPR
9902 147476956 : && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
9903 0 : r = TARGET_EXPR_INITIAL (r);
9904 147476956 : if (DECL_P (r)
9905 : /* P2280 allows references to unknown. */
9906 147764923 : && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
9907 : {
9908 34578779 : if (!ctx->quiet)
9909 183 : non_const_var_error (loc, r, /*fundef_p*/false);
9910 34578779 : *non_constant_p = true;
9911 : }
9912 : break;
9913 :
9914 : case DEBUG_BEGIN_STMT:
9915 : /* ??? It might be nice to retain this information somehow, so
9916 : as to be able to step into a constexpr function call. */
9917 : /* Fall through. */
9918 :
9919 : case FUNCTION_DECL:
9920 : case TEMPLATE_DECL:
9921 : case LABEL_DECL:
9922 : case LABEL_EXPR:
9923 : case CASE_LABEL_EXPR:
9924 : case PREDICT_EXPR:
9925 : case OMP_DECLARE_MAPPER:
9926 : case REFLECT_EXPR:
9927 : return t;
9928 :
9929 304907038 : case PARM_DECL:
9930 304907038 : if (lval && !TYPE_REF_P (TREE_TYPE (t)))
9931 : {
9932 : /* glvalue use. */
9933 21273391 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9934 219787 : if (tree v = ctx->global->get_value (t))
9935 2055779742 : r = v;
9936 : }
9937 283633647 : else if (tree v = ctx->global->get_value (t))
9938 : {
9939 165142711 : r = v;
9940 165142711 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9941 11305 : r = cxx_eval_constant_expression (ctx, r, vc_prvalue,
9942 : non_constant_p, overflow_p,
9943 : jump_target);
9944 165142711 : if (*jump_target)
9945 : return NULL_TREE;
9946 : }
9947 118490936 : else if (lval)
9948 : /* Defer in case this is only used for its type. */;
9949 118490936 : else if (ctx->global->is_outside_lifetime (t))
9950 : {
9951 18 : if (!ctx->quiet)
9952 6 : outside_lifetime_error (loc, t);
9953 18 : *non_constant_p = true;
9954 18 : break;
9955 : }
9956 118490918 : else if (COMPLETE_TYPE_P (TREE_TYPE (t))
9957 118490918 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9958 : {
9959 : /* If the class is empty, we aren't actually loading anything. */
9960 41725 : r = build_constructor (TREE_TYPE (t), NULL);
9961 41725 : TREE_CONSTANT (r) = true;
9962 : }
9963 118449193 : else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t)))
9964 : /* P2280 allows references to unknown... */;
9965 118168484 : else if (p2280_active_p (ctx) && is_this_parameter (t))
9966 : /* ...as well as the this pointer. */;
9967 : else
9968 : {
9969 117709753 : if (!ctx->quiet)
9970 199 : error ("%qE is not a constant expression", t);
9971 117709753 : *non_constant_p = true;
9972 : }
9973 : break;
9974 :
9975 206993461 : case CALL_EXPR:
9976 206993461 : case AGGR_INIT_EXPR:
9977 206993461 : r = cxx_eval_call_expression (ctx, t, lval,
9978 : non_constant_p, overflow_p, jump_target);
9979 206993461 : break;
9980 :
9981 21533066 : case DECL_EXPR:
9982 21533066 : {
9983 21533066 : r = DECL_EXPR_DECL (t);
9984 21533066 : if (TREE_CODE (r) == USING_DECL)
9985 : {
9986 9428 : r = void_node;
9987 9428 : break;
9988 : }
9989 :
9990 21523638 : if (VAR_P (r)
9991 21523638 : && (TREE_STATIC (r)
9992 21358526 : || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
9993 : /* Allow __FUNCTION__ etc. */
9994 165112 : && !DECL_ARTIFICIAL (r)
9995 21524535 : && !decl_constant_var_p (r))
9996 : {
9997 7 : if (!ctx->quiet)
9998 : {
9999 2 : if (CP_DECL_THREAD_LOCAL_P (r))
10000 1 : error_at (loc, "control passes through definition of %qD "
10001 : "with thread storage duration", r);
10002 : else
10003 1 : error_at (loc, "control passes through definition of %qD "
10004 : "with static storage duration", r);
10005 : }
10006 7 : *non_constant_p = true;
10007 7 : break;
10008 : }
10009 :
10010 : /* make_rtl_for_nonlocal_decl could have deferred emission of
10011 : a local static var, but if it appears in a statement expression
10012 : which is constant expression evaluated to e.g. just the address
10013 : of the variable, its DECL_EXPR will never be seen during
10014 : gimple lowering's record_vars_into as the statement expression
10015 : will not be in the IL at all. */
10016 21523631 : if (VAR_P (r)
10017 21523631 : && TREE_STATIC (r)
10018 165105 : && !DECL_REALLY_EXTERN (r)
10019 165083 : && DECL_FUNCTION_SCOPE_P (r)
10020 165083 : && !var_in_maybe_constexpr_fn (r)
10021 21523634 : && decl_constant_var_p (r))
10022 : {
10023 3 : varpool_node *node = varpool_node::get (r);
10024 3 : if (node == NULL || !node->definition)
10025 3 : rest_of_decl_compilation (r, 0, at_eof);
10026 : }
10027 :
10028 42802484 : if (AGGREGATE_TYPE_P (TREE_TYPE (r))
10029 40142112 : || VECTOR_TYPE_P (TREE_TYPE (r)))
10030 : {
10031 2908114 : new_ctx = *ctx;
10032 2908114 : new_ctx.object = r;
10033 2908114 : new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
10034 2908114 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
10035 2908114 : ctx->global->put_value (r, new_ctx.ctor);
10036 2908114 : ctx = &new_ctx;
10037 : }
10038 :
10039 21523631 : if (tree init = DECL_INITIAL (r))
10040 : {
10041 11243723 : init = cxx_eval_constant_expression (ctx, init, vc_prvalue,
10042 : non_constant_p, overflow_p,
10043 : jump_target);
10044 11243723 : if (*jump_target)
10045 : return NULL_TREE;
10046 : /* Don't share a CONSTRUCTOR that might be changed. */
10047 11243723 : init = unshare_constructor (init);
10048 : /* Remember that a constant object's constructor has already
10049 : run. */
10050 22487446 : if (CLASS_TYPE_P (TREE_TYPE (r))
10051 11793606 : && CP_TYPE_CONST_P (TREE_TYPE (r)))
10052 71517 : TREE_READONLY (init) = true;
10053 11243723 : ctx->global->put_value (r, init);
10054 : }
10055 10279908 : else if (ctx == &new_ctx)
10056 : /* We gave it a CONSTRUCTOR above. */;
10057 : else
10058 7998744 : ctx->global->put_value (r, NULL_TREE);
10059 : }
10060 : break;
10061 :
10062 27124909 : case TARGET_EXPR:
10063 27124909 : {
10064 27124909 : tree type = TREE_TYPE (t);
10065 :
10066 27124909 : if (!literal_type_p (type))
10067 : {
10068 6597 : if (!ctx->quiet)
10069 : {
10070 0 : auto_diagnostic_group d;
10071 0 : error ("temporary of non-literal type %qT in a "
10072 : "constant expression", type);
10073 0 : explain_non_literal_class (type);
10074 0 : }
10075 6597 : *non_constant_p = true;
10076 11824083 : break;
10077 : }
10078 27118312 : gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (t));
10079 : /* Avoid evaluating a TARGET_EXPR more than once. */
10080 27118312 : tree slot = TARGET_EXPR_SLOT (t);
10081 27118312 : if (tree v = ctx->global->get_value (slot))
10082 : {
10083 2136 : if (lval)
10084 10985825 : return slot;
10085 : r = v;
10086 : break;
10087 : }
10088 27116176 : if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
10089 : {
10090 : /* We're being expanded without an explicit target, so start
10091 : initializing a new object; expansion with an explicit target
10092 : strips the TARGET_EXPR before we get here. */
10093 20552092 : new_ctx = *ctx;
10094 : /* Link CTX to NEW_CTX so that lookup_placeholder can resolve
10095 : any PLACEHOLDER_EXPR within the initializer that refers to the
10096 : former object under construction. */
10097 20552092 : new_ctx.parent = ctx;
10098 20552092 : new_ctx.ctor = build_constructor (type, NULL);
10099 20552092 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
10100 20552092 : new_ctx.object = slot;
10101 20552092 : ctx->global->put_value (new_ctx.object, new_ctx.ctor);
10102 20552092 : ctx = &new_ctx;
10103 : }
10104 :
10105 : /* If the initializer is complex, evaluate it to initialize slot. */
10106 27116176 : bool is_complex = target_expr_needs_replace (t);
10107 27116176 : if (is_complex)
10108 : /* In case no initialization actually happens, clear out any
10109 : void_node from a previous evaluation. */
10110 483 : ctx->global->put_value (slot, NULL_TREE);
10111 :
10112 : /* Pass vc_prvalue because this indicates
10113 : initialization of a temporary. */
10114 27116176 : r = cxx_eval_constant_expression (ctx, TARGET_EXPR_INITIAL (t),
10115 : vc_prvalue, non_constant_p,
10116 : overflow_p, jump_target);
10117 27116176 : if (*non_constant_p)
10118 : break;
10119 15299776 : if (ctx->save_exprs)
10120 10140359 : ctx->save_exprs->safe_push (slot);
10121 15299776 : if (*jump_target)
10122 : {
10123 669 : if (!is_complex
10124 669 : && !(AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
10125 : /* If TARGET_EXPR_INITIAL throws exception and slot's value
10126 : has not been changed yet, CLEANUP_POINT_EXPR handling
10127 : could see there void_node from a previous evaluation
10128 : and complain. */
10129 6 : ctx->global->put_value (slot, NULL_TREE);
10130 : return NULL_TREE;
10131 : }
10132 15299107 : if (!is_complex)
10133 : {
10134 15298702 : r = unshare_constructor (r);
10135 : /* Adjust the type of the result to the type of the temporary. */
10136 15298702 : r = adjust_temp_type (type, r);
10137 15298702 : ctx->global->put_value (slot, r);
10138 : }
10139 15299107 : if (TARGET_EXPR_CLEANUP (t)
10140 15299107 : && (!CLEANUP_EH_ONLY (t) || cxx_dialect >= cxx26))
10141 : {
10142 1462256 : ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t));
10143 : /* Mark CLEANUP_EH_ONLY cleanups by pushing NULL_TREE after
10144 : them. */
10145 1462256 : if (CLEANUP_EH_ONLY (t))
10146 2156 : ctx->global->cleanups->safe_push (NULL_TREE);
10147 : }
10148 15299107 : if (lval)
10149 : return slot;
10150 4315001 : if (is_complex)
10151 0 : r = ctx->global->get_value (slot);
10152 : }
10153 4315001 : break;
10154 :
10155 103530518 : case INIT_EXPR:
10156 103530518 : case MODIFY_EXPR:
10157 103530518 : gcc_assert (jump_target == NULL || *jump_target == NULL_TREE);
10158 103530518 : r = cxx_eval_store_expression (ctx, t, lval,
10159 : non_constant_p, overflow_p, jump_target);
10160 103530518 : break;
10161 :
10162 0 : case SCOPE_REF:
10163 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
10164 : lval,
10165 : non_constant_p, overflow_p,
10166 : jump_target);
10167 0 : break;
10168 :
10169 64414115 : case RETURN_EXPR:
10170 64414115 : if (TREE_OPERAND (t, 0) != NULL_TREE)
10171 64068720 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10172 : lval,
10173 : non_constant_p, overflow_p,
10174 : jump_target);
10175 64414111 : if (!throws (jump_target))
10176 64413743 : *jump_target = t;
10177 : break;
10178 54031 : case BREAK_STMT:
10179 54031 : case CONTINUE_STMT:
10180 54031 : *jump_target = t;
10181 54031 : break;
10182 :
10183 966788 : case SAVE_EXPR:
10184 : /* Avoid evaluating a SAVE_EXPR more than once. */
10185 966788 : if (tree v = ctx->global->get_value (t))
10186 : r = v;
10187 : else
10188 : {
10189 944759 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10190 : vc_prvalue, non_constant_p,
10191 : overflow_p, jump_target);
10192 944759 : if (*non_constant_p || *jump_target)
10193 : break;
10194 12795 : ctx->global->put_value (t, r);
10195 12795 : if (ctx->save_exprs)
10196 9259 : ctx->save_exprs->safe_push (t);
10197 : }
10198 : break;
10199 :
10200 62878870 : case NON_LVALUE_EXPR:
10201 62878870 : case EXPR_STMT:
10202 62878870 : case EH_SPEC_BLOCK:
10203 62878870 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10204 : lval,
10205 : non_constant_p, overflow_p,
10206 : jump_target);
10207 62878870 : break;
10208 :
10209 9408 : case TRY_BLOCK:
10210 9408 : r = cxx_eval_constant_expression (ctx, TRY_STMTS (t), lval,
10211 : non_constant_p, overflow_p,
10212 : jump_target);
10213 9408 : if (!*non_constant_p && throws (jump_target))
10214 3787 : if (tree h = TRY_HANDLERS (t))
10215 : {
10216 3787 : tree type = strip_array_types (TREE_TYPE (*jump_target));
10217 3787 : if (TREE_CODE (h) == STATEMENT_LIST)
10218 : {
10219 938 : for (tree stmt : tsi_range (h))
10220 904 : if (TREE_CODE (stmt) == HANDLER
10221 904 : && handler_match_for_exception_type (stmt, type))
10222 : {
10223 : h = stmt;
10224 : break;
10225 : }
10226 462 : if (TREE_CODE (h) == STATEMENT_LIST)
10227 : h = NULL_TREE;
10228 : }
10229 3325 : else if (TREE_CODE (h) != HANDLER
10230 3325 : || !handler_match_for_exception_type (h, type))
10231 : h = NULL_TREE;
10232 : if (h)
10233 : {
10234 3753 : gcc_assert (VAR_P (*jump_target));
10235 3753 : ctx->global->caught_exceptions.safe_push (*jump_target);
10236 3753 : ctx->global->caught_exceptions.safe_push (HANDLER_TYPE (h));
10237 3753 : *jump_target = NULL_TREE;
10238 3753 : r = cxx_eval_constant_expression (ctx, HANDLER_BODY (h),
10239 : vc_discard, non_constant_p,
10240 : overflow_p, jump_target);
10241 : }
10242 : }
10243 : break;
10244 :
10245 91793498 : case CLEANUP_POINT_EXPR:
10246 91793498 : {
10247 91793498 : auto_vec<tree, 2> cleanups;
10248 91793498 : vec<tree> *prev_cleanups = ctx->global->cleanups;
10249 91793498 : ctx->global->cleanups = &cleanups;
10250 :
10251 91793498 : auto_vec<tree, 10> save_exprs;
10252 91793498 : constexpr_ctx new_ctx = *ctx;
10253 91793498 : new_ctx.save_exprs = &save_exprs;
10254 :
10255 91793498 : r = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 0),
10256 : lval,
10257 : non_constant_p, overflow_p,
10258 : jump_target);
10259 :
10260 91793496 : ctx->global->cleanups = prev_cleanups;
10261 91793496 : unsigned int i;
10262 91793496 : tree cleanup, jmp_target = NULL_TREE;
10263 91793496 : bool eh = throws (jump_target);
10264 : /* Evaluate the cleanups. */
10265 184946758 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
10266 1359766 : if (cleanup == NULL_TREE)
10267 : {
10268 : /* NULL_TREE cleanup is a marker that before it is
10269 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it
10270 : if the body didn't throw. */
10271 2133 : if (!eh)
10272 2131 : --i;
10273 : }
10274 : else
10275 1357633 : cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard,
10276 : non_constant_p, overflow_p,
10277 : &jmp_target);
10278 :
10279 : /* Forget SAVE_EXPRs and TARGET_EXPRs created by this
10280 : full-expression. */
10281 285530106 : for (tree save_expr : save_exprs)
10282 10149618 : destroy_value_checked (ctx, save_expr, non_constant_p);
10283 91793496 : if (throws (&jmp_target))
10284 0 : *jump_target = jmp_target;
10285 91793496 : }
10286 91793496 : break;
10287 :
10288 58908583 : case MUST_NOT_THROW_EXPR:
10289 58908583 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10290 : lval,
10291 : non_constant_p, overflow_p,
10292 : jump_target);
10293 58908581 : if (throws (jump_target))
10294 : {
10295 : /* [except.handle]/7 - If the search for a handler exits the
10296 : function body of a function with a non-throwing exception
10297 : specification, the function std::terminate is invoked. */
10298 54 : if (!ctx->quiet)
10299 : {
10300 18 : auto_diagnostic_group d;
10301 18 : diagnose_std_terminate (loc, ctx, *jump_target);
10302 18 : if (MUST_NOT_THROW_NOEXCEPT_P (t)
10303 14 : && ctx->call
10304 32 : && ctx->call->fundef)
10305 14 : inform (loc, "uncaught exception exited from %<noexcept%> "
10306 : "function %qD",
10307 : ctx->call->fundef->decl);
10308 4 : else if (MUST_NOT_THROW_THROW_P (t))
10309 2 : inform (loc, "destructor exited with an exception after "
10310 : "initializing the exception object");
10311 2 : else if (MUST_NOT_THROW_CATCH_P (t))
10312 2 : inform (loc, "constructor exited with another exception while "
10313 : "entering handler");
10314 18 : }
10315 54 : *non_constant_p = true;
10316 54 : *jump_target = NULL_TREE;
10317 54 : r = NULL_TREE;
10318 : }
10319 : break;
10320 :
10321 0 : case TRY_CATCH_EXPR:
10322 0 : if (TREE_OPERAND (t, 0) == NULL_TREE)
10323 : {
10324 0 : r = void_node;
10325 0 : break;
10326 : }
10327 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10328 : non_constant_p, overflow_p,
10329 : jump_target);
10330 0 : if (!*non_constant_p && throws (jump_target))
10331 : {
10332 0 : tree jmp_target = NULL_TREE;
10333 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
10334 : non_constant_p, overflow_p,
10335 : &jmp_target);
10336 0 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10337 : jmp_target);
10338 : }
10339 : break;
10340 :
10341 842 : case TRY_FINALLY_EXPR:
10342 842 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10343 : non_constant_p, overflow_p,
10344 : jump_target);
10345 842 : if (!*non_constant_p)
10346 : {
10347 827 : tree jmp_target = NULL_TREE;
10348 : /* Also evaluate the cleanup. */
10349 827 : if (TREE_CODE (TREE_OPERAND (t, 1)) == EH_ELSE_EXPR
10350 827 : && throws (jump_target))
10351 0 : cxx_eval_constant_expression (ctx,
10352 0 : TREE_OPERAND (TREE_OPERAND (t, 1),
10353 : 1), vc_discard,
10354 : non_constant_p, overflow_p,
10355 : &jmp_target);
10356 : else
10357 827 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
10358 : non_constant_p, overflow_p,
10359 : &jmp_target);
10360 827 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10361 : jmp_target);
10362 : }
10363 : break;
10364 :
10365 0 : case EH_ELSE_EXPR:
10366 : /* Evaluate any cleanup that applies to non-EH exits. */
10367 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_discard,
10368 : non_constant_p, overflow_p,
10369 : jump_target);
10370 :
10371 : /* The EH path is handled in TRY_FINALLY_EXPR handling above. */
10372 0 : break;
10373 :
10374 3944365 : case CLEANUP_STMT:
10375 3944365 : r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
10376 : non_constant_p, overflow_p,
10377 : jump_target);
10378 3944379 : if ((!CLEANUP_EH_ONLY (t) || throws (jump_target)) && !*non_constant_p)
10379 : {
10380 1762584 : iloc_sentinel ils (loc);
10381 1762584 : tree jmp_target = NULL_TREE;
10382 : /* Also evaluate the cleanup. */
10383 1762584 : cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), vc_discard,
10384 : non_constant_p, overflow_p,
10385 : &jmp_target);
10386 1762584 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
10387 : jmp_target);
10388 1762584 : }
10389 : break;
10390 :
10391 : /* These differ from cxx_eval_unary_expression in that this doesn't
10392 : check for a constant operand or result; an address can be
10393 : constant without its operand being, and vice versa. */
10394 103846674 : case MEM_REF:
10395 103846674 : case INDIRECT_REF:
10396 103846674 : r = cxx_eval_indirect_ref (ctx, t, lval,
10397 : non_constant_p, overflow_p,
10398 : jump_target);
10399 103846674 : break;
10400 :
10401 101356090 : case ADDR_EXPR:
10402 101356090 : {
10403 101356090 : tree oldop = TREE_OPERAND (t, 0);
10404 101356090 : tree op = cxx_eval_constant_expression (ctx, oldop, vc_glvalue,
10405 : non_constant_p, overflow_p,
10406 : jump_target);
10407 101356090 : if (*jump_target)
10408 : return NULL_TREE;
10409 : /* Don't VERIFY_CONSTANT here. */
10410 101356085 : if (*non_constant_p)
10411 : return t;
10412 81718208 : gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
10413 : /* This function does more aggressive folding than fold itself. */
10414 81718208 : r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
10415 81718208 : if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
10416 : {
10417 56642319 : ggc_free (r);
10418 56642319 : return t;
10419 : }
10420 : break;
10421 : }
10422 :
10423 856895 : case REALPART_EXPR:
10424 856895 : case IMAGPART_EXPR:
10425 856895 : if (lval)
10426 : {
10427 1386 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10428 : non_constant_p, overflow_p,
10429 : jump_target);
10430 1386 : if (*jump_target)
10431 : return NULL_TREE;
10432 1386 : if (r == error_mark_node)
10433 : ;
10434 1386 : else if (r == TREE_OPERAND (t, 0) || lval == vc_discard)
10435 : r = t;
10436 : else
10437 1276 : r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
10438 : break;
10439 : }
10440 : /* FALLTHRU */
10441 25813295 : case CONJ_EXPR:
10442 25813295 : case FIX_TRUNC_EXPR:
10443 25813295 : case FLOAT_EXPR:
10444 25813295 : case NEGATE_EXPR:
10445 25813295 : case ABS_EXPR:
10446 25813295 : case ABSU_EXPR:
10447 25813295 : case BIT_NOT_EXPR:
10448 25813295 : case TRUTH_NOT_EXPR:
10449 25813295 : case FIXED_CONVERT_EXPR:
10450 25813295 : case VEC_DUPLICATE_EXPR:
10451 25813295 : r = cxx_eval_unary_expression (ctx, t, lval,
10452 : non_constant_p, overflow_p,
10453 : jump_target);
10454 25813295 : break;
10455 :
10456 9401340 : case SIZEOF_EXPR:
10457 9401340 : r = fold_sizeof_expr (t);
10458 : /* In a template, fold_sizeof_expr may merely create a new SIZEOF_EXPR,
10459 : which could lead to an infinite recursion. */
10460 9401340 : if (TREE_CODE (r) != SIZEOF_EXPR)
10461 9401340 : r = cxx_eval_constant_expression (ctx, r, lval,
10462 : non_constant_p, overflow_p,
10463 : jump_target);
10464 : else
10465 : {
10466 0 : *non_constant_p = true;
10467 0 : gcc_assert (ctx->quiet);
10468 : }
10469 :
10470 : break;
10471 :
10472 13803720 : case COMPOUND_EXPR:
10473 13803720 : {
10474 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
10475 : COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
10476 : introduced by build_call_a. */
10477 13803720 : tree op0 = TREE_OPERAND (t, 0);
10478 13803720 : tree op1 = TREE_OPERAND (t, 1);
10479 13803720 : STRIP_NOPS (op1);
10480 5601701 : if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
10481 16440210 : || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
10482 6857331 : r = cxx_eval_constant_expression (ctx, op0,
10483 : lval, non_constant_p, overflow_p,
10484 : jump_target);
10485 : else
10486 : {
10487 : /* Check that the LHS is constant and then discard it. */
10488 6946389 : cxx_eval_constant_expression (ctx, op0, vc_discard,
10489 : non_constant_p, overflow_p,
10490 : jump_target);
10491 6946389 : if (*jump_target)
10492 : return NULL_TREE;
10493 6939178 : if (*non_constant_p)
10494 : return t;
10495 6660177 : op1 = TREE_OPERAND (t, 1);
10496 6660177 : r = cxx_eval_constant_expression (ctx, op1,
10497 : lval, non_constant_p, overflow_p,
10498 : jump_target);
10499 : }
10500 : }
10501 : break;
10502 :
10503 112345121 : case POINTER_PLUS_EXPR:
10504 112345121 : case POINTER_DIFF_EXPR:
10505 112345121 : case PLUS_EXPR:
10506 112345121 : case MINUS_EXPR:
10507 112345121 : case MULT_EXPR:
10508 112345121 : case TRUNC_DIV_EXPR:
10509 112345121 : case CEIL_DIV_EXPR:
10510 112345121 : case FLOOR_DIV_EXPR:
10511 112345121 : case ROUND_DIV_EXPR:
10512 112345121 : case TRUNC_MOD_EXPR:
10513 112345121 : case CEIL_MOD_EXPR:
10514 112345121 : case ROUND_MOD_EXPR:
10515 112345121 : case RDIV_EXPR:
10516 112345121 : case EXACT_DIV_EXPR:
10517 112345121 : case MIN_EXPR:
10518 112345121 : case MAX_EXPR:
10519 112345121 : case LSHIFT_EXPR:
10520 112345121 : case RSHIFT_EXPR:
10521 112345121 : case LROTATE_EXPR:
10522 112345121 : case RROTATE_EXPR:
10523 112345121 : case BIT_IOR_EXPR:
10524 112345121 : case BIT_XOR_EXPR:
10525 112345121 : case BIT_AND_EXPR:
10526 112345121 : case TRUTH_XOR_EXPR:
10527 112345121 : case LT_EXPR:
10528 112345121 : case LE_EXPR:
10529 112345121 : case GT_EXPR:
10530 112345121 : case GE_EXPR:
10531 112345121 : case EQ_EXPR:
10532 112345121 : case NE_EXPR:
10533 112345121 : case SPACESHIP_EXPR:
10534 112345121 : case UNORDERED_EXPR:
10535 112345121 : case ORDERED_EXPR:
10536 112345121 : case UNLT_EXPR:
10537 112345121 : case UNLE_EXPR:
10538 112345121 : case UNGT_EXPR:
10539 112345121 : case UNGE_EXPR:
10540 112345121 : case UNEQ_EXPR:
10541 112345121 : case LTGT_EXPR:
10542 112345121 : case RANGE_EXPR:
10543 112345121 : case COMPLEX_EXPR:
10544 112345121 : r = cxx_eval_binary_expression (ctx, t, lval,
10545 : non_constant_p, overflow_p,
10546 : jump_target);
10547 112345121 : break;
10548 :
10549 : /* fold can introduce non-IF versions of these; still treat them as
10550 : short-circuiting. */
10551 15427013 : case TRUTH_AND_EXPR:
10552 15427013 : case TRUTH_ANDIF_EXPR:
10553 15427013 : r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
10554 : boolean_true_node,
10555 : non_constant_p, overflow_p,
10556 : jump_target);
10557 15427013 : break;
10558 :
10559 3056949 : case TRUTH_OR_EXPR:
10560 3056949 : case TRUTH_ORIF_EXPR:
10561 3056949 : r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
10562 : boolean_false_node,
10563 : non_constant_p, overflow_p,
10564 : jump_target);
10565 3056949 : break;
10566 :
10567 15557274 : case ARRAY_REF:
10568 15557274 : r = cxx_eval_array_reference (ctx, t, lval,
10569 : non_constant_p, overflow_p,
10570 : jump_target);
10571 15557274 : break;
10572 :
10573 116103048 : case COMPONENT_REF:
10574 116103048 : if (is_overloaded_fn (t))
10575 : {
10576 : /* We can only get here in checking mode via
10577 : build_non_dependent_expr, because any expression that
10578 : calls or takes the address of the function will have
10579 : pulled a FUNCTION_DECL out of the COMPONENT_REF. */
10580 6 : gcc_checking_assert (ctx->quiet || errorcount);
10581 6 : *non_constant_p = true;
10582 6 : return t;
10583 : }
10584 116103042 : r = cxx_eval_component_reference (ctx, t, lval,
10585 : non_constant_p, overflow_p,
10586 : jump_target);
10587 116103042 : break;
10588 :
10589 40745 : case BIT_FIELD_REF:
10590 40745 : r = cxx_eval_bit_field_ref (ctx, t, lval,
10591 : non_constant_p, overflow_p,
10592 : jump_target);
10593 40745 : break;
10594 :
10595 39435171 : case COND_EXPR:
10596 39435171 : case IF_STMT:
10597 39435171 : if (*jump_target)
10598 : {
10599 151552 : tree orig_jump = *jump_target;
10600 151552 : tree arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 1))
10601 303104 : ? TREE_OPERAND (t, 1) : void_node);
10602 : /* When jumping to a label, the label might be either in the
10603 : then or else blocks, so process then block first in skipping
10604 : mode first, and if we are still in the skipping mode at its end,
10605 : process the else block too. */
10606 151552 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
10607 : overflow_p, jump_target);
10608 : /* It's possible that we found the label in the then block. But
10609 : it could have been followed by another jumping statement, e.g.
10610 : say we're looking for case 1:
10611 : if (cond)
10612 : {
10613 : // skipped statements
10614 : case 1:; // clears up *jump_target
10615 : return 1; // and sets it to a RETURN_EXPR
10616 : }
10617 : else { ... }
10618 : in which case we need not go looking to the else block.
10619 : (goto is not allowed in a constexpr function.) */
10620 151552 : if (*jump_target == orig_jump)
10621 : {
10622 151609 : arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 2))
10623 151609 : ? TREE_OPERAND (t, 2) : void_node);
10624 151514 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
10625 : overflow_p, jump_target);
10626 : }
10627 : break;
10628 : }
10629 39283619 : r = cxx_eval_conditional_expression (ctx, t, lval,
10630 : non_constant_p, overflow_p,
10631 : jump_target);
10632 39283619 : break;
10633 11755 : case VEC_COND_EXPR:
10634 11755 : r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
10635 : overflow_p, jump_target);
10636 11755 : break;
10637 :
10638 23323902 : case CONSTRUCTOR:
10639 23323902 : if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
10640 : {
10641 : /* Don't re-process a constant CONSTRUCTOR. */
10642 19936183 : verify_constructor_flags (t);
10643 19936183 : if (TREE_CONSTANT (t))
10644 : return t;
10645 : }
10646 3387719 : if (TREE_CLOBBER_P (t))
10647 : {
10648 : /* Assignment from a clobber is handled in cxx_eval_store_expression;
10649 : a clobber by itself isn't a constant-expression. */
10650 240 : gcc_assert (ctx->quiet);
10651 240 : *non_constant_p = true;
10652 240 : break;
10653 : }
10654 3387479 : r = cxx_eval_bare_aggregate (ctx, t, lval,
10655 : non_constant_p, overflow_p, jump_target);
10656 3387479 : break;
10657 :
10658 790 : case VEC_INIT_EXPR:
10659 : /* We can get this in a defaulted constructor for a class with a
10660 : non-static data member of array type. Either the initializer will
10661 : be NULL, meaning default-initialization, or it will be an lvalue
10662 : or xvalue of the same type, meaning direct-initialization from the
10663 : corresponding member. */
10664 790 : r = cxx_eval_vec_init (ctx, t, lval,
10665 : non_constant_p, overflow_p, jump_target);
10666 790 : break;
10667 :
10668 43640 : case VEC_PERM_EXPR:
10669 43640 : r = cxx_eval_trinary_expression (ctx, t, lval,
10670 : non_constant_p, overflow_p,
10671 : jump_target);
10672 43640 : break;
10673 :
10674 7 : case PAREN_EXPR:
10675 7 : gcc_assert (!REF_PARENTHESIZED_P (t));
10676 : /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
10677 : constant expressions since it's unaffected by -fassociative-math. */
10678 7 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10679 : non_constant_p, overflow_p,
10680 : jump_target);
10681 7 : break;
10682 :
10683 441298753 : case NOP_EXPR:
10684 441298753 : if (REINTERPRET_CAST_P (t))
10685 : {
10686 145 : if (!ctx->quiet)
10687 6 : error_at (loc,
10688 : "%<reinterpret_cast%> is not a constant expression");
10689 145 : *non_constant_p = true;
10690 145 : return t;
10691 : }
10692 : /* FALLTHROUGH. */
10693 552449496 : case CONVERT_EXPR:
10694 552449496 : case VIEW_CONVERT_EXPR:
10695 552449496 : case UNARY_PLUS_EXPR:
10696 552449496 : {
10697 552449496 : tree oldop = TREE_OPERAND (t, 0);
10698 :
10699 552449496 : tree op = cxx_eval_constant_expression (ctx, oldop,
10700 552449496 : VOID_TYPE_P (TREE_TYPE (t))
10701 : ? vc_discard
10702 : : tcode == VIEW_CONVERT_EXPR
10703 518691037 : ? lval : vc_prvalue,
10704 : non_constant_p, overflow_p,
10705 : jump_target);
10706 552446797 : if (*jump_target)
10707 : return NULL_TREE;
10708 552442781 : if (*non_constant_p)
10709 : return t;
10710 444752833 : tree type = TREE_TYPE (t);
10711 :
10712 444752833 : if (VOID_TYPE_P (type))
10713 32555273 : return void_node;
10714 :
10715 412197560 : if (TREE_CODE (t) == CONVERT_EXPR
10716 59863417 : && ARITHMETIC_TYPE_P (type)
10717 5076570 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10718 412221077 : && ctx->strict)
10719 : {
10720 23422 : if (!ctx->quiet)
10721 54 : error_at (loc,
10722 : "conversion from pointer type %qT to arithmetic type "
10723 54 : "%qT in a constant expression", TREE_TYPE (op), type);
10724 23422 : *non_constant_p = true;
10725 23422 : return t;
10726 : }
10727 :
10728 : /* [expr.const]: a conversion from type cv void* to a pointer-to-object
10729 : type cannot be part of a core constant expression as a resolution to
10730 : DR 1312. */
10731 153002839 : if (TYPE_PTROB_P (type)
10732 149586360 : && TYPE_PTR_P (TREE_TYPE (op))
10733 94673435 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
10734 : /* Inside a call to std::construct_at,
10735 : std::allocator<T>::{,de}allocate, or
10736 : std::source_location::current, we permit casting from void*
10737 : because that is compiler-generated code. */
10738 1947250 : && !is_std_construct_at (ctx->call)
10739 167644 : && !is_std_allocator_allocate_deallocate (ctx->call)
10740 412259698 : && !is_std_source_location_current (ctx->call))
10741 : {
10742 : /* Likewise, don't error when casting from void* when OP is
10743 : &heap uninit and similar. */
10744 85401 : tree sop = tree_strip_nop_conversions (op);
10745 85401 : tree decl = NULL_TREE;
10746 85401 : if (TREE_CODE (sop) == ADDR_EXPR)
10747 63221 : decl = TREE_OPERAND (sop, 0);
10748 63221 : if (decl
10749 63221 : && VAR_P (decl)
10750 61793 : && DECL_ARTIFICIAL (decl)
10751 124580 : && (DECL_NAME (decl) == heap_identifier
10752 39408 : || DECL_NAME (decl) == heap_uninit_identifier
10753 4561 : || DECL_NAME (decl) == heap_vec_identifier
10754 2620 : || DECL_NAME (decl) == heap_vec_uninit_identifier))
10755 : /* OK */;
10756 : /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
10757 : cv void" to a pointer-to-object type T unless P is a null
10758 : pointer value or points to an object whose type is similar to
10759 : T. */
10760 24453 : else if (cxx_dialect > cxx23)
10761 : {
10762 24288 : if (integer_zerop (sop))
10763 30 : return build_int_cst (type, 0);
10764 24258 : r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10765 : NULL, jump_target);
10766 24258 : if (*jump_target)
10767 : return NULL_TREE;
10768 24258 : if (r)
10769 : {
10770 24211 : r = build1 (ADDR_EXPR, type, r);
10771 24211 : break;
10772 : }
10773 47 : if (!ctx->quiet)
10774 : {
10775 5 : gcc_assert (TREE_CODE (sop) == ADDR_EXPR);
10776 5 : auto_diagnostic_group d;
10777 5 : error_at (loc, "cast from %qT is not allowed in a "
10778 : "constant expression because "
10779 : "pointed-to type %qT is not similar to %qT",
10780 5 : TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)),
10781 5 : TREE_TYPE (type));
10782 5 : tree obj = build_fold_indirect_ref (sop);
10783 5 : if (TREE_CODE (obj) == COMPONENT_REF)
10784 4 : obj = TREE_OPERAND (obj, 1);
10785 5 : if (DECL_P (obj))
10786 5 : inform (DECL_SOURCE_LOCATION (obj),
10787 : "pointed-to object declared here");
10788 5 : }
10789 47 : *non_constant_p = true;
10790 47 : return t;
10791 : }
10792 : else
10793 : {
10794 165 : if (!ctx->quiet)
10795 26 : error_at (loc, "cast from %qT is not allowed in a "
10796 : "constant expression before C++26",
10797 26 : TREE_TYPE (op));
10798 165 : *non_constant_p = true;
10799 165 : return t;
10800 : }
10801 : }
10802 :
10803 : /* [expr.static.cast]/10: A prvalue of type "pointer to cv1 B", where
10804 : B is a class type, can be converted to a prvalue of type
10805 : "pointer to cv2 D", where D is a complete class derived from B, ...
10806 : If the prvalue of type "pointer to cv1 B" points to a B that is
10807 : actually a base class subobject of an object of type D, the
10808 : resulting pointer points to the enclosing object of type D.
10809 : Otherwise, the behavior is undefined.
10810 : Similarly [expr.static.cast]/2 for references. */
10811 412149685 : if (INDIRECT_TYPE_P (type)
10812 255648903 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10813 255513647 : && COMPLETE_TYPE_P (TREE_TYPE (type))
10814 252281072 : && !integer_zerop (op)
10815 663703702 : && is_properly_derived_from (TREE_TYPE (type),
10816 251554017 : TREE_TYPE (TREE_TYPE (op))))
10817 : {
10818 14362 : tree sop = tree_strip_nop_conversions (op);
10819 14362 : if (cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10820 : NULL, jump_target) == NULL_TREE)
10821 : {
10822 189 : tree dyntype = NULL_TREE;
10823 189 : if (!ctx->quiet && TREE_CODE (sop) == ADDR_EXPR)
10824 : {
10825 44 : sop = TREE_OPERAND (sop, 0);
10826 44 : while (TREE_CODE (sop) == COMPONENT_REF
10827 59 : && DECL_FIELD_IS_BASE (TREE_OPERAND (sop, 1)))
10828 15 : sop = TREE_OPERAND (sop, 0);
10829 44 : dyntype = strip_array_types (TREE_TYPE (sop));
10830 44 : if (same_type_p (dyntype, TREE_TYPE (TREE_TYPE (op))))
10831 166 : dyntype = NULL_TREE;
10832 : }
10833 189 : if (!ctx->quiet)
10834 : {
10835 53 : if (dyntype)
10836 23 : error_at (loc, "%qT operand (of dynamic type %qT) is "
10837 : "not a base class subobject of a %qT object",
10838 23 : TREE_TYPE (TREE_TYPE (op)), dyntype,
10839 23 : TREE_TYPE (type));
10840 : else
10841 30 : error_at (loc, "%qT operand is not a base class "
10842 : "subobject of a %qT object",
10843 30 : TREE_TYPE (TREE_TYPE (op)), TREE_TYPE (type));
10844 : }
10845 189 : *non_constant_p = true;
10846 189 : return t;
10847 : }
10848 : }
10849 :
10850 412149496 : if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
10851 : {
10852 1064 : op = cplus_expand_constant (op);
10853 1064 : if (TREE_CODE (op) == PTRMEM_CST)
10854 : {
10855 21 : if (!ctx->quiet)
10856 3 : error_at (loc, "%qE is not a constant expression when the "
10857 : "class %qT is still incomplete", op,
10858 3 : PTRMEM_CST_CLASS (op));
10859 21 : *non_constant_p = true;
10860 21 : return t;
10861 : }
10862 : }
10863 :
10864 412149475 : if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
10865 : {
10866 655 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
10867 655 : && !can_convert_qual (type, op))
10868 6 : op = cplus_expand_constant (op);
10869 655 : return cp_fold_convert (type, op);
10870 : }
10871 :
10872 412148820 : if (INDIRECT_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
10873 : {
10874 838502 : if (integer_zerop (op))
10875 : {
10876 781533 : if (TYPE_REF_P (type))
10877 : {
10878 36 : if (!ctx->quiet)
10879 4 : error_at (loc, "dereferencing a null pointer");
10880 36 : *non_constant_p = true;
10881 36 : return t;
10882 : }
10883 : }
10884 56969 : else if (TYPE_PTR_P (type)
10885 56969 : && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
10886 : /* INTEGER_CST with pointer-to-method type is only used
10887 : for a virtual method in a pointer to member function.
10888 : Don't reject those. */
10889 : ;
10890 : else
10891 : {
10892 : /* This detects for example:
10893 : reinterpret_cast<void*>(sizeof 0)
10894 : */
10895 56966 : if (!ctx->quiet)
10896 15 : error_at (loc, "%<reinterpret_cast<%T>(%E)%> is not "
10897 : "a constant expression",
10898 : type, op);
10899 56966 : *non_constant_p = true;
10900 56966 : return t;
10901 : }
10902 : }
10903 :
10904 412091818 : if (INDIRECT_TYPE_P (type)
10905 255591712 : && TREE_CODE (op) == NOP_EXPR
10906 122555889 : && TREE_TYPE (op) == ptr_type_node
10907 524568 : && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR
10908 521404 : && VAR_P (TREE_OPERAND (TREE_OPERAND (op, 0), 0))
10909 412500498 : && (DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10910 408680 : 0)) == heap_uninit_identifier
10911 291749 : || DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10912 291749 : 0)) == heap_vec_uninit_identifier))
10913 : {
10914 119140 : tree var = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10915 119140 : tree var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
10916 119140 : tree elt_type = TREE_TYPE (type);
10917 119140 : tree cookie_size = NULL_TREE;
10918 119140 : tree arg_size = NULL_TREE;
10919 119140 : if (TREE_CODE (elt_type) == RECORD_TYPE
10920 119140 : && TYPE_IDENTIFIER (elt_type) == heap_identifier)
10921 : {
10922 9 : tree fld1 = TYPE_FIELDS (elt_type);
10923 9 : tree fld2 = DECL_CHAIN (fld1);
10924 9 : elt_type = TREE_TYPE (TREE_TYPE (fld2));
10925 9 : cookie_size = TYPE_SIZE_UNIT (TREE_TYPE (fld1));
10926 : }
10927 119140 : DECL_NAME (var)
10928 119140 : = (DECL_NAME (var) == heap_uninit_identifier
10929 119140 : ? heap_identifier : heap_vec_identifier);
10930 : /* For zero sized elt_type, try to recover how many outer_nelts
10931 : it should have. */
10932 119140 : if ((cookie_size ? tree_int_cst_equal (var_size, cookie_size)
10933 119131 : : integer_zerop (var_size))
10934 105 : && !int_size_in_bytes (elt_type)
10935 9 : && TREE_CODE (oldop) == CALL_EXPR
10936 119158 : && call_expr_nargs (oldop) >= 1)
10937 9 : if (tree fun = get_function_named_in_call (oldop))
10938 9 : if (cxx_replaceable_global_alloc_fn (fun)
10939 9 : && IDENTIFIER_NEW_OP_P (DECL_NAME (fun)))
10940 9 : arg_size = CALL_EXPR_ARG (oldop, 0);
10941 119140 : tree new_type
10942 119140 : = build_new_constexpr_heap_type (ctx, elt_type, cookie_size,
10943 : var_size, arg_size,
10944 : non_constant_p, overflow_p,
10945 : jump_target);
10946 119140 : if (*jump_target)
10947 : return NULL_TREE;
10948 119140 : TREE_TYPE (var) = new_type;
10949 119140 : TREE_TYPE (TREE_OPERAND (op, 0))
10950 119140 : = build_pointer_type (TREE_TYPE (var));
10951 119140 : if (is_std_allocator_allocate (ctx->call))
10952 : {
10953 : /* [allocator.members]/5: This function starts the lifetime
10954 : of the array object, but not that of any of the array
10955 : elements. */
10956 82084 : tree ctor = build_constructor (new_type, NULL);
10957 82084 : CONSTRUCTOR_NO_CLEARING (ctor) = 1;
10958 82084 : CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
10959 82084 : ctx->global->put_value (var, ctor);
10960 : }
10961 : }
10962 :
10963 : /* This can happen for std::meta::info(^^int) where the cast has no
10964 : meaning. */
10965 412091818 : if (REFLECTION_TYPE_P (type) && REFLECT_EXPR_P (op))
10966 : {
10967 : r = op;
10968 : break;
10969 : }
10970 :
10971 411983716 : if (op == oldop && tcode != UNARY_PLUS_EXPR)
10972 : /* We didn't fold at the top so we could check for ptr-int
10973 : conversion. */
10974 32646389 : return fold (t);
10975 :
10976 379337327 : tree sop;
10977 :
10978 : /* Handle an array's bounds having been deduced after we built
10979 : the wrapping expression. */
10980 379337327 : if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
10981 : r = op;
10982 165142021 : else if (sop = tree_strip_nop_conversions (op),
10983 231406469 : sop != op && (same_type_ignoring_tlq_and_bounds_p
10984 66264448 : (type, TREE_TYPE (sop))))
10985 : r = sop;
10986 135968039 : else if (tcode == UNARY_PLUS_EXPR)
10987 0 : r = fold_convert (TREE_TYPE (t), op);
10988 : else
10989 135968039 : r = fold_build1 (tcode, type, op);
10990 :
10991 : /* Conversion of an out-of-range value has implementation-defined
10992 : behavior; the language considers it different from arithmetic
10993 : overflow, which is undefined. */
10994 379337327 : if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
10995 13273 : TREE_OVERFLOW (r) = false;
10996 : }
10997 : break;
10998 :
10999 9741 : case EXCESS_PRECISION_EXPR:
11000 9741 : {
11001 9741 : tree oldop = TREE_OPERAND (t, 0);
11002 :
11003 9741 : tree op = cxx_eval_constant_expression (ctx, oldop,
11004 : lval,
11005 : non_constant_p, overflow_p,
11006 : jump_target);
11007 9741 : if (*jump_target)
11008 : return NULL_TREE;
11009 9741 : if (*non_constant_p)
11010 : return t;
11011 9735 : r = fold_convert (TREE_TYPE (t), op);
11012 9735 : break;
11013 : }
11014 :
11015 64993 : case EMPTY_CLASS_EXPR:
11016 : /* Handle EMPTY_CLASS_EXPR produced by build_call_a by lowering
11017 : it to an appropriate CONSTRUCTOR. */
11018 64993 : return build_constructor (TREE_TYPE (t), NULL);
11019 :
11020 48474297 : case STATEMENT_LIST:
11021 48474297 : new_ctx = *ctx;
11022 48474297 : new_ctx.ctor = new_ctx.object = NULL_TREE;
11023 48474297 : return cxx_eval_statement_list (&new_ctx, t,
11024 48474293 : non_constant_p, overflow_p, jump_target);
11025 :
11026 33689562 : case BIND_EXPR:
11027 : /* Pre-emptively clear the vars declared by this BIND_EXPR from the value
11028 : map, so that when checking whether they're already destroyed later we
11029 : don't get confused by remnants of previous calls. */
11030 52988137 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
11031 19298575 : ctx->global->clear_value (decl);
11032 33689562 : r = cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
11033 : lval,
11034 : non_constant_p, overflow_p,
11035 : jump_target);
11036 52988133 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
11037 19298573 : destroy_value_checked (ctx, decl, non_constant_p);
11038 : break;
11039 :
11040 8717186 : case PREINCREMENT_EXPR:
11041 8717186 : case POSTINCREMENT_EXPR:
11042 8717186 : case PREDECREMENT_EXPR:
11043 8717186 : case POSTDECREMENT_EXPR:
11044 8717186 : return cxx_eval_increment_expression (ctx, t,
11045 : lval, non_constant_p, overflow_p,
11046 8717186 : jump_target);
11047 :
11048 2182 : case THROW_EXPR:
11049 2182 : if (cxx_dialect >= cxx26)
11050 1855 : return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
11051 : non_constant_p, overflow_p,
11052 1855 : jump_target);
11053 : /* FALLTHROUGH */
11054 335 : case LAMBDA_EXPR:
11055 335 : case NEW_EXPR:
11056 335 : case VEC_NEW_EXPR:
11057 335 : case DELETE_EXPR:
11058 335 : case VEC_DELETE_EXPR:
11059 335 : case MODOP_EXPR:
11060 : /* GCC internal stuff. */
11061 335 : case VA_ARG_EXPR:
11062 335 : case BASELINK:
11063 335 : case OFFSET_REF:
11064 335 : if (!ctx->quiet)
11065 86 : error_at (loc, "expression %qE is not a constant expression", t);
11066 335 : *non_constant_p = true;
11067 335 : break;
11068 :
11069 406273 : case OBJ_TYPE_REF:
11070 : /* Virtual function lookup. We don't need to do anything fancy. */
11071 406273 : return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t),
11072 : lval, non_constant_p, overflow_p,
11073 406273 : jump_target);
11074 :
11075 16140 : case PLACEHOLDER_EXPR:
11076 : /* Use of the value or address of the current object. */
11077 16140 : if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
11078 : {
11079 15897 : if (TREE_CODE (ctor) == CONSTRUCTOR)
11080 : return ctor;
11081 : else
11082 15597 : return cxx_eval_constant_expression (ctx, ctor, lval,
11083 : non_constant_p, overflow_p,
11084 15597 : jump_target);
11085 : }
11086 : /* A placeholder without a referent. We can get here when
11087 : checking whether NSDMIs are noexcept, or in massage_init_elt;
11088 : just say it's non-constant for now. */
11089 243 : gcc_assert (ctx->quiet);
11090 243 : *non_constant_p = true;
11091 243 : break;
11092 :
11093 6921 : case EXIT_EXPR:
11094 6921 : {
11095 6921 : tree cond = TREE_OPERAND (t, 0);
11096 6921 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
11097 : non_constant_p, overflow_p,
11098 : jump_target);
11099 6921 : if (*jump_target)
11100 : return NULL_TREE;
11101 6921 : VERIFY_CONSTANT (cond);
11102 6921 : if (integer_nonzerop (cond))
11103 3385 : *jump_target = t;
11104 : }
11105 : break;
11106 :
11107 83 : case GOTO_EXPR:
11108 83 : if (breaks (&TREE_OPERAND (t, 0))
11109 83 : || continues (&TREE_OPERAND (t, 0)))
11110 64 : *jump_target = TREE_OPERAND (t, 0);
11111 : else
11112 : {
11113 19 : if (!ctx->quiet)
11114 1 : error_at (loc, "%<goto%> is not a constant expression");
11115 19 : *non_constant_p = true;
11116 : }
11117 : break;
11118 :
11119 6662927 : case LOOP_EXPR:
11120 6662927 : case DO_STMT:
11121 6662927 : case WHILE_STMT:
11122 6662927 : case FOR_STMT:
11123 6662927 : cxx_eval_loop_expr (ctx, t,
11124 : non_constant_p, overflow_p, jump_target);
11125 6662927 : break;
11126 :
11127 50118 : case SWITCH_EXPR:
11128 50118 : case SWITCH_STMT:
11129 50118 : cxx_eval_switch_expr (ctx, t,
11130 : non_constant_p, overflow_p, jump_target);
11131 50118 : break;
11132 :
11133 213 : case REQUIRES_EXPR:
11134 : /* It's possible to get a requires-expression in a constant
11135 : expression. For example:
11136 :
11137 : template<typename T> concept bool C() {
11138 : return requires (T t) { t; };
11139 : }
11140 :
11141 : template<typename T> requires !C<T>() void f(T);
11142 :
11143 : Normalization leaves f with the associated constraint
11144 : '!requires (T t) { ... }' which is not transformed into
11145 : a constraint. */
11146 213 : if (!processing_template_decl)
11147 213 : return evaluate_requires_expr (t);
11148 : else
11149 0 : *non_constant_p = true;
11150 0 : return t;
11151 :
11152 1223590 : case ANNOTATE_EXPR:
11153 1223590 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
11154 : lval,
11155 : non_constant_p, overflow_p,
11156 : jump_target);
11157 1223590 : break;
11158 :
11159 9357 : case USING_STMT:
11160 9357 : r = void_node;
11161 9357 : break;
11162 :
11163 30 : case ASSERTION_STMT:
11164 30 : case PRECONDITION_STMT:
11165 30 : case POSTCONDITION_STMT:
11166 30 : {
11167 30 : r = void_node;
11168 : /* Only record the first fail, and do not go further is the semantic
11169 : is 'ignore'. */
11170 30 : if (*non_constant_p || ctx->global->contract_statement
11171 60 : || contract_ignored_p (t))
11172 : break;
11173 :
11174 30 : tree cond = CONTRACT_CONDITION (t);
11175 30 : if (!potential_rvalue_constant_expression (cond))
11176 : {
11177 6 : ctx->global->contract_statement = t;
11178 6 : ctx->global->contract_condition_non_const = true;
11179 6 : break;
11180 : }
11181 :
11182 : /* We need to evaluate and stash the result of this here, since whether
11183 : it needs to be reported (and how) depends on whether the containing
11184 : expression is otherwise const. */
11185 24 : bool ctrct_non_const_p = false;
11186 24 : bool ctrct_overflow_p = false;
11187 24 : tree jmp_target = NULL_TREE;
11188 24 : constexpr_ctx new_ctx = *ctx;
11189 24 : new_ctx.quiet = true;
11190 : /* Avoid modification of existing values. */
11191 24 : modifiable_tracker ms (new_ctx.global);
11192 24 : tree eval =
11193 24 : cxx_eval_constant_expression (&new_ctx, cond, vc_prvalue,
11194 : &ctrct_non_const_p,
11195 : &ctrct_overflow_p, &jmp_target);
11196 : /* Not a constant. */
11197 24 : if (ctrct_non_const_p)
11198 : {
11199 0 : ctx->global->contract_statement = t;
11200 0 : ctx->global->contract_condition_non_const = true;
11201 0 : break;
11202 : }
11203 : /* Constant, but check failed. */
11204 24 : if (integer_zerop (eval))
11205 24 : ctx->global->contract_statement = t;
11206 24 : }
11207 24 : break;
11208 :
11209 2771600 : case TEMPLATE_ID_EXPR:
11210 2771600 : {
11211 : /* We can evaluate template-id that refers to a concept only if
11212 : the template arguments are non-dependent. */
11213 2771600 : gcc_assert (concept_check_p (t));
11214 :
11215 2771600 : if (!value_dependent_expression_p (t)
11216 2771600 : && !uid_sensitive_constexpr_evaluation_p ())
11217 2770677 : r = evaluate_concept_check (t);
11218 : else
11219 923 : *non_constant_p = true;
11220 :
11221 : break;
11222 : }
11223 :
11224 51 : case ASM_EXPR:
11225 51 : if (!ctx->quiet)
11226 29 : inline_asm_in_constexpr_error (loc, /*constexpr_fundef_p*/false);
11227 51 : *non_constant_p = true;
11228 51 : return t;
11229 :
11230 4025 : case BIT_CAST_EXPR:
11231 4025 : if (lval)
11232 : {
11233 0 : if (!ctx->quiet)
11234 0 : error_at (EXPR_LOCATION (t),
11235 : "address of a call to %qs is not a constant expression",
11236 : "__builtin_bit_cast");
11237 0 : *non_constant_p = true;
11238 0 : return t;
11239 : }
11240 4025 : r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p, jump_target);
11241 4025 : break;
11242 :
11243 0 : case OMP_PARALLEL:
11244 0 : case OMP_TASK:
11245 0 : case OMP_FOR:
11246 0 : case OMP_SIMD:
11247 0 : case OMP_DISTRIBUTE:
11248 0 : case OMP_TASKLOOP:
11249 0 : case OMP_LOOP:
11250 0 : case OMP_TEAMS:
11251 0 : case OMP_TARGET_DATA:
11252 0 : case OMP_TARGET:
11253 0 : case OMP_SECTIONS:
11254 0 : case OMP_ORDERED:
11255 0 : case OMP_CRITICAL:
11256 0 : case OMP_SINGLE:
11257 0 : case OMP_SCAN:
11258 0 : case OMP_SCOPE:
11259 0 : case OMP_SECTION:
11260 0 : case OMP_STRUCTURED_BLOCK:
11261 0 : case OMP_MASTER:
11262 0 : case OMP_MASKED:
11263 0 : case OMP_TASKGROUP:
11264 0 : case OMP_TARGET_UPDATE:
11265 0 : case OMP_TARGET_ENTER_DATA:
11266 0 : case OMP_TARGET_EXIT_DATA:
11267 0 : case OMP_ATOMIC:
11268 0 : case OMP_ATOMIC_READ:
11269 0 : case OMP_ATOMIC_CAPTURE_OLD:
11270 0 : case OMP_ATOMIC_CAPTURE_NEW:
11271 0 : case OMP_DEPOBJ:
11272 0 : case OACC_PARALLEL:
11273 0 : case OACC_KERNELS:
11274 0 : case OACC_SERIAL:
11275 0 : case OACC_DATA:
11276 0 : case OACC_HOST_DATA:
11277 0 : case OACC_LOOP:
11278 0 : case OACC_CACHE:
11279 0 : case OACC_DECLARE:
11280 0 : case OACC_ENTER_DATA:
11281 0 : case OACC_EXIT_DATA:
11282 0 : case OACC_UPDATE:
11283 0 : if (!ctx->quiet)
11284 0 : error_at (EXPR_LOCATION (t),
11285 : "statement is not a constant expression");
11286 0 : *non_constant_p = true;
11287 0 : break;
11288 :
11289 0 : default:
11290 0 : if (STATEMENT_CODE_P (TREE_CODE (t)))
11291 : {
11292 : /* This function doesn't know how to deal with pre-genericize
11293 : statements; this can only happen with statement-expressions,
11294 : so for now just fail. */
11295 0 : if (!ctx->quiet)
11296 0 : error_at (EXPR_LOCATION (t),
11297 : "statement is not a constant expression");
11298 : }
11299 0 : else if (flag_checking)
11300 0 : internal_error ("unexpected expression %qE of kind %s", t,
11301 : get_tree_code_name (TREE_CODE (t)));
11302 0 : *non_constant_p = true;
11303 0 : break;
11304 : }
11305 :
11306 2055779742 : if (r == error_mark_node)
11307 14668302 : *non_constant_p = true;
11308 :
11309 135658028 : if (r == void_node && lval != vc_discard && !*jump_target
11310 2055797963 : && !VOID_TYPE_P (TREE_TYPE (t)))
11311 : {
11312 : /* For diagnostic quality we should have handled this sooner, where we
11313 : can be more specific about the out-of-lifetime object. But here we
11314 : can still be correct. */
11315 2 : gcc_checking_assert (false);
11316 : if (!ctx->quiet)
11317 : error_at (EXPR_LOCATION (t),
11318 : "%qE accesses an object outside its lifetime", t);
11319 : *non_constant_p = true;
11320 : }
11321 :
11322 2055779740 : if (*non_constant_p)
11323 : return t;
11324 : else
11325 1632185424 : return r;
11326 : }
11327 :
11328 : /* P0859: A function is needed for constant evaluation if it is a constexpr
11329 : function that is named by an expression ([basic.def.odr]) that is
11330 : potentially constant evaluated.
11331 :
11332 : So we need to instantiate any constexpr functions mentioned by the
11333 : expression even if the definition isn't needed for evaluating the
11334 : expression. */
11335 :
11336 : static tree
11337 594774668 : instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
11338 : {
11339 594774668 : if (TREE_CODE (*tp) == FUNCTION_DECL
11340 12251919 : && DECL_DECLARED_CONSTEXPR_P (*tp)
11341 12114373 : && !DECL_INITIAL (*tp)
11342 3123082 : && !trivial_fn_p (*tp)
11343 3122933 : && (DECL_TEMPLOID_INSTANTIATION (*tp) || DECL_DEFAULTED_FN (*tp))
11344 594774668 : && !uid_sensitive_constexpr_evaluation_p ())
11345 : {
11346 3092791 : ++function_depth;
11347 3092791 : if (DECL_TEMPLOID_INSTANTIATION (*tp))
11348 3092764 : instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
11349 : else
11350 27 : synthesize_method (*tp);
11351 3092791 : --function_depth;
11352 : }
11353 591681877 : else if (TREE_CODE (*tp) == CALL_EXPR
11354 579924895 : || TREE_CODE (*tp) == AGGR_INIT_EXPR)
11355 : {
11356 12316961 : if (EXPR_HAS_LOCATION (*tp))
11357 12310150 : input_location = EXPR_LOCATION (*tp);
11358 : }
11359 :
11360 594774668 : if (!EXPR_P (*tp))
11361 340185604 : *walk_subtrees = 0;
11362 :
11363 594774668 : return NULL_TREE;
11364 : }
11365 :
11366 : static void
11367 290129718 : instantiate_constexpr_fns (tree t)
11368 : {
11369 290129718 : location_t loc = input_location;
11370 290129718 : cp_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
11371 290129718 : input_location = loc;
11372 290129718 : }
11373 :
11374 : /* Look for heap variables in the expression *TP. */
11375 :
11376 : static tree
11377 381494 : find_heap_var_refs (tree *tp, int *walk_subtrees, void */*data*/)
11378 : {
11379 381494 : if (VAR_P (*tp)
11380 381494 : && (DECL_NAME (*tp) == heap_uninit_identifier
11381 10173 : || DECL_NAME (*tp) == heap_identifier
11382 3245 : || DECL_NAME (*tp) == heap_vec_uninit_identifier
11383 2487 : || DECL_NAME (*tp) == heap_vec_identifier
11384 719 : || DECL_NAME (*tp) == heap_deleted_identifier))
11385 : return *tp;
11386 :
11387 267681 : if (TYPE_P (*tp))
11388 178 : *walk_subtrees = 0;
11389 : return NULL_TREE;
11390 : }
11391 :
11392 : /* Find immediate function decls in *TP if any. */
11393 :
11394 : static tree
11395 623180191 : find_immediate_fndecl (tree *tp, int *walk_subtrees, void */*data*/)
11396 : {
11397 627250917 : if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (*tp))
11398 : return *tp;
11399 623172733 : if (TREE_CODE (*tp) == PTRMEM_CST
11400 29810 : && TREE_CODE (PTRMEM_CST_MEMBER (*tp)) == FUNCTION_DECL
11401 623201740 : && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (*tp)))
11402 : return PTRMEM_CST_MEMBER (*tp);
11403 623172628 : if (REFLECT_EXPR_P (*tp))
11404 103748 : *walk_subtrees = 0;
11405 : return NULL_TREE;
11406 : }
11407 :
11408 : /* T has TREE_CONSTANT set but has been deemed not a valid C++ constant
11409 : expression. Return a version of T that has TREE_CONSTANT cleared. */
11410 :
11411 : static tree
11412 148463 : mark_non_constant (tree t)
11413 : {
11414 148463 : gcc_checking_assert (TREE_CONSTANT (t));
11415 :
11416 : /* This isn't actually constant, so unset TREE_CONSTANT.
11417 : Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
11418 : it to be set if it is invariant address, even when it is not
11419 : a valid C++ constant expression. Wrap it with a NOP_EXPR
11420 : instead. */
11421 148463 : if (EXPR_P (t) && TREE_CODE (t) != ADDR_EXPR)
11422 145621 : t = copy_node (t);
11423 2842 : else if (TREE_CODE (t) == CONSTRUCTOR)
11424 478 : t = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (t), t);
11425 : else
11426 2364 : t = build_nop (TREE_TYPE (t), t);
11427 148463 : TREE_CONSTANT (t) = false;
11428 148463 : return t;
11429 : }
11430 :
11431 : /* If we have a successful constant evaluation, now check whether there is
11432 : a failed or non-constant contract that would invalidate this. */
11433 :
11434 : static bool
11435 568517705 : check_for_failed_contracts (constexpr_ctx *ctx)
11436 : {
11437 568517705 : constexpr_global_ctx *const global_ctx = ctx->global;
11438 568517705 : if (!flag_contracts || !global_ctx->contract_statement)
11439 : return false;
11440 :
11441 30 : location_t loc = EXPR_LOCATION (global_ctx->contract_statement);
11442 30 : enum diagnostics::kind kind;
11443 30 : bool error = false;
11444 : /* [intro.compliance.general]/2.3.4. */
11445 : /* [basic.contract.eval]/8. */
11446 30 : if (ctx->manifestly_const_eval != mce_true)
11447 : {
11448 : /* When !MCE, silently return not constant. */
11449 : return true;
11450 : }
11451 27 : else if (contract_terminating_p (global_ctx->contract_statement))
11452 : {
11453 : kind = diagnostics::kind::error;
11454 : error = true;
11455 : }
11456 : else
11457 6 : kind = diagnostics::kind::warning;
11458 :
11459 : /* [basic.contract.eval]/7.3 */
11460 27 : if (global_ctx->contract_condition_non_const)
11461 : {
11462 6 : emit_diagnostic (kind, loc, 0, "contract condition is not constant");
11463 6 : return error;
11464 : }
11465 :
11466 : /* Otherwise, the evaluation was const, but determined to be false. */
11467 21 : emit_diagnostic (kind, loc, 0,
11468 : "contract predicate is false in constant expression");
11469 21 : return error;
11470 : }
11471 :
11472 : /* ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
11473 : STRICT has the same sense as for constant_value_1: true if we only allow
11474 : conforming C++ constant expressions, or false if we want a constant value
11475 : even if it doesn't conform.
11476 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
11477 : per P0595 even when ALLOW_NON_CONSTANT is true.
11478 : CONSTEXPR_DTOR is true when evaluating the dtor of a constexpr variable.
11479 : OBJECT must be non-NULL in that case. */
11480 :
11481 : static tree
11482 578608694 : cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
11483 : bool strict = true,
11484 : mce_value manifestly_const_eval = mce_unknown,
11485 : bool constexpr_dtor = false,
11486 : tree object = NULL_TREE)
11487 : {
11488 578608694 : auto_timevar time (TV_CONSTEXPR);
11489 :
11490 578608694 : bool non_constant_p = false;
11491 578608694 : bool overflow_p = false;
11492 :
11493 578608694 : if (BRACE_ENCLOSED_INITIALIZER_P (t))
11494 : {
11495 0 : gcc_checking_assert (allow_non_constant);
11496 : return t;
11497 : }
11498 :
11499 578608694 : constexpr_global_ctx global_ctx;
11500 578608694 : constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
11501 : allow_non_constant, strict,
11502 578608694 : !allow_non_constant ? mce_true : manifestly_const_eval };
11503 :
11504 : /* Turn off -frounding-math for manifestly constant evaluation. */
11505 578608694 : warning_sentinel rm (flag_rounding_math,
11506 578608694 : ctx.manifestly_const_eval == mce_true);
11507 578608694 : tree type = (object
11508 578608694 : ? cv_unqualified (TREE_TYPE (object))
11509 511854929 : : initialized_type (t));
11510 578608694 : tree r = t;
11511 578608694 : bool is_consteval = false;
11512 578608694 : if (VOID_TYPE_P (type))
11513 : {
11514 10083246 : if (!constexpr_dtor)
11515 : {
11516 10083246 : if (cxx_dialect < cxx20)
11517 : return t;
11518 : /* We could have a COMPOUND_EXPR here coming from
11519 : keep_unused_object_arg. */
11520 10072196 : tree x = extract_call_expr (t);
11521 10072196 : if (x == NULL_TREE || x == error_mark_node)
11522 : return t;
11523 : /* Calls to immediate functions returning void need to be
11524 : evaluated. */
11525 10072156 : tree fndecl = cp_get_callee_fndecl_nofold (x);
11526 20144312 : if (fndecl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (fndecl))
11527 : return t;
11528 : else
11529 1154 : is_consteval = true;
11530 1154 : tree lam;
11531 1154 : if (manifestly_const_eval == mce_true
11532 1693 : && LAMBDA_FUNCTION_P (fndecl)
11533 533 : && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fndecl)))
11534 1687 : && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
11535 516 : global_ctx.consteval_block = fndecl;
11536 : }
11537 : }
11538 568525448 : else if (cxx_dialect >= cxx20
11539 559618969 : && (TREE_CODE (t) == CALL_EXPR
11540 480740069 : || TREE_CODE (t) == AGGR_INIT_EXPR
11541 475620248 : || TREE_CODE (t) == TARGET_EXPR))
11542 : {
11543 89462686 : tree x = t;
11544 89462686 : if (TREE_CODE (x) == TARGET_EXPR)
11545 5463965 : x = TARGET_EXPR_INITIAL (x);
11546 89462686 : tree fndecl = cp_get_callee_fndecl_nofold (x);
11547 176144771 : if (fndecl && DECL_IMMEDIATE_FUNCTION_P (fndecl))
11548 : is_consteval = true;
11549 : /* Don't try to evaluate a std::vector constructor taking an integer, it
11550 : will fail in the 'if (heap_var)' block below after doing all the work
11551 : (c++/113835). This will need adjustment if P3554 is accepted. Note
11552 : that evaluation of e.g. the vector default constructor can succeed, so
11553 : we don't shortcut all vector constructors. */
11554 173364170 : if (fndecl && DECL_CONSTRUCTOR_P (fndecl) && allow_non_constant
11555 11531821 : && is_std_class (type, "vector") && call_expr_nargs (x) > 1
11556 89487216 : && TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE)
11557 : return t;
11558 : }
11559 568524555 : if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
11560 : {
11561 : /* In C++14 an NSDMI can participate in aggregate initialization,
11562 : and can refer to the address of the object being initialized, so
11563 : we need to pass in the relevant VAR_DECL if we want to do the
11564 : evaluation in a single pass. The evaluation will dynamically
11565 : update ctx.values for the VAR_DECL. We use the same strategy
11566 : for C++11 constexpr constructors that refer to the object being
11567 : initialized. */
11568 49606912 : if (constexpr_dtor)
11569 : {
11570 200 : gcc_assert (object && VAR_P (object));
11571 200 : gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
11572 200 : gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
11573 200 : if (error_operand_p (DECL_INITIAL (object)))
11574 : return t;
11575 183 : ctx.ctor = unshare_expr (DECL_INITIAL (object));
11576 183 : TREE_READONLY (ctx.ctor) = false;
11577 : /* Temporarily force decl_really_constant_value to return false
11578 : for it, we want to use ctx.ctor for the current value instead. */
11579 183 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = false;
11580 : }
11581 : else
11582 : {
11583 49606712 : ctx.ctor = build_constructor (type, NULL);
11584 49606712 : CONSTRUCTOR_NO_CLEARING (ctx.ctor) = true;
11585 : }
11586 49606895 : if (!object)
11587 : {
11588 21998700 : if (TREE_CODE (t) == CALL_EXPR)
11589 : {
11590 : /* If T is calling a constructor to initialize an object, reframe
11591 : it as an AGGR_INIT_EXPR to avoid trying to modify an object
11592 : from outside the constant evaluation, which will fail even if
11593 : the value is actually constant (is_constant_evaluated3.C). */
11594 9971237 : tree fn = cp_get_callee_fndecl_nofold (t);
11595 19942266 : if (fn && DECL_CONSTRUCTOR_P (fn))
11596 : {
11597 4096262 : object = CALL_EXPR_ARG (t, 0);
11598 4096262 : object = build_fold_indirect_ref (object);
11599 4096262 : r = build_aggr_init_expr (type, r);
11600 : }
11601 : }
11602 12027463 : else if (TREE_CODE (t) == TARGET_EXPR)
11603 5359003 : object = TARGET_EXPR_SLOT (t);
11604 6668460 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
11605 707588 : object = AGGR_INIT_EXPR_SLOT (t);
11606 : }
11607 49606895 : ctx.object = object;
11608 49606895 : if (object)
11609 37771048 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
11610 : (type, TREE_TYPE (object)));
11611 37771048 : if (object && DECL_P (object))
11612 31626790 : global_ctx.put_value (object, ctx.ctor);
11613 49606895 : if (TREE_CODE (r) == TARGET_EXPR)
11614 : /* Avoid creating another CONSTRUCTOR when we expand the
11615 : TARGET_EXPR. */
11616 5500480 : r = TARGET_EXPR_INITIAL (r);
11617 : }
11618 :
11619 : /* uid_sensitive_constexpr_evaluation_value restricts warning-dependent
11620 : constexpr evaluation to avoid unnecessary template instantiation, and is
11621 : always done with mce_unknown. But due to gaps in the restriction logic
11622 : we may still end up taking an evaluation path that in turn requires
11623 : manifestly constant evaluation, and such evaluation must not be
11624 : restricted since it likely has semantic consequences.
11625 : TODO: Remove/replace the mechanism in GCC 17. */
11626 568524538 : auto uids = make_temp_override (uid_sensitive_constexpr_evaluation_value);
11627 568524538 : if (ctx.manifestly_const_eval == mce_true)
11628 290129718 : uid_sensitive_constexpr_evaluation_value = false;
11629 :
11630 568524538 : auto_vec<tree, 16> cleanups;
11631 568524538 : global_ctx.cleanups = &cleanups;
11632 :
11633 568524538 : if (manifestly_const_eval == mce_true)
11634 290129718 : instantiate_constexpr_fns (r);
11635 568524538 : tree jmp_target = NULL_TREE;
11636 568524538 : r = cxx_eval_constant_expression (&ctx, r, vc_prvalue,
11637 : &non_constant_p, &overflow_p,
11638 : &jmp_target);
11639 568523175 : if (throws (&jmp_target) && !non_constant_p)
11640 : {
11641 1336 : if (!ctx.quiet)
11642 374 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
11643 1336 : non_constant_p = true;
11644 1336 : jmp_target = NULL_TREE;
11645 1336 : r = t;
11646 : }
11647 568520503 : else if (!non_constant_p && jmp_target)
11648 : {
11649 24 : non_constant_p = true;
11650 24 : if (!ctx.quiet)
11651 : {
11652 3 : if (breaks (&jmp_target))
11653 3 : error ("%<break%> outside of a loop or %<switch%>");
11654 0 : else if (continues (&jmp_target))
11655 0 : error ("%<continue%> outside of a loop");
11656 0 : else if (returns (&jmp_target))
11657 0 : error ("%<return%> in a statement expression");
11658 : else
11659 0 : gcc_unreachable ();
11660 : }
11661 24 : r = t;
11662 : }
11663 :
11664 : /* If we got a non-simple TARGET_EXPR, the initializer was a sequence
11665 : of statements, and the result ought to be stored in ctx.ctor. */
11666 568521839 : if (r == void_node && !constexpr_dtor && ctx.ctor)
11667 0 : r = ctx.ctor;
11668 :
11669 568521839 : unsigned int i;
11670 568521839 : tree cleanup;
11671 568521839 : jmp_target = NULL_TREE;
11672 : /* Evaluate the cleanups. */
11673 1137146170 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
11674 102492 : if (cleanup == NULL_TREE)
11675 : /* NULL_TREE cleanup is a marker that before it is
11676 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it. */
11677 23 : --i;
11678 : else
11679 102469 : cxx_eval_constant_expression (&ctx, cleanup, vc_discard,
11680 : &non_constant_p, &overflow_p,
11681 : &jmp_target);
11682 568521839 : if (throws (&jmp_target) && !non_constant_p)
11683 : {
11684 0 : if (!ctx.quiet)
11685 0 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
11686 0 : non_constant_p = true;
11687 0 : r = t;
11688 : }
11689 :
11690 : /* Mutable logic is a bit tricky: we want to allow initialization of
11691 : constexpr variables with mutable members, but we can't copy those
11692 : members to another constexpr variable. */
11693 568521839 : if (!non_constant_p
11694 417057482 : && TREE_CODE (r) == CONSTRUCTOR
11695 585449045 : && CONSTRUCTOR_MUTABLE_POISON (r))
11696 : {
11697 93 : if (!allow_non_constant)
11698 6 : error ("%qE is not a constant expression because it refers to "
11699 : "mutable subobjects of %qT", t, type);
11700 93 : non_constant_p = true;
11701 : }
11702 :
11703 417057389 : if (!non_constant_p && cxx_dialect >= cxx20
11704 985579228 : && !global_ctx.heap_vars.is_empty ())
11705 : {
11706 124515 : tree heap_var = cp_walk_tree_without_duplicates (&r, find_heap_var_refs,
11707 : NULL);
11708 124515 : unsigned int i;
11709 124515 : if (heap_var)
11710 : {
11711 113813 : if (!allow_non_constant && !non_constant_p)
11712 : {
11713 17 : auto_diagnostic_group d;
11714 17 : if (DECL_LANG_SPECIFIC (heap_var))
11715 4 : error ("%qE is not a constant expression because it refers to "
11716 : "exception object allocated with "
11717 : "%<__cxa_allocate_exception%>", t);
11718 : else
11719 13 : error ("%qE is not a constant expression because it refers to "
11720 : "a result of %<operator new%>", t);
11721 17 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11722 17 : }
11723 113813 : r = t;
11724 113813 : non_constant_p = true;
11725 : }
11726 322944 : FOR_EACH_VEC_ELT (global_ctx.heap_vars, i, heap_var)
11727 : {
11728 198429 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
11729 : {
11730 114385 : if (!allow_non_constant && !non_constant_p)
11731 : {
11732 16 : auto_diagnostic_group d;
11733 16 : error ("%qE is not a constant expression because allocated "
11734 : "storage has not been deallocated", t);
11735 16 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11736 16 : }
11737 114385 : r = t;
11738 114385 : non_constant_p = true;
11739 : }
11740 : }
11741 : }
11742 :
11743 : /* Check that immediate invocation does not return an expression referencing
11744 : any immediate function decls. */
11745 568521839 : if (!non_constant_p && cxx_dialect >= cxx20)
11746 822459638 : if (tree immediate_fndecl
11747 411229819 : = cp_walk_tree_without_duplicates (&r, find_immediate_fndecl,
11748 : NULL))
11749 : {
11750 7563 : if (!allow_non_constant && !non_constant_p)
11751 : {
11752 74 : if (is_consteval)
11753 36 : error_at (cp_expr_loc_or_input_loc (t),
11754 : "immediate evaluation returns address of immediate "
11755 : "function %qD", immediate_fndecl);
11756 : else
11757 58 : error_at (cp_expr_loc_or_input_loc (t),
11758 : "constant evaluation returns address of immediate "
11759 : "function %qD", immediate_fndecl);
11760 : }
11761 7563 : r = t;
11762 7563 : non_constant_p = true;
11763 : }
11764 :
11765 : /* Detect consteval-only smuggling: turning a consteval-only object
11766 : into one that is not. For instance, in
11767 : struct B { };
11768 : struct D : B { info r; };
11769 : constexpr D d{^^::};
11770 : constexpr const B &b = d; // #1
11771 : #1 is wrong because D is a consteval-only type but B is not. */
11772 568521839 : if (flag_reflection
11773 11600417 : && !non_constant_p
11774 9336990 : && object
11775 1024462 : && POINTER_TYPE_P (TREE_TYPE (object))
11776 4256 : && !consteval_only_p (object)
11777 568525981 : && check_out_of_consteval_use (r, /*complain=*/false))
11778 : {
11779 30 : if (!allow_non_constant)
11780 : {
11781 10 : if (TYPE_REF_P (TREE_TYPE (object)))
11782 12 : error_at (cp_expr_loc_or_input_loc (t),
11783 : "reference into an object of consteval-only type is "
11784 : "not a constant expression unless it also has "
11785 : "consteval-only type");
11786 : else
11787 4 : error_at (cp_expr_loc_or_input_loc (t),
11788 : "pointer into an object of consteval-only type is "
11789 : "not a constant expression unless it also has "
11790 : "consteval-only type");
11791 : }
11792 30 : r = t;
11793 30 : non_constant_p = true;
11794 : }
11795 :
11796 568521839 : if (!non_constant_p && !constexpr_dtor)
11797 416935738 : verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
11798 :
11799 : /* After verify_constant because reduced_constant_expression_p can unset
11800 : CONSTRUCTOR_NO_CLEARING. */
11801 568521839 : if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
11802 : {
11803 69850 : if (!allow_non_constant)
11804 45 : error ("%qE is not a constant expression because it refers to "
11805 : "an incompletely initialized variable", t);
11806 69850 : TREE_CONSTANT (r) = false;
11807 69850 : non_constant_p = true;
11808 : }
11809 :
11810 568521839 : if (non_constant_p)
11811 : /* If we saw something bad, go back to our argument. The wrapping below is
11812 : only for the cases of TREE_CONSTANT argument or overflow. */
11813 154022990 : r = t;
11814 :
11815 568521839 : if (!non_constant_p && overflow_p)
11816 215 : non_constant_p = true;
11817 :
11818 : /* Unshare the result. */
11819 568521839 : bool should_unshare = true;
11820 568521839 : if (r == t || (TREE_CODE (t) == TARGET_EXPR
11821 1507213 : && TARGET_EXPR_INITIAL (t) == r))
11822 : should_unshare = false;
11823 :
11824 568521839 : if (non_constant_p && !allow_non_constant)
11825 4134 : return error_mark_node;
11826 568517705 : else if (check_for_failed_contracts (&ctx))
11827 : {
11828 24 : if (manifestly_const_eval == mce_true)
11829 : /* If MCE, we gave a hard error and return error_mark_node. */
11830 21 : return error_mark_node;
11831 : else
11832 : {
11833 : /* Otherwise treat it as non-constant so the violation is still
11834 : detectable at run-time. */
11835 3 : gcc_checking_assert (allow_non_constant);
11836 : return t;
11837 : }
11838 : }
11839 568517681 : else if (non_constant_p && TREE_CONSTANT (r))
11840 143965 : r = mark_non_constant (r);
11841 568373716 : else if (non_constant_p)
11842 : return t;
11843 :
11844 414642575 : if (constexpr_dtor)
11845 : {
11846 165 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
11847 165 : return r;
11848 : }
11849 :
11850 : /* Check we are not trying to return the wrong type. */
11851 414642410 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
11852 : {
11853 : /* If so, this is not a constant expression. */
11854 156 : if (!allow_non_constant)
11855 4 : error ("%qE is not a constant expression because it initializes "
11856 4 : "a %qT rather than %qT", t, TREE_TYPE (t), type);
11857 : return t;
11858 : }
11859 :
11860 414642254 : if (should_unshare)
11861 232675246 : r = unshare_expr (r);
11862 :
11863 414642254 : if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
11864 : {
11865 15974732 : r = adjust_temp_type (type, r);
11866 15974732 : if (TREE_CODE (t) == TARGET_EXPR
11867 15974732 : && TARGET_EXPR_INITIAL (t) == r)
11868 : return t;
11869 15020630 : else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR
11870 2521762 : || TREE_CODE (t) == AGGR_INIT_EXPR)
11871 : /* Don't add a TARGET_EXPR if our argument didn't have one. */;
11872 837275 : else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t))
11873 767 : r = get_target_expr (r);
11874 836508 : else if (processing_template_decl)
11875 : /* Don't insert TARGET_EXPR in template trees. */
11876 : return r;
11877 : else
11878 : {
11879 836505 : r = get_target_expr (r, tf_warning_or_error | tf_no_cleanup);
11880 836505 : TREE_CONSTANT (r) = true;
11881 : }
11882 : }
11883 :
11884 413688149 : if (TREE_CODE (t) == TARGET_EXPR
11885 553111 : && TREE_CODE (r) == TARGET_EXPR)
11886 : {
11887 : /* Preserve this flag for potential_constant_expression, and the others
11888 : for good measure. */
11889 552999 : TARGET_EXPR_ELIDING_P (r) = TARGET_EXPR_ELIDING_P (t);
11890 552999 : TARGET_EXPR_IMPLICIT_P (r) = TARGET_EXPR_IMPLICIT_P (t);
11891 552999 : TARGET_EXPR_LIST_INIT_P (r) = TARGET_EXPR_LIST_INIT_P (t);
11892 552999 : TARGET_EXPR_DIRECT_INIT_P (r) = TARGET_EXPR_DIRECT_INIT_P (t);
11893 : }
11894 :
11895 : /* Remember the original location if that wouldn't need a wrapper. */
11896 413688149 : if (location_t loc = EXPR_LOCATION (t))
11897 189597845 : protected_set_expr_location (r, loc);
11898 :
11899 413688149 : return r;
11900 578605995 : }
11901 :
11902 : /* If T represents a constant expression returns its reduced value.
11903 : Otherwise return error_mark_node. */
11904 :
11905 : tree
11906 159089996 : cxx_constant_value (tree t, tree decl /* = NULL_TREE */,
11907 : tsubst_flags_t complain /* = tf_error */)
11908 : {
11909 159089996 : bool sfinae = !(complain & tf_error);
11910 159089996 : tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, mce_true, false, decl);
11911 159089996 : if (sfinae && !TREE_CONSTANT (r))
11912 2685 : r = error_mark_node;
11913 159089996 : return r;
11914 : }
11915 :
11916 : /* Like cxx_constant_value, but used for evaluation of constexpr destructors
11917 : of constexpr variables. The actual initializer of DECL is not modified. */
11918 :
11919 : void
11920 200 : cxx_constant_dtor (tree t, tree decl)
11921 : {
11922 200 : cxx_eval_outermost_constant_expr (t, false, true, mce_true, true, decl);
11923 200 : }
11924 :
11925 : /* Helper routine for fold_simple function. Either return simplified
11926 : expression T, otherwise NULL_TREE.
11927 : In contrast to cp_fully_fold, and to maybe_constant_value, we try to fold
11928 : even if we are within template-declaration. So be careful on call, as in
11929 : such case types can be undefined. */
11930 :
11931 : static tree
11932 170688289 : fold_simple_1 (tree t)
11933 : {
11934 170688289 : tree op1;
11935 170688289 : enum tree_code code = TREE_CODE (t);
11936 :
11937 170688289 : switch (code)
11938 : {
11939 : case INTEGER_CST:
11940 : case REAL_CST:
11941 : case VECTOR_CST:
11942 : case FIXED_CST:
11943 : case COMPLEX_CST:
11944 : return t;
11945 :
11946 1462028 : case SIZEOF_EXPR:
11947 1462028 : return fold_sizeof_expr (t);
11948 :
11949 40435257 : case ABS_EXPR:
11950 40435257 : case ABSU_EXPR:
11951 40435257 : case CONJ_EXPR:
11952 40435257 : case REALPART_EXPR:
11953 40435257 : case IMAGPART_EXPR:
11954 40435257 : case NEGATE_EXPR:
11955 40435257 : case BIT_NOT_EXPR:
11956 40435257 : case TRUTH_NOT_EXPR:
11957 40435257 : case VIEW_CONVERT_EXPR:
11958 40435257 : CASE_CONVERT:
11959 40435257 : case FLOAT_EXPR:
11960 40435257 : case FIX_TRUNC_EXPR:
11961 40435257 : case FIXED_CONVERT_EXPR:
11962 40435257 : case ADDR_SPACE_CONVERT_EXPR:
11963 :
11964 40435257 : op1 = TREE_OPERAND (t, 0);
11965 :
11966 40435257 : t = const_unop (code, TREE_TYPE (t), op1);
11967 40435257 : if (!t)
11968 : return NULL_TREE;
11969 :
11970 6121672 : if (CONVERT_EXPR_CODE_P (code)
11971 6121672 : && TREE_OVERFLOW_P (t) && !TREE_OVERFLOW_P (op1))
11972 0 : TREE_OVERFLOW (t) = false;
11973 : return t;
11974 :
11975 : default:
11976 : return NULL_TREE;
11977 : }
11978 : }
11979 :
11980 : /* If T is a simple constant expression, returns its simplified value.
11981 : Otherwise returns T. In contrast to maybe_constant_value we
11982 : simplify only few operations on constant-expressions, and we don't
11983 : try to simplify constexpressions. */
11984 :
11985 : tree
11986 171458882 : fold_simple (tree t)
11987 : {
11988 171458882 : if (processing_template_decl)
11989 : return t;
11990 :
11991 170688289 : tree r = fold_simple_1 (t);
11992 170688289 : if (r)
11993 119871937 : return r;
11994 :
11995 : return t;
11996 : }
11997 :
11998 : /* Try folding the expression T to a simple constant.
11999 : Returns that constant, otherwise returns T. */
12000 :
12001 : tree
12002 1681603 : fold_to_constant (tree t)
12003 : {
12004 1681603 : if (processing_template_decl)
12005 : return t;
12006 :
12007 1584204 : tree r = fold (t);
12008 1584204 : if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
12009 : return r;
12010 : else
12011 140970 : return t;
12012 : }
12013 :
12014 : /* If T is a constant expression, returns its reduced value.
12015 : Otherwise, if T does not have TREE_CONSTANT set, returns T.
12016 : Otherwise, returns a version of T without TREE_CONSTANT.
12017 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
12018 : as per P0595. */
12019 :
12020 : static GTY((deletable)) hash_map<tree, tree> *cv_cache;
12021 :
12022 : tree
12023 869736575 : maybe_constant_value (tree t, tree decl /* = NULL_TREE */,
12024 : mce_value manifestly_const_eval /* = mce_unknown */)
12025 : {
12026 869736575 : tree orig_t = t;
12027 869736575 : tree r;
12028 :
12029 869736575 : if (EXPR_P (t) && manifestly_const_eval == mce_unknown)
12030 : {
12031 : /* Look up each operand in the cv_cache first to see if we've already
12032 : reduced it, and reuse that result to avoid quadratic behavior if
12033 : we're called when building up a large expression. */
12034 252199376 : int n = cp_tree_operand_length (t);
12035 252199376 : tree *ops = XALLOCAVEC (tree, n);
12036 252199376 : bool rebuild = false;
12037 705950935 : for (int i = 0; i < n; ++i)
12038 : {
12039 453751559 : ops[i] = TREE_OPERAND (t, i);
12040 938257840 : if (tree *cached = hash_map_safe_get (cv_cache, ops[i]))
12041 31382345 : if (*cached != ops[i])
12042 : {
12043 9807538 : ops[i] = *cached;
12044 9807538 : rebuild = true;
12045 : }
12046 : }
12047 252199376 : if (rebuild)
12048 : {
12049 8234324 : t = copy_node (t);
12050 26822074 : for (int i = 0; i < n; ++i)
12051 18587750 : TREE_OPERAND (t, i) = ops[i];
12052 : }
12053 : }
12054 :
12055 869736575 : if (!is_nondependent_constant_expression (t))
12056 : {
12057 0 : if (TREE_OVERFLOW_P (t)
12058 128883151 : || (!processing_template_decl && TREE_CONSTANT (t)))
12059 4498 : t = mark_non_constant (t);
12060 128883151 : return t;
12061 : }
12062 740853424 : else if (CONSTANT_CLASS_P (t))
12063 : /* No caching or evaluation needed. */
12064 : return t;
12065 :
12066 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
12067 : but at least try folding it to a simple constant. */
12068 339049981 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
12069 511180 : return fold_to_constant (t);
12070 :
12071 321949973 : if (manifestly_const_eval != mce_unknown)
12072 : /* TODO: Extend the cache to be mce_value aware. And if we have a
12073 : previously cached mce_unknown result that's TREE_CONSTANT, it means
12074 : the reduced value is independent of mce_value and so we should
12075 : be able to reuse it in the mce_true/false case. */
12076 173546981 : return cxx_eval_outermost_constant_expr (t, true, true,
12077 173544282 : manifestly_const_eval, false, decl);
12078 :
12079 164991820 : if (cv_cache == NULL)
12080 151184 : cv_cache = hash_map<tree, tree>::create_ggc (101);
12081 164991820 : if (tree *cached = cv_cache->get (t))
12082 : {
12083 13439962 : r = *cached;
12084 13439962 : if (r != t)
12085 : {
12086 : /* Clear processing_template_decl for sake of break_out_target_exprs;
12087 : entries in the cv_cache are non-templated. */
12088 4526747 : processing_template_decl_sentinel ptds;
12089 :
12090 4526747 : r = break_out_target_exprs (r, /*clear_loc*/true);
12091 4526747 : protected_set_expr_location (r, EXPR_LOCATION (t));
12092 4526747 : }
12093 13439962 : return r;
12094 : }
12095 :
12096 151551858 : uid_sensitive_constexpr_evaluation_checker c;
12097 151551858 : r = cxx_eval_outermost_constant_expr (t, true, true,
12098 : manifestly_const_eval, false, decl);
12099 151551858 : gcc_checking_assert (r == t
12100 : || CONVERT_EXPR_P (t)
12101 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
12102 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
12103 : || !cp_tree_equal (r, t));
12104 151551858 : if (!c.evaluation_restricted_p ())
12105 151308016 : cv_cache->put (orig_t, r);
12106 : return r;
12107 : }
12108 :
12109 : /* Dispose of the whole CV_CACHE. */
12110 :
12111 : static void
12112 41314662 : clear_cv_cache (void)
12113 : {
12114 41314662 : if (cv_cache != NULL)
12115 41000245 : cv_cache->empty ();
12116 41314662 : }
12117 :
12118 : /* Dispose of the whole CV_CACHE and FOLD_CACHE. */
12119 :
12120 : void
12121 41314662 : clear_cv_and_fold_caches ()
12122 : {
12123 41314662 : clear_cv_cache ();
12124 41314662 : clear_fold_cache ();
12125 41314662 : }
12126 :
12127 : /* Internal function handling expressions in templates for
12128 : fold_non_dependent_expr and fold_non_dependent_init.
12129 :
12130 : If we're in a template, but T isn't value dependent, simplify
12131 : it. We're supposed to treat:
12132 :
12133 : template <typename T> void f(T[1 + 1]);
12134 : template <typename T> void f(T[2]);
12135 :
12136 : as two declarations of the same function, for example. */
12137 :
12138 : static tree
12139 31734084 : fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
12140 : bool manifestly_const_eval,
12141 : tree object)
12142 : {
12143 31734084 : gcc_assert (processing_template_decl);
12144 :
12145 31734084 : if (is_nondependent_constant_expression (t))
12146 : {
12147 17661923 : processing_template_decl_sentinel s;
12148 17661923 : t = instantiate_non_dependent_expr_internal (t, complain);
12149 :
12150 17661923 : if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t))
12151 : {
12152 0 : if (TREE_OVERFLOW_P (t))
12153 : {
12154 0 : t = build_nop (TREE_TYPE (t), t);
12155 0 : TREE_CONSTANT (t) = false;
12156 : }
12157 : return t;
12158 : }
12159 17661923 : else if (CONSTANT_CLASS_P (t))
12160 : /* No evaluation needed. */
12161 : return t;
12162 :
12163 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
12164 : but at least try folding it to a simple constant. */
12165 4687905 : if (cp_unevaluated_operand && !manifestly_const_eval)
12166 89 : return fold_to_constant (t);
12167 :
12168 4687816 : tree r = cxx_eval_outermost_constant_expr (t, true, true,
12169 : mce_value (manifestly_const_eval),
12170 : false, object);
12171 : /* cp_tree_equal looks through NOPs, so allow them. */
12172 4687816 : gcc_checking_assert (r == t
12173 : || CONVERT_EXPR_P (t)
12174 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
12175 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
12176 : || !cp_tree_equal (r, t));
12177 : return r;
12178 17661923 : }
12179 14072161 : else if (TREE_OVERFLOW_P (t))
12180 : {
12181 0 : t = build_nop (TREE_TYPE (t), t);
12182 0 : TREE_CONSTANT (t) = false;
12183 : }
12184 :
12185 : return t;
12186 : }
12187 :
12188 : /* Like maybe_constant_value but first fully instantiate the argument.
12189 :
12190 : Note: this is equivalent to instantiate_non_dependent_expr (t, complain)
12191 : followed by maybe_constant_value but is more efficient,
12192 : because it calls instantiation_dependent_expression_p and
12193 : potential_constant_expression at most once.
12194 : The manifestly_const_eval argument is passed to maybe_constant_value.
12195 :
12196 : Callers should generally pass their active complain, or if they are in a
12197 : non-template, diagnosing context, they can use the default of
12198 : tf_warning_or_error. Callers that might be within a template context, don't
12199 : have a complain parameter, and aren't going to remember the result for long
12200 : (e.g. null_ptr_cst_p), can pass tf_none and deal with error_mark_node
12201 : appropriately. */
12202 :
12203 : tree
12204 266005778 : fold_non_dependent_expr (tree t,
12205 : tsubst_flags_t complain /* = tf_warning_or_error */,
12206 : bool manifestly_const_eval /* = false */,
12207 : tree object /* = NULL_TREE */)
12208 : {
12209 266005778 : if (t == NULL_TREE)
12210 : return NULL_TREE;
12211 :
12212 264877669 : if (processing_template_decl)
12213 30600205 : return fold_non_dependent_expr_template (t, complain,
12214 30600205 : manifestly_const_eval, object);
12215 :
12216 234277464 : return maybe_constant_value (t, object, mce_value (manifestly_const_eval));
12217 : }
12218 :
12219 : /* Like fold_non_dependent_expr, but if EXPR couldn't be folded to a constant,
12220 : return the original expression. */
12221 :
12222 : tree
12223 2403796 : maybe_fold_non_dependent_expr (tree expr,
12224 : tsubst_flags_t complain/*=tf_warning_or_error*/)
12225 : {
12226 2403796 : tree t = fold_non_dependent_expr (expr, complain);
12227 2403796 : if (t && TREE_CONSTANT (t))
12228 1155136 : return t;
12229 :
12230 : return expr;
12231 : }
12232 :
12233 : /* Like maybe_constant_init but first fully instantiate the argument. */
12234 :
12235 : tree
12236 62944934 : fold_non_dependent_init (tree t,
12237 : tsubst_flags_t complain /*=tf_warning_or_error*/,
12238 : bool manifestly_const_eval /*=false*/,
12239 : tree object /* = NULL_TREE */)
12240 : {
12241 62944934 : if (t == NULL_TREE)
12242 : return NULL_TREE;
12243 :
12244 62944934 : if (processing_template_decl)
12245 : {
12246 1133879 : t = fold_non_dependent_expr_template (t, complain,
12247 : manifestly_const_eval, object);
12248 : /* maybe_constant_init does this stripping, so do it here too. */
12249 1133879 : if (TREE_CODE (t) == TARGET_EXPR)
12250 : {
12251 2107 : tree init = TARGET_EXPR_INITIAL (t);
12252 2107 : if (TREE_CODE (init) == CONSTRUCTOR)
12253 62944934 : t = init;
12254 : }
12255 : return t;
12256 : }
12257 :
12258 61811055 : return maybe_constant_init (t, object, manifestly_const_eval);
12259 : }
12260 :
12261 : /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
12262 : than wrapped in a TARGET_EXPR.
12263 : ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
12264 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
12265 : per P0595 even when ALLOW_NON_CONSTANT is true. */
12266 :
12267 : static tree
12268 175811675 : maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
12269 : mce_value manifestly_const_eval)
12270 : {
12271 175811675 : if (!t)
12272 : return t;
12273 175811675 : if (TREE_CODE (t) == EXPR_STMT)
12274 264 : t = TREE_OPERAND (t, 0);
12275 175811675 : if (TREE_CODE (t) == CONVERT_EXPR
12276 175811675 : && VOID_TYPE_P (TREE_TYPE (t)))
12277 2833 : t = TREE_OPERAND (t, 0);
12278 : /* If the types don't match, the INIT_EXPR is initializing a subobject of
12279 : DECL and losing that information would cause mischief later. */
12280 175811675 : if (TREE_CODE (t) == INIT_EXPR
12281 175811675 : && (!decl
12282 2587 : || same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (decl),
12283 2587 : TREE_TYPE (t))))
12284 1688 : t = TREE_OPERAND (t, 1);
12285 175811675 : if (TREE_CODE (t) == TARGET_EXPR)
12286 7880716 : t = TARGET_EXPR_INITIAL (t);
12287 175811675 : if (!is_nondependent_static_init_expression (t))
12288 : /* Don't try to evaluate it. */;
12289 142077863 : else if (CONSTANT_CLASS_P (t) && TREE_CODE (t) != PTRMEM_CST)
12290 : /* No evaluation needed. PTRMEM_CST needs the immediate fn check. */;
12291 : else
12292 : {
12293 : /* [basic.start.static] allows constant-initialization of variables with
12294 : static or thread storage duration even if it isn't required, but we
12295 : shouldn't bend the rules the same way for automatic variables.
12296 :
12297 : But still enforce the requirements of constexpr/constinit.
12298 : [dcl.constinit] "If a variable declared with the constinit specifier
12299 : has dynamic initialization, the program is ill-formed, even if the
12300 : implementation would perform that initialization as a static
12301 : initialization." */
12302 43353784 : bool is_static = (decl && DECL_P (decl)
12303 103437761 : && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
12304 : bool strict = (!is_static
12305 : || (decl && DECL_P (decl)
12306 3447268 : && (DECL_DECLARED_CONSTEXPR_P (decl)
12307 992815 : || DECL_DECLARED_CONSTINIT_P (decl))));
12308 : if (is_static)
12309 : manifestly_const_eval = mce_true;
12310 :
12311 65854657 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
12312 89181 : return fold_to_constant (t);
12313 :
12314 65765476 : t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
12315 : manifestly_const_eval,
12316 : false, decl);
12317 : }
12318 175722494 : if (TREE_CODE (t) == TARGET_EXPR)
12319 : {
12320 283715 : tree init = TARGET_EXPR_INITIAL (t);
12321 283715 : if (TREE_CODE (init) == CONSTRUCTOR)
12322 175811675 : t = init;
12323 : }
12324 : return t;
12325 : }
12326 :
12327 : /* Wrapper for maybe_constant_init_1 which permits non constants. */
12328 :
12329 : tree
12330 96279646 : maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
12331 : {
12332 96279646 : return maybe_constant_init_1 (t, decl, true, mce_value (manifestly_const_eval));
12333 : }
12334 :
12335 : tree
12336 79529802 : maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval)
12337 : {
12338 79529802 : return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
12339 : }
12340 :
12341 : /* Wrapper for maybe_constant_init_1 which does not permit non constants. */
12342 :
12343 : tree
12344 2227 : cxx_constant_init (tree t, tree decl)
12345 : {
12346 2227 : return maybe_constant_init_1 (t, decl, false, mce_true);
12347 : }
12348 :
12349 : /* Return true if CALL_EXPR T might throw during constant evaluation. */
12350 :
12351 : static bool
12352 232137147 : callee_might_throw (tree t)
12353 : {
12354 232137147 : if (cxx_dialect < cxx26 || !flag_exceptions)
12355 : return false;
12356 36692915 : tree callee = cp_get_callee (t);
12357 36692915 : if (callee == NULL_TREE)
12358 : return false;
12359 36636167 : tree callee_fn = cp_get_fndecl_from_callee (callee, false);
12360 36636167 : return (!flag_enforce_eh_specs
12361 36636167 : || type_dependent_expression_p (callee)
12362 33607750 : || !POINTER_TYPE_P (TREE_TYPE (callee))
12363 68050805 : || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee)))
12364 14779740 : && (callee_fn == NULL_TREE || !TREE_NOTHROW (callee_fn))));
12365 : }
12366 :
12367 : #if 0
12368 : /* FIXME see ADDR_EXPR section in potential_constant_expression_1. */
12369 : /* Return true if the object referred to by REF has automatic or thread
12370 : local storage. */
12371 :
12372 : enum { ck_ok, ck_bad, ck_unknown };
12373 : static int
12374 : check_automatic_or_tls (tree ref)
12375 : {
12376 : machine_mode mode;
12377 : poly_int64 bitsize, bitpos;
12378 : tree offset;
12379 : int volatilep = 0, unsignedp = 0;
12380 : tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
12381 : &mode, &unsignedp, &volatilep, false);
12382 : duration_kind dk;
12383 :
12384 : /* If there isn't a decl in the middle, we don't know the linkage here,
12385 : and this isn't a constant expression anyway. */
12386 : if (!DECL_P (decl))
12387 : return ck_unknown;
12388 : dk = decl_storage_duration (decl);
12389 : return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
12390 : }
12391 : #endif
12392 :
12393 : /* Data structure for passing data from potential_constant_expression_1
12394 : to check_for_return_continue via cp_walk_tree. */
12395 : struct check_for_return_continue_data {
12396 : hash_set<tree> *pset;
12397 : tree continue_stmt;
12398 : tree break_stmt;
12399 : bool could_throw;
12400 : };
12401 :
12402 : /* Helper function for potential_constant_expression_1 SWITCH_STMT handling,
12403 : called through cp_walk_tree. Return the first RETURN_EXPR found, or note
12404 : the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found.
12405 : For C++26 also note presence of possibly throwing calls. */
12406 : static tree
12407 51622841 : check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
12408 : {
12409 51622841 : tree t = *tp, s, b;
12410 51622841 : check_for_return_continue_data *d = (check_for_return_continue_data *) data;
12411 51622841 : switch (TREE_CODE (t))
12412 : {
12413 : case RETURN_EXPR:
12414 : return t;
12415 :
12416 28 : case CONTINUE_STMT:
12417 28 : if (d->continue_stmt == NULL_TREE)
12418 28 : d->continue_stmt = t;
12419 : break;
12420 :
12421 3268 : case BREAK_STMT:
12422 3268 : if (d->break_stmt == NULL_TREE)
12423 1345 : d->break_stmt = t;
12424 : break;
12425 :
12426 : #define RECUR(x) \
12427 : if (tree r = cp_walk_tree (&x, check_for_return_continue, data, \
12428 : d->pset)) \
12429 : return r
12430 :
12431 : /* For loops, walk subtrees manually, so that continue stmts found
12432 : inside of the bodies of the loops are ignored. */
12433 42311 : case DO_STMT:
12434 42311 : *walk_subtrees = 0;
12435 42311 : RECUR (DO_COND (t));
12436 42311 : s = d->continue_stmt;
12437 42311 : b = d->break_stmt;
12438 42311 : RECUR (DO_BODY (t));
12439 42311 : d->continue_stmt = s;
12440 42311 : d->break_stmt = b;
12441 42311 : break;
12442 :
12443 123 : case WHILE_STMT:
12444 123 : *walk_subtrees = 0;
12445 123 : RECUR (WHILE_COND_PREP (t));
12446 123 : RECUR (WHILE_COND (t));
12447 123 : s = d->continue_stmt;
12448 123 : b = d->break_stmt;
12449 123 : RECUR (WHILE_BODY (t));
12450 109 : d->continue_stmt = s;
12451 109 : d->break_stmt = b;
12452 109 : break;
12453 :
12454 402 : case FOR_STMT:
12455 402 : *walk_subtrees = 0;
12456 402 : RECUR (FOR_INIT_STMT (t));
12457 402 : RECUR (FOR_COND_PREP (t));
12458 402 : RECUR (FOR_COND (t));
12459 402 : RECUR (FOR_EXPR (t));
12460 402 : s = d->continue_stmt;
12461 402 : b = d->break_stmt;
12462 402 : RECUR (FOR_BODY (t));
12463 348 : d->continue_stmt = s;
12464 348 : d->break_stmt = b;
12465 348 : break;
12466 :
12467 0 : case RANGE_FOR_STMT:
12468 0 : *walk_subtrees = 0;
12469 0 : RECUR (RANGE_FOR_EXPR (t));
12470 0 : s = d->continue_stmt;
12471 0 : b = d->break_stmt;
12472 0 : RECUR (RANGE_FOR_BODY (t));
12473 0 : d->continue_stmt = s;
12474 0 : d->break_stmt = b;
12475 0 : break;
12476 :
12477 209 : case SWITCH_STMT:
12478 209 : *walk_subtrees = 0;
12479 209 : RECUR (SWITCH_STMT_COND (t));
12480 209 : b = d->break_stmt;
12481 209 : RECUR (SWITCH_STMT_BODY (t));
12482 189 : d->break_stmt = b;
12483 189 : break;
12484 : #undef RECUR
12485 :
12486 : case STATEMENT_LIST:
12487 : case CONSTRUCTOR:
12488 : break;
12489 :
12490 2658569 : case AGGR_INIT_EXPR:
12491 2658569 : case CALL_EXPR:
12492 : /* In C++26 a function could throw. */
12493 2658569 : if (callee_might_throw (t))
12494 126437 : d->could_throw = true;
12495 : break;
12496 :
12497 47502851 : default:
12498 47502851 : if (!EXPR_P (t))
12499 14734956 : *walk_subtrees = 0;
12500 : break;
12501 : }
12502 :
12503 : return NULL_TREE;
12504 : }
12505 :
12506 : /* Return true if T denotes a potentially constant expression. Issue
12507 : diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
12508 : an lvalue-rvalue conversion is implied. If NOW is true, we want to
12509 : consider the expression in the current context, independent of constexpr
12510 : substitution. If FUNDEF_P is true, we're checking a constexpr function body
12511 : and hard errors should not be reported by constexpr_error.
12512 :
12513 : C++0x [expr.const] used to say
12514 :
12515 : 6 An expression is a potential constant expression if it is
12516 : a constant expression where all occurrences of function
12517 : parameters are replaced by arbitrary constant expressions
12518 : of the appropriate type.
12519 :
12520 : 2 A conditional expression is a constant expression unless it
12521 : involves one of the following as a potentially evaluated
12522 : subexpression (3.2), but subexpressions of logical AND (5.14),
12523 : logical OR (5.15), and conditional (5.16) operations that are
12524 : not evaluated are not considered. */
12525 :
12526 : static bool
12527 4971433753 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
12528 : bool fundef_p, tsubst_flags_t flags,
12529 : tree *jump_target)
12530 : {
12531 : #define RECUR(T,RV) \
12532 : potential_constant_expression_1 ((T), (RV), strict, now, fundef_p, flags, \
12533 : jump_target)
12534 :
12535 4971433753 : enum { any = false, rval = true };
12536 4971433753 : int i;
12537 4971433753 : tree tmp;
12538 :
12539 4971433753 : if (t == error_mark_node)
12540 : return false;
12541 4971421298 : if (t == NULL_TREE)
12542 : return true;
12543 4963232489 : location_t loc = cp_expr_loc_or_input_loc (t);
12544 4963232489 : iloc_sentinel ils = loc;
12545 :
12546 4963232489 : if (*jump_target)
12547 : /* If we are jumping, ignore everything. This is simpler than the
12548 : cxx_eval_constant_expression handling because we only need to be
12549 : conservatively correct, and we don't necessarily have a constant value
12550 : available, so we don't bother with switch tracking. */
12551 : return true;
12552 :
12553 2242578 : if (TREE_THIS_VOLATILE (t) && want_rval
12554 1267414 : && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))
12555 4953730719 : && !NULLPTR_TYPE_P (TREE_TYPE (t)))
12556 : {
12557 78758 : if (TREE_CLOBBER_P (t))
12558 : {
12559 : /* We should have caught any clobbers in INIT/MODIFY_EXPR. */
12560 0 : gcc_checking_assert (false);
12561 : return true;
12562 : }
12563 :
12564 78758 : if (flags & tf_error)
12565 25 : constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of "
12566 : "a volatile lvalue %qE with type %qT", t,
12567 25 : TREE_TYPE (t));
12568 : return false;
12569 : }
12570 4953573176 : if (CONSTANT_CLASS_P (t))
12571 : return true;
12572 3609799427 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
12573 3609799427 : && TREE_TYPE (t) == error_mark_node)
12574 : return false;
12575 :
12576 3609799384 : switch (TREE_CODE (t))
12577 : {
12578 : case FUNCTION_DECL:
12579 : case BASELINK:
12580 : case TEMPLATE_DECL:
12581 : case OVERLOAD:
12582 : case TEMPLATE_ID_EXPR:
12583 : case LABEL_DECL:
12584 : case CASE_LABEL_EXPR:
12585 : case PREDICT_EXPR:
12586 : case CONST_DECL:
12587 : case SIZEOF_EXPR:
12588 : case ALIGNOF_EXPR:
12589 : case OFFSETOF_EXPR:
12590 : case NOEXCEPT_EXPR:
12591 : case TEMPLATE_PARM_INDEX:
12592 : case TRAIT_EXPR:
12593 : case IDENTIFIER_NODE:
12594 : case USERDEF_LITERAL:
12595 : /* We can see a FIELD_DECL in a pointer-to-member expression. */
12596 : case FIELD_DECL:
12597 : case RESULT_DECL:
12598 : case USING_DECL:
12599 : case USING_STMT:
12600 : case PLACEHOLDER_EXPR:
12601 : case REQUIRES_EXPR:
12602 : case STATIC_ASSERT:
12603 : case DEBUG_BEGIN_STMT:
12604 : case REFLECT_EXPR:
12605 : return true;
12606 :
12607 24993874 : case RETURN_EXPR:
12608 24993874 : if (!RECUR (TREE_OPERAND (t, 0), any))
12609 : return false;
12610 : /* FALLTHROUGH */
12611 :
12612 24825783 : case BREAK_STMT:
12613 24825783 : case CONTINUE_STMT:
12614 24825783 : *jump_target = t;
12615 24825783 : return true;
12616 :
12617 395375434 : case PARM_DECL:
12618 395375434 : if (now && want_rval)
12619 : {
12620 101578608 : tree type = TREE_TYPE (t);
12621 101578608 : if (dependent_type_p (type)
12622 72583936 : || !COMPLETE_TYPE_P (processing_template_decl
12623 : ? type : complete_type (type))
12624 174162544 : || is_really_empty_class (type, /*ignore_vptr*/false))
12625 : /* An empty class has no data to read. */
12626 : return true;
12627 72583230 : if (flags & tf_error)
12628 19 : constexpr_error (input_location, fundef_p,
12629 : "%qE is not a constant expression", t);
12630 : return false;
12631 : }
12632 : return true;
12633 :
12634 286486040 : case AGGR_INIT_EXPR:
12635 286486040 : case CALL_EXPR:
12636 : /* -- an invocation of a function other than a constexpr function
12637 : or a constexpr constructor. */
12638 286486040 : {
12639 286486040 : tree fun = get_function_named_in_call (t);
12640 286486040 : const int nargs = call_expr_nargs (t);
12641 286486040 : i = 0;
12642 :
12643 286486040 : if (fun == NULL_TREE)
12644 : {
12645 : /* Reset to allow the function to continue past the end
12646 : of the block below. Otherwise return early. */
12647 427271 : bool bail = true;
12648 :
12649 427271 : if (TREE_CODE (t) == CALL_EXPR
12650 427271 : && CALL_EXPR_FN (t) == NULL_TREE)
12651 427271 : switch (CALL_EXPR_IFN (t))
12652 : {
12653 : /* These should be ignored, they are optimized away from
12654 : constexpr functions. */
12655 : case IFN_UBSAN_NULL:
12656 : case IFN_UBSAN_BOUNDS:
12657 : case IFN_UBSAN_VPTR:
12658 : case IFN_FALLTHROUGH:
12659 : case IFN_ASSUME:
12660 : return true;
12661 :
12662 : case IFN_ADD_OVERFLOW:
12663 : case IFN_SUB_OVERFLOW:
12664 : case IFN_MUL_OVERFLOW:
12665 : case IFN_LAUNDER:
12666 : case IFN_VEC_CONVERT:
12667 : case IFN_BSWAP:
12668 : case IFN_BITREVERSE:
12669 : bail = false;
12670 : break;
12671 :
12672 : default:
12673 : break;
12674 : }
12675 :
12676 : if (bail)
12677 : {
12678 : /* fold_call_expr can't do anything with IFN calls. */
12679 172 : if (flags & tf_error)
12680 0 : constexpr_error (loc, fundef_p,
12681 : "call to internal function %qE", t);
12682 : return false;
12683 : }
12684 : }
12685 :
12686 286058769 : if (fun && is_overloaded_fn (fun))
12687 : {
12688 267175130 : if (!RECUR (fun, true))
12689 : return false;
12690 266749229 : fun = get_fns (fun);
12691 :
12692 266749229 : if (TREE_CODE (fun) == FUNCTION_DECL)
12693 : {
12694 248787105 : if (builtin_valid_in_constant_expr_p (fun))
12695 : return true;
12696 246962861 : if (!maybe_constexpr_fn (fun)
12697 : /* Allow any built-in function; if the expansion
12698 : isn't constant, we'll deal with that then. */
12699 55452823 : && !fndecl_built_in_p (fun)
12700 : /* In C++20, replaceable global allocation functions
12701 : are constant expressions. */
12702 37823282 : && (!cxx_replaceable_global_alloc_fn (fun)
12703 993086 : || TREE_CODE (t) != CALL_EXPR
12704 993086 : || (!CALL_FROM_NEW_OR_DELETE_P (t)
12705 362790 : && (current_function_decl == NULL_TREE
12706 362790 : || !is_std_allocator_allocate_deallocate
12707 362790 : (current_function_decl))))
12708 : /* Allow placement new in std::construct_at. */
12709 36837262 : && (!cxx_placement_new_fn (fun)
12710 403009 : || TREE_CODE (t) != CALL_EXPR
12711 403009 : || current_function_decl == NULL_TREE
12712 402997 : || !is_std_construct_at (current_function_decl))
12713 36564824 : && !cxx_dynamic_cast_fn_p (fun)
12714 283524074 : && !cxx_cxa_builtin_fn_p (fun))
12715 : {
12716 : /* In C++26 evaluation of the function arguments might
12717 : throw and in that case it is irrelevant whether
12718 : fun is constexpr or not. */
12719 36508381 : if (cxx_dialect >= cxx26)
12720 8061981 : for (; i < nargs; ++i)
12721 : {
12722 4838123 : tree x = get_nth_callarg (t, i);
12723 4838123 : bool rv = processing_template_decl ? any : rval;
12724 4838123 : bool sub_now = false;
12725 4838123 : if (!potential_constant_expression_1 (x, rv, strict,
12726 : sub_now,
12727 : fundef_p,
12728 : flags,
12729 : jump_target))
12730 : return false;
12731 4550312 : if (throws (jump_target))
12732 : return true;
12733 : }
12734 36191310 : if ((flags & tf_error)
12735 36191310 : && constexpr_error (loc, fundef_p,
12736 : "call to non-%<constexpr%> "
12737 : "function %qD", fun))
12738 272 : explain_invalid_constexpr_fn (fun);
12739 : return false;
12740 : }
12741 : }
12742 :
12743 228416604 : fun = OVL_FIRST (fun);
12744 : /* Skip initial arguments to base constructors. */
12745 228416604 : if (DECL_BASE_CONSTRUCTOR_P (fun))
12746 4182562 : i = num_artificial_parms_for (fun);
12747 : }
12748 18883639 : else if (fun)
12749 : {
12750 18883639 : if (TREE_TYPE (fun)
12751 18883639 : && FUNCTION_POINTER_TYPE_P (TREE_TYPE (fun)))
12752 : want_rval = rval;
12753 : else
12754 : want_rval = any;
12755 18883639 : if (RECUR (fun, want_rval))
12756 : /* Might end up being a constant function pointer. But it
12757 : could also be a function object with constexpr op(), so
12758 : we pass 'any' so that the underlying VAR_DECL is deemed
12759 : as potentially-constant even though it wasn't declared
12760 : constexpr. */;
12761 : else
12762 : return false;
12763 : }
12764 548954504 : for (; i < nargs; ++i)
12765 : {
12766 319420904 : tree x = get_nth_callarg (t, i);
12767 : /* In a template, reference arguments haven't been converted to
12768 : REFERENCE_TYPE and we might not even know if the parameter
12769 : is a reference, so accept lvalue constants too. */
12770 319420904 : bool rv = processing_template_decl ? any : rval;
12771 : /* Don't require an immediately constant value, as constexpr
12772 : substitution might not use the value of the argument. */
12773 319420904 : bool sub_now = false;
12774 319420904 : if (!potential_constant_expression_1 (x, rv, strict,
12775 : sub_now, fundef_p, flags,
12776 : jump_target))
12777 : return false;
12778 3234435181 : if (throws (jump_target))
12779 : return true;
12780 : }
12781 : /* In C++26 a function could throw. */
12782 229533600 : if (*jump_target == NULL_TREE && callee_might_throw (t))
12783 11624615 : *jump_target = void_node;
12784 : return true;
12785 : }
12786 :
12787 203569263 : case NON_LVALUE_EXPR:
12788 : /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
12789 : -- an lvalue of integral type that refers to a non-volatile
12790 : const variable or static data member initialized with
12791 : constant expressions, or
12792 :
12793 : -- an lvalue of literal type that refers to non-volatile
12794 : object defined with constexpr, or that refers to a
12795 : sub-object of such an object; */
12796 203569263 : return RECUR (TREE_OPERAND (t, 0), rval);
12797 :
12798 71291 : case EXCESS_PRECISION_EXPR:
12799 71291 : return RECUR (TREE_OPERAND (t, 0), rval);
12800 :
12801 315819031 : case VAR_DECL:
12802 315819031 : if (DECL_HAS_VALUE_EXPR_P (t))
12803 : {
12804 5240931 : if (now && is_normal_capture_proxy (t))
12805 : {
12806 : /* -- in a lambda-expression, a reference to this or to a
12807 : variable with automatic storage duration defined outside that
12808 : lambda-expression, where the reference would be an
12809 : odr-use. */
12810 :
12811 471187 : if (want_rval)
12812 : /* Since we're doing an lvalue-rvalue conversion, this might
12813 : not be an odr-use, so evaluate the variable directly. */
12814 464220 : return RECUR (DECL_CAPTURED_VARIABLE (t), rval);
12815 :
12816 6967 : if (flags & tf_error)
12817 : {
12818 3 : tree cap = DECL_CAPTURED_VARIABLE (t);
12819 3 : auto_diagnostic_group d;
12820 3 : if (constexpr_error (input_location, fundef_p,
12821 : "lambda capture of %qE is not a "
12822 : "constant expression", cap)
12823 3 : && decl_constant_var_p (cap))
12824 3 : inform (input_location, "because it is used as a glvalue");
12825 3 : }
12826 : return false;
12827 : }
12828 4769744 : tree ve = DECL_VALUE_EXPR (t);
12829 : /* Treat __PRETTY_FUNCTION__ inside a template function as
12830 : potentially-constant. */
12831 4769744 : if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
12832 : return true;
12833 4769739 : if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
12834 2736 : return RECUR (TREE_VEC_ELT (ve, 0), rval);
12835 4767003 : return RECUR (ve, rval);
12836 : }
12837 310578100 : if (want_rval
12838 219446310 : && (now || !var_in_maybe_constexpr_fn (t))
12839 200023293 : && !type_dependent_expression_p (t)
12840 168104817 : && !decl_maybe_constant_var_p (t)
12841 55128858 : && !is_local_temp (t)
12842 54553424 : && (strict
12843 4115744 : || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
12844 1635792 : || (DECL_INITIAL (t)
12845 1166364 : && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)))
12846 54044881 : && COMPLETE_TYPE_P (TREE_TYPE (t))
12847 364622829 : && !is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
12848 : {
12849 54039898 : if (flags & tf_error)
12850 171 : non_const_var_error (loc, t, fundef_p);
12851 : return false;
12852 : }
12853 : return true;
12854 :
12855 449714767 : case NOP_EXPR:
12856 449714767 : if (REINTERPRET_CAST_P (t))
12857 : {
12858 163487 : if (flags & tf_error)
12859 49 : constexpr_error (loc, fundef_p, "%<reinterpret_cast%> is not a "
12860 : "constant expression");
12861 : return false;
12862 : }
12863 : /* FALLTHRU */
12864 905246588 : case CONVERT_EXPR:
12865 905246588 : case VIEW_CONVERT_EXPR:
12866 : /* -- a reinterpret_cast. FIXME not implemented, and this rule
12867 : may change to something more specific to type-punning (DR 1312). */
12868 905246588 : {
12869 905246588 : tree from = TREE_OPERAND (t, 0);
12870 905246588 : if (location_wrapper_p (t))
12871 371526362 : return (RECUR (from, want_rval));
12872 533720226 : if (INDIRECT_TYPE_P (TREE_TYPE (t)))
12873 : {
12874 304369200 : STRIP_ANY_LOCATION_WRAPPER (from);
12875 304369200 : if (TREE_CODE (from) == INTEGER_CST
12876 304369200 : && !integer_zerop (from))
12877 : {
12878 1629 : if (flags & tf_error)
12879 28 : constexpr_error (loc, fundef_p,
12880 : "%<reinterpret_cast%> from integer to "
12881 : "pointer");
12882 : return false;
12883 : }
12884 : }
12885 533718597 : return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR));
12886 : }
12887 :
12888 12973 : case ADDRESSOF_EXPR:
12889 : /* This is like ADDR_EXPR, except it won't form pointer-to-member. */
12890 12973 : t = TREE_OPERAND (t, 0);
12891 12973 : goto handle_addr_expr;
12892 :
12893 100727132 : case ADDR_EXPR:
12894 : /* -- a unary operator & that is applied to an lvalue that
12895 : designates an object with thread or automatic storage
12896 : duration; */
12897 100727132 : t = TREE_OPERAND (t, 0);
12898 :
12899 100727132 : if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t))
12900 : /* A pointer-to-member constant. */
12901 : return true;
12902 :
12903 100739839 : handle_addr_expr:
12904 : #if 0
12905 : /* FIXME adjust when issue 1197 is fully resolved. For now don't do
12906 : any checking here, as we might dereference the pointer later. If
12907 : we remove this code, also remove check_automatic_or_tls. */
12908 : i = check_automatic_or_tls (t);
12909 : if (i == ck_ok)
12910 : return true;
12911 : if (i == ck_bad)
12912 : {
12913 : if (flags & tf_error)
12914 : error ("address-of an object %qE with thread local or "
12915 : "automatic storage is not a constant expression", t);
12916 : return false;
12917 : }
12918 : #endif
12919 100739839 : return RECUR (t, any);
12920 :
12921 107557270 : case COMPONENT_REF:
12922 107557270 : case ARROW_EXPR:
12923 107557270 : case OFFSET_REF:
12924 : /* -- a class member access unless its postfix-expression is
12925 : of literal type or of pointer to literal type. */
12926 : /* This test would be redundant, as it follows from the
12927 : postfix-expression being a potential constant expression. */
12928 107557270 : if (type_unknown_p (t))
12929 : return true;
12930 99567194 : if (is_overloaded_fn (t))
12931 : /* In a template, a COMPONENT_REF of a function expresses ob.fn(),
12932 : which uses ob as an lvalue. */
12933 102084510 : want_rval = false;
12934 102084510 : gcc_fallthrough ();
12935 :
12936 102084510 : case REALPART_EXPR:
12937 102084510 : case IMAGPART_EXPR:
12938 102084510 : case BIT_FIELD_REF:
12939 102084510 : return RECUR (TREE_OPERAND (t, 0), want_rval);
12940 :
12941 295649 : case EXPR_PACK_EXPANSION:
12942 295649 : return RECUR (PACK_EXPANSION_PATTERN (t), want_rval);
12943 :
12944 : case PACK_INDEX_EXPR:
12945 : return true;
12946 :
12947 113225020 : case INDIRECT_REF:
12948 113225020 : return RECUR (TREE_OPERAND (t, 0), rval);
12949 :
12950 25648171 : case STATEMENT_LIST:
12951 5064207081 : for (tree stmt : tsi_range (t))
12952 75853893 : if (!RECUR (stmt, any))
12953 4963232489 : return false;
12954 : return true;
12955 :
12956 5178015 : case MODIFY_EXPR:
12957 5178015 : if (cxx_dialect < cxx14)
12958 3892 : goto fail;
12959 5174123 : if (!RECUR (TREE_OPERAND (t, 0), any))
12960 : return false;
12961 : /* Just ignore clobbers. */
12962 4315799 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
12963 : return true;
12964 3833495 : if (!RECUR (TREE_OPERAND (t, 1), rval))
12965 : return false;
12966 : return true;
12967 :
12968 908574 : case MODOP_EXPR:
12969 908574 : if (cxx_dialect < cxx14)
12970 98 : goto fail;
12971 908476 : if (!RECUR (TREE_OPERAND (t, 0), rval))
12972 : return false;
12973 897883 : if (!RECUR (TREE_OPERAND (t, 2), rval))
12974 : return false;
12975 : return true;
12976 :
12977 552152 : case DO_STMT:
12978 552152 : if (!RECUR (DO_COND (t), rval))
12979 : return false;
12980 552152 : if (!RECUR (DO_BODY (t), any))
12981 : return false;
12982 551537 : if (breaks (jump_target) || continues (jump_target))
12983 5 : *jump_target = NULL_TREE;
12984 : return true;
12985 :
12986 454790 : case FOR_STMT:
12987 454790 : if (!RECUR (FOR_INIT_STMT (t), any))
12988 : return false;
12989 454790 : if (!RECUR (FOR_COND_PREP (t), any))
12990 : return false;
12991 454790 : tmp = FOR_COND (t);
12992 454790 : if (!RECUR (tmp, rval))
12993 : return false;
12994 454716 : if (tmp)
12995 : {
12996 406141 : if (!processing_template_decl)
12997 401596 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
12998 : /* If we couldn't evaluate the condition, it might not ever be
12999 : true. */
13000 406141 : if (!integer_onep (tmp))
13001 : {
13002 : /* Before returning true, check if the for body can contain
13003 : a return. */
13004 406141 : hash_set<tree> pset;
13005 406141 : check_for_return_continue_data data = { &pset, NULL_TREE,
13006 406141 : NULL_TREE, false };
13007 406141 : if (tree ret_expr
13008 406141 : = cp_walk_tree (&FOR_BODY (t), check_for_return_continue,
13009 : &data, &pset))
13010 141251 : *jump_target = ret_expr;
13011 406141 : if (data.could_throw)
13012 17863 : *jump_target = void_node;
13013 406141 : return true;
13014 406141 : }
13015 : }
13016 48575 : if (!RECUR (FOR_EXPR (t), any))
13017 : return false;
13018 48575 : if (!RECUR (FOR_BODY (t), any))
13019 : return false;
13020 48575 : if (!RECUR (FOR_COND_CLEANUP (t), any))
13021 : return false;
13022 48575 : if (breaks (jump_target) || continues (jump_target))
13023 12 : *jump_target = NULL_TREE;
13024 : return true;
13025 :
13026 480 : case RANGE_FOR_STMT:
13027 480 : if (!RECUR (RANGE_FOR_INIT_STMT (t), any))
13028 : return false;
13029 480 : if (!RECUR (RANGE_FOR_EXPR (t), any))
13030 : return false;
13031 480 : if (!RECUR (RANGE_FOR_BODY (t), any))
13032 : return false;
13033 478 : if (breaks (jump_target) || continues (jump_target))
13034 0 : *jump_target = NULL_TREE;
13035 : return true;
13036 :
13037 169017 : case WHILE_STMT:
13038 169017 : if (!RECUR (WHILE_COND_PREP (t), any))
13039 : return false;
13040 169017 : tmp = WHILE_COND (t);
13041 169017 : if (!RECUR (tmp, rval))
13042 : return false;
13043 168953 : if (!processing_template_decl)
13044 168916 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13045 : /* If we couldn't evaluate the condition, it might not ever be true. */
13046 168953 : if (!integer_onep (tmp))
13047 : {
13048 : /* Before returning true, check if the while body can contain
13049 : a return. */
13050 158761 : hash_set<tree> pset;
13051 158761 : check_for_return_continue_data data = { &pset, NULL_TREE,
13052 158761 : NULL_TREE, false };
13053 158761 : if (tree ret_expr
13054 158761 : = cp_walk_tree (&WHILE_BODY (t), check_for_return_continue,
13055 : &data, &pset))
13056 476 : *jump_target = ret_expr;
13057 158761 : if (data.could_throw)
13058 4617 : *jump_target = void_node;
13059 158761 : return true;
13060 158761 : }
13061 10192 : if (!RECUR (WHILE_BODY (t), any))
13062 : return false;
13063 10181 : if (!RECUR (WHILE_COND_CLEANUP (t), any))
13064 : return false;
13065 10181 : if (breaks (jump_target) || continues (jump_target))
13066 24 : *jump_target = NULL_TREE;
13067 : return true;
13068 :
13069 43086 : case SWITCH_STMT:
13070 43086 : if (!RECUR (SWITCH_STMT_COND (t), rval))
13071 : return false;
13072 : /* FIXME we don't check SWITCH_STMT_BODY currently, because even
13073 : unreachable labels would be checked and it is enough if there is
13074 : a single switch cond value for which it is a valid constant
13075 : expression. We need to check if there are any RETURN_EXPRs
13076 : or CONTINUE_STMTs inside of the body though, as in that case
13077 : we need to set *jump_target. */
13078 : else
13079 : {
13080 43080 : hash_set<tree> pset;
13081 43080 : check_for_return_continue_data data = { &pset, NULL_TREE,
13082 43080 : NULL_TREE, false };
13083 43080 : if (tree ret_expr
13084 43080 : = cp_walk_tree (&SWITCH_STMT_BODY (t), check_for_return_continue,
13085 : &data, &pset))
13086 : /* The switch might return. */
13087 42687 : *jump_target = ret_expr;
13088 393 : else if (data.continue_stmt)
13089 : /* The switch can't return, but might continue. */
13090 3 : *jump_target = data.continue_stmt;
13091 43080 : if (data.could_throw)
13092 1859 : *jump_target = void_node;
13093 43080 : }
13094 43080 : return true;
13095 :
13096 50 : case STMT_EXPR:
13097 50 : return RECUR (STMT_EXPR_STMT (t), rval);
13098 :
13099 626489 : case LAMBDA_EXPR:
13100 626489 : if (cxx_dialect >= cxx17)
13101 : /* In C++17 lambdas can be constexpr, don't give up yet. */
13102 : return true;
13103 476 : else if (flags & tf_error)
13104 0 : constexpr_error (loc, fundef_p, "lambda-expression is not a "
13105 : "constant expression before C++17");
13106 : return false;
13107 :
13108 114145 : case NEW_EXPR:
13109 114145 : case VEC_NEW_EXPR:
13110 114145 : case DELETE_EXPR:
13111 114145 : case VEC_DELETE_EXPR:
13112 114145 : if (cxx_dialect >= cxx20)
13113 : /* In C++20, new-expressions are potentially constant. */
13114 : return true;
13115 1077 : else if (flags & tf_error)
13116 0 : constexpr_error (loc, fundef_p, "new-expression is not a "
13117 : "constant expression before C++20");
13118 : return false;
13119 :
13120 85331 : case DYNAMIC_CAST_EXPR:
13121 85331 : case PSEUDO_DTOR_EXPR:
13122 85331 : case OMP_PARALLEL:
13123 85331 : case OMP_TASK:
13124 85331 : case OMP_FOR:
13125 85331 : case OMP_SIMD:
13126 85331 : case OMP_DISTRIBUTE:
13127 85331 : case OMP_TASKLOOP:
13128 85331 : case OMP_LOOP:
13129 85331 : case OMP_TEAMS:
13130 85331 : case OMP_TARGET_DATA:
13131 85331 : case OMP_TARGET:
13132 85331 : case OMP_SECTIONS:
13133 85331 : case OMP_ORDERED:
13134 85331 : case OMP_CRITICAL:
13135 85331 : case OMP_SINGLE:
13136 85331 : case OMP_SCAN:
13137 85331 : case OMP_SCOPE:
13138 85331 : case OMP_SECTION:
13139 85331 : case OMP_MASTER:
13140 85331 : case OMP_MASKED:
13141 85331 : case OMP_TASKGROUP:
13142 85331 : case OMP_TARGET_UPDATE:
13143 85331 : case OMP_TARGET_ENTER_DATA:
13144 85331 : case OMP_TARGET_EXIT_DATA:
13145 85331 : case OMP_ATOMIC:
13146 85331 : case OMP_ATOMIC_READ:
13147 85331 : case OMP_ATOMIC_CAPTURE_OLD:
13148 85331 : case OMP_ATOMIC_CAPTURE_NEW:
13149 85331 : case OMP_DEPOBJ:
13150 85331 : case OACC_PARALLEL:
13151 85331 : case OACC_KERNELS:
13152 85331 : case OACC_SERIAL:
13153 85331 : case OACC_DATA:
13154 85331 : case OACC_HOST_DATA:
13155 85331 : case OACC_LOOP:
13156 85331 : case OACC_CACHE:
13157 85331 : case OACC_DECLARE:
13158 85331 : case OACC_ENTER_DATA:
13159 85331 : case OACC_EXIT_DATA:
13160 85331 : case OACC_UPDATE:
13161 85331 : case OMP_ARRAY_SECTION:
13162 : /* GCC internal stuff. */
13163 85331 : case VA_ARG_EXPR:
13164 85331 : case TRANSACTION_EXPR:
13165 85331 : case AT_ENCODE_EXPR:
13166 85331 : fail:
13167 85331 : if (flags & tf_error)
13168 23 : constexpr_error (loc, fundef_p, "expression %qE is not a constant "
13169 : "expression", t);
13170 : return false;
13171 :
13172 : case OMP_DECLARE_MAPPER:
13173 : /* This can be used to initialize VAR_DECLs: it's treated as a magic
13174 : constant. */
13175 : return true;
13176 :
13177 26692 : case THROW_EXPR:
13178 26692 : if (cxx_dialect < cxx26)
13179 291 : goto fail;
13180 26401 : return RECUR (TREE_OPERAND (t, 0), rval);
13181 :
13182 531 : case ASM_EXPR:
13183 531 : if (flags & tf_error)
13184 6 : inline_asm_in_constexpr_error (loc, fundef_p);
13185 : return false;
13186 :
13187 543485 : case OBJ_TYPE_REF:
13188 543485 : if (cxx_dialect >= cxx20)
13189 : /* In C++20 virtual calls can be constexpr, don't give up yet. */
13190 : return true;
13191 9122 : else if (flags & tf_error)
13192 0 : constexpr_error (loc, fundef_p, "virtual functions cannot be "
13193 : "%<constexpr%> before C++20");
13194 : return false;
13195 :
13196 6599 : case TYPEID_EXPR:
13197 : /* In C++20, a typeid expression whose operand is of polymorphic
13198 : class type can be constexpr. */
13199 6599 : {
13200 6599 : tree e = TREE_OPERAND (t, 0);
13201 6599 : if (cxx_dialect < cxx20
13202 26 : && strict
13203 26 : && !TYPE_P (e)
13204 19 : && !type_dependent_expression_p (e)
13205 7 : && CLASS_TYPE_P (TREE_TYPE (e))
13206 6604 : && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
13207 : {
13208 4 : if (flags & tf_error)
13209 1 : constexpr_error (loc, fundef_p, "%<typeid%> is not a "
13210 : "constant expression because %qE is "
13211 : "of polymorphic type", e);
13212 : return false;
13213 : }
13214 : return true;
13215 : }
13216 :
13217 31475300 : case POINTER_DIFF_EXPR:
13218 31475300 : case MINUS_EXPR:
13219 31475300 : want_rval = true;
13220 31475300 : goto binary;
13221 :
13222 84611545 : case LT_EXPR:
13223 84611545 : case LE_EXPR:
13224 84611545 : case GT_EXPR:
13225 84611545 : case GE_EXPR:
13226 84611545 : case EQ_EXPR:
13227 84611545 : case NE_EXPR:
13228 84611545 : case SPACESHIP_EXPR:
13229 84611545 : want_rval = true;
13230 84611545 : goto binary;
13231 :
13232 2006159 : case PREINCREMENT_EXPR:
13233 2006159 : case POSTINCREMENT_EXPR:
13234 2006159 : case PREDECREMENT_EXPR:
13235 2006159 : case POSTDECREMENT_EXPR:
13236 2006159 : if (cxx_dialect < cxx14)
13237 9471 : goto fail;
13238 1996688 : goto unary;
13239 :
13240 1284894 : case BIT_NOT_EXPR:
13241 : /* A destructor. */
13242 1284894 : if (TYPE_P (TREE_OPERAND (t, 0)))
13243 : return true;
13244 : /* fall through. */
13245 :
13246 48650126 : case CONJ_EXPR:
13247 48650126 : case SAVE_EXPR:
13248 48650126 : case FIX_TRUNC_EXPR:
13249 48650126 : case FLOAT_EXPR:
13250 48650126 : case NEGATE_EXPR:
13251 48650126 : case ABS_EXPR:
13252 48650126 : case ABSU_EXPR:
13253 48650126 : case TRUTH_NOT_EXPR:
13254 48650126 : case FIXED_CONVERT_EXPR:
13255 48650126 : case UNARY_PLUS_EXPR:
13256 48650126 : case UNARY_LEFT_FOLD_EXPR:
13257 48650126 : case UNARY_RIGHT_FOLD_EXPR:
13258 48650126 : case VEC_DUPLICATE_EXPR:
13259 1284894 : unary:
13260 48650126 : return RECUR (TREE_OPERAND (t, 0), rval);
13261 :
13262 31749141 : case CAST_EXPR:
13263 31749141 : case CONST_CAST_EXPR:
13264 31749141 : case STATIC_CAST_EXPR:
13265 31749141 : case REINTERPRET_CAST_EXPR:
13266 31749141 : case IMPLICIT_CONV_EXPR:
13267 31749141 : if (!cast_valid_in_integral_constant_expression_p (TREE_TYPE (t)))
13268 : /* In C++98, a conversion to non-integral type can't be part of a
13269 : constant expression. */
13270 : {
13271 346 : if (flags & tf_error)
13272 0 : constexpr_error (loc, fundef_p,
13273 : "cast to non-integral type %qT in a constant "
13274 0 : "expression", TREE_TYPE (t));
13275 : return false;
13276 : }
13277 : /* This might be a conversion from a class to a (potentially) literal
13278 : type. Let's consider it potentially constant since the conversion
13279 : might be a constexpr user-defined conversion. */
13280 31748795 : else if (cxx_dialect >= cxx11
13281 31726246 : && (dependent_type_p (TREE_TYPE (t))
13282 11172788 : || !COMPLETE_TYPE_P (TREE_TYPE (t))
13283 11158064 : || literal_type_p (TREE_TYPE (t)))
13284 31688011 : && TREE_OPERAND (t, 0)
13285 63190417 : && (TREE_CODE (t) != CAST_EXPR
13286 23832985 : || !TREE_CHAIN (TREE_OPERAND (t, 0))))
13287 : {
13288 31398376 : tree from = TREE_OPERAND (t, 0);
13289 31398376 : if (TREE_CODE (t) == CAST_EXPR)
13290 23789739 : from = TREE_VALUE (from);
13291 31398376 : tree type = TREE_TYPE (from);
13292 : /* If this is a dependent type, it could end up being a class
13293 : with conversions. */
13294 31398376 : if (type == NULL_TREE || WILDCARD_TYPE_P (type))
13295 : return true;
13296 : /* Or a non-dependent class which has conversions. */
13297 595762 : else if (CLASS_TYPE_P (type)
13298 595762 : && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
13299 : return true;
13300 : }
13301 :
13302 25222333 : return (RECUR (TREE_OPERAND (t, 0),
13303 25222333 : !TYPE_REF_P (TREE_TYPE (t))));
13304 :
13305 14577736 : case BIND_EXPR:
13306 14577736 : return RECUR (BIND_EXPR_BODY (t), want_rval);
13307 :
13308 71503537 : case CLEANUP_POINT_EXPR:
13309 71503537 : case MUST_NOT_THROW_EXPR:
13310 71503537 : case TRY_CATCH_EXPR:
13311 : /* Even for C++26 handle TRY_BLOCK conservatively, if we detect the
13312 : body could throw, even with catch (...) among handlers we'd need
13313 : to analyze them in detail if they couldn't rethrow it. More
13314 : importantly though, throws (jump_target) is just conservative,
13315 : and there could be e.g.
13316 : try
13317 : {
13318 : possibly_throwing_fn (args);
13319 : break;
13320 : }
13321 : catch (...)
13322 : {
13323 : }
13324 : or continue or return instead of break. So, clearing *jump_target
13325 : because we see catch (...) handler might mean we missed break
13326 : etc. */
13327 71503537 : case TRY_BLOCK:
13328 71503537 : case EH_SPEC_BLOCK:
13329 71503537 : case EXPR_STMT:
13330 71503537 : case PAREN_EXPR:
13331 : /* For convenience. */
13332 71503537 : case LOOP_EXPR:
13333 71503537 : case EXIT_EXPR:
13334 71503537 : return RECUR (TREE_OPERAND (t, 0), want_rval);
13335 :
13336 13006049 : case DECL_EXPR:
13337 13006049 : tmp = DECL_EXPR_DECL (t);
13338 8632031 : if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)
13339 19078589 : && (processing_template_decl
13340 5587245 : ? !decl_maybe_constant_var_p (tmp)
13341 5101950 : : !decl_constant_var_p (tmp)))
13342 : {
13343 5022449 : if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
13344 : {
13345 8 : if (flags & tf_error)
13346 3 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
13347 : "%qD defined %<thread_local%> in "
13348 : "%<constexpr%> context", tmp);
13349 : return false;
13350 : }
13351 5022441 : else if (TREE_STATIC (tmp))
13352 : {
13353 142 : if (flags & tf_error)
13354 34 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
13355 : "%qD defined %<static%> in %<constexpr%> "
13356 : "context", tmp);
13357 : return false;
13358 : }
13359 5022299 : else if (!check_for_uninitialized_const_var
13360 5022299 : (tmp, /*constexpr_context_p=*/true, flags))
13361 : return false;
13362 : }
13363 13000954 : if (VAR_P (tmp))
13364 8626936 : return RECUR (DECL_INITIAL (tmp), want_rval);
13365 : return true;
13366 :
13367 43667 : case TRY_FINALLY_EXPR:
13368 43667 : return (RECUR (TREE_OPERAND (t, 0), want_rval)
13369 43667 : && RECUR (TREE_OPERAND (t, 1), any));
13370 :
13371 0 : case EH_ELSE_EXPR:
13372 : /* maybe_apply_function_contracts uses this to check postconditions only
13373 : on normal return. */
13374 0 : return (RECUR (TREE_OPERAND (t, 1), any)
13375 0 : || RECUR (TREE_OPERAND (t, 0), any));
13376 :
13377 24772272 : case SCOPE_REF:
13378 24772272 : return RECUR (TREE_OPERAND (t, 1), want_rval);
13379 :
13380 49808466 : case TARGET_EXPR:
13381 49808466 : if (!TARGET_EXPR_DIRECT_INIT_P (t)
13382 49599064 : && !TARGET_EXPR_ELIDING_P (t)
13383 89685414 : && !literal_type_p (TREE_TYPE (t)))
13384 : {
13385 905276 : if (flags & tf_error)
13386 : {
13387 25 : auto_diagnostic_group d;
13388 25 : if (constexpr_error (loc, fundef_p,
13389 : "temporary of non-literal type %qT in a "
13390 25 : "constant expression", TREE_TYPE (t)))
13391 25 : explain_non_literal_class (TREE_TYPE (t));
13392 25 : }
13393 : return false;
13394 : }
13395 : /* FALLTHRU */
13396 77728278 : case INIT_EXPR:
13397 77728278 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
13398 : return true;
13399 77607320 : return RECUR (TREE_OPERAND (t, 1), rval);
13400 :
13401 40101976 : case CONSTRUCTOR:
13402 40101976 : {
13403 40101976 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
13404 40101976 : constructor_elt *ce;
13405 5236396379 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
13406 234354936 : if (!RECUR (ce->value, want_rval))
13407 : return false;
13408 : return true;
13409 : }
13410 :
13411 21348607 : case TREE_LIST:
13412 21348607 : {
13413 21348607 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
13414 : || DECL_P (TREE_PURPOSE (t)));
13415 21348607 : if (!RECUR (TREE_VALUE (t), want_rval))
13416 : return false;
13417 19131945 : if (TREE_CHAIN (t) == NULL_TREE)
13418 : return true;
13419 55384 : return RECUR (TREE_CHAIN (t), want_rval);
13420 : }
13421 :
13422 15519952 : case TRUNC_DIV_EXPR:
13423 15519952 : case CEIL_DIV_EXPR:
13424 15519952 : case FLOOR_DIV_EXPR:
13425 15519952 : case ROUND_DIV_EXPR:
13426 15519952 : case TRUNC_MOD_EXPR:
13427 15519952 : case CEIL_MOD_EXPR:
13428 15519952 : case ROUND_MOD_EXPR:
13429 15519952 : {
13430 15519952 : tree denom = TREE_OPERAND (t, 1);
13431 15519952 : if (!RECUR (denom, rval))
13432 : return false;
13433 : /* We can't call cxx_eval_outermost_constant_expr on an expression
13434 : that hasn't been through instantiate_non_dependent_expr yet. */
13435 14996255 : if (!processing_template_decl)
13436 7959145 : denom = cxx_eval_outermost_constant_expr (denom, true);
13437 14996255 : if (integer_zerop (denom))
13438 : {
13439 377 : if (flags & tf_error)
13440 38 : constexpr_error (input_location, fundef_p,
13441 : "division by zero is not a constant expression");
13442 : return false;
13443 : }
13444 : else
13445 : {
13446 14995878 : want_rval = true;
13447 14995878 : return RECUR (TREE_OPERAND (t, 0), want_rval);
13448 : }
13449 : }
13450 :
13451 9758891 : case COMPOUND_EXPR:
13452 9758891 : {
13453 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
13454 : COMPOUND_EXPR; don't get confused. */
13455 9758891 : tree op0 = TREE_OPERAND (t, 0);
13456 9758891 : tree op1 = TREE_OPERAND (t, 1);
13457 9758891 : STRIP_NOPS (op1);
13458 9758891 : if (TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
13459 2737184 : return RECUR (op0, want_rval);
13460 : else
13461 7021707 : goto binary;
13462 : }
13463 :
13464 : /* If the first operand is the non-short-circuit constant, look at
13465 : the second operand; otherwise we only care about the first one for
13466 : potentiality. */
13467 18910479 : case TRUTH_AND_EXPR:
13468 18910479 : case TRUTH_ANDIF_EXPR:
13469 18910479 : tmp = boolean_true_node;
13470 18910479 : goto truth;
13471 7676753 : case TRUTH_OR_EXPR:
13472 7676753 : case TRUTH_ORIF_EXPR:
13473 7676753 : tmp = boolean_false_node;
13474 26587232 : truth:
13475 26587232 : {
13476 26587232 : tree op0 = TREE_OPERAND (t, 0);
13477 26587232 : tree op1 = TREE_OPERAND (t, 1);
13478 26587232 : if (!RECUR (op0, rval))
13479 : return false;
13480 18335680 : if (!(flags & tf_error) && RECUR (op1, rval))
13481 : /* When quiet, try to avoid expensive trial evaluation by first
13482 : checking potentiality of the second operand. */
13483 : return true;
13484 1849584 : if (!processing_template_decl)
13485 1445817 : op0 = cxx_eval_outermost_constant_expr (op0, true);
13486 1849584 : if (tree_int_cst_equal (op0, tmp))
13487 5203 : return (flags & tf_error) ? RECUR (op1, rval) : false;
13488 : else
13489 : return true;
13490 : }
13491 :
13492 : case PLUS_EXPR:
13493 : case MULT_EXPR:
13494 : case POINTER_PLUS_EXPR:
13495 : case RDIV_EXPR:
13496 : case EXACT_DIV_EXPR:
13497 : case MIN_EXPR:
13498 : case MAX_EXPR:
13499 : case LSHIFT_EXPR:
13500 : case RSHIFT_EXPR:
13501 : case LROTATE_EXPR:
13502 : case RROTATE_EXPR:
13503 : case BIT_IOR_EXPR:
13504 : case BIT_XOR_EXPR:
13505 : case BIT_AND_EXPR:
13506 : case TRUTH_XOR_EXPR:
13507 : case UNORDERED_EXPR:
13508 : case ORDERED_EXPR:
13509 : case UNLT_EXPR:
13510 : case UNLE_EXPR:
13511 : case UNGT_EXPR:
13512 : case UNGE_EXPR:
13513 : case UNEQ_EXPR:
13514 : case LTGT_EXPR:
13515 : case RANGE_EXPR:
13516 : case COMPLEX_EXPR:
13517 237201602 : want_rval = true;
13518 : /* Fall through. */
13519 249536765 : case ARRAY_REF:
13520 249536765 : case ARRAY_RANGE_REF:
13521 249536765 : case MEMBER_REF:
13522 249536765 : case DOTSTAR_EXPR:
13523 249536765 : case MEM_REF:
13524 249536765 : case BINARY_LEFT_FOLD_EXPR:
13525 249536765 : case BINARY_RIGHT_FOLD_EXPR:
13526 249536765 : binary:
13527 548119364 : for (i = 0; i < 2; ++i)
13528 406090799 : if (!RECUR (TREE_OPERAND (t, i), want_rval))
13529 : return false;
13530 : return true;
13531 :
13532 : case VEC_PERM_EXPR:
13533 121529 : for (i = 0; i < 3; ++i)
13534 120583 : if (!RECUR (TREE_OPERAND (t, i), true))
13535 : return false;
13536 : return true;
13537 :
13538 7567255 : case COND_EXPR:
13539 7567255 : if (COND_EXPR_IS_VEC_DELETE (t) && cxx_dialect < cxx20)
13540 : {
13541 8 : if (flags & tf_error)
13542 2 : constexpr_error (loc, fundef_p, "%<delete[]%> is not a "
13543 : "constant expression");
13544 : return false;
13545 : }
13546 : /* Fall through. */
13547 18317624 : case IF_STMT:
13548 18317624 : case VEC_COND_EXPR:
13549 : /* If the condition is a known constant, we know which of the legs we
13550 : care about; otherwise we only require that the condition and
13551 : either of the legs be potentially constant. */
13552 18317624 : tmp = TREE_OPERAND (t, 0);
13553 18317624 : if (!RECUR (tmp, rval))
13554 : return false;
13555 15998455 : if (!processing_template_decl)
13556 13990893 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
13557 : /* potential_constant_expression* isn't told if it is called for
13558 : manifestly_const_eval or not, so for consteval if always
13559 : process both branches as if the condition is not a known
13560 : constant. */
13561 15998455 : if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
13562 : {
13563 15921813 : if (integer_zerop (tmp))
13564 3451120 : return RECUR (TREE_OPERAND (t, 2), want_rval);
13565 12470693 : else if (TREE_CODE (tmp) == INTEGER_CST)
13566 3817646 : return RECUR (TREE_OPERAND (t, 1), want_rval);
13567 : }
13568 8729689 : tmp = *jump_target;
13569 10090189 : for (i = 1; i < 3; ++i)
13570 : {
13571 9940139 : tree this_jump_target = tmp;
13572 9940139 : if (potential_constant_expression_1 (TREE_OPERAND (t, i),
13573 : want_rval, strict, now, fundef_p,
13574 : tf_none, &this_jump_target))
13575 : {
13576 8877740 : if (returns (&this_jump_target) || throws (&this_jump_target))
13577 2477253 : *jump_target = this_jump_target;
13578 6102386 : else if (!returns (jump_target) && !throws (jump_target))
13579 : {
13580 6102386 : if (breaks (&this_jump_target)
13581 6102386 : || continues (&this_jump_target))
13582 45 : *jump_target = this_jump_target;
13583 6102386 : if (i == 1)
13584 : {
13585 : /* If the then branch is potentially constant, but
13586 : does not return, check if the else branch
13587 : couldn't return, break or continue. */
13588 5042659 : hash_set<tree> pset;
13589 5042659 : check_for_return_continue_data data = { &pset, NULL_TREE,
13590 : NULL_TREE,
13591 5042659 : false };
13592 10085318 : if (tree ret_expr
13593 5042659 : = cp_walk_tree (&TREE_OPERAND (t, 2),
13594 : check_for_return_continue, &data,
13595 : &pset))
13596 80715 : *jump_target = ret_expr;
13597 4961944 : else if (*jump_target == NULL_TREE)
13598 : {
13599 4961902 : if (data.continue_stmt)
13600 0 : *jump_target = data.continue_stmt;
13601 4961902 : else if (data.break_stmt)
13602 13 : *jump_target = data.break_stmt;
13603 : }
13604 5042659 : if (data.could_throw)
13605 54507 : *jump_target = void_node;
13606 5042659 : }
13607 : }
13608 8579639 : return true;
13609 : }
13610 : }
13611 150050 : if (flags & tf_error)
13612 : {
13613 3 : if (TREE_CODE (t) == IF_STMT)
13614 3 : constexpr_error (loc, fundef_p, "neither branch of %<if%> is a "
13615 : "constant expression");
13616 : else
13617 0 : constexpr_error (loc, fundef_p, "expression %qE is not a "
13618 : "constant expression", t);
13619 : }
13620 : return false;
13621 :
13622 1742 : case VEC_INIT_EXPR:
13623 1742 : if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
13624 : return true;
13625 868 : if (flags & tf_error)
13626 : {
13627 3 : if (constexpr_error (loc, fundef_p, "non-constant array "
13628 : "initialization"))
13629 2 : diagnose_non_constexpr_vec_init (t);
13630 : }
13631 : return false;
13632 :
13633 : case TYPE_DECL:
13634 : case TAG_DEFN:
13635 : /* We can see these in statement-expressions. */
13636 : return true;
13637 :
13638 1498318 : case CLEANUP_STMT:
13639 1498318 : if (!RECUR (CLEANUP_BODY (t), any))
13640 : return false;
13641 2502700 : if (!CLEANUP_EH_ONLY (t) && !RECUR (CLEANUP_EXPR (t), any))
13642 : return false;
13643 : return true;
13644 :
13645 : case EMPTY_CLASS_EXPR:
13646 : return true;
13647 :
13648 128 : case GOTO_EXPR:
13649 128 : {
13650 128 : tree *target = &TREE_OPERAND (t, 0);
13651 : /* Gotos representing break, continue and cdtor return are OK. */
13652 128 : if (breaks (target) || continues (target) || returns (target))
13653 : {
13654 108 : *jump_target = *target;
13655 108 : return true;
13656 : }
13657 20 : if (TREE_CODE (*target) == LABEL_DECL && DECL_ARTIFICIAL (*target))
13658 : /* The user didn't write this goto, this isn't the problem. */
13659 : return true;
13660 16 : if (flags & tf_error)
13661 3 : constexpr_error (loc, fundef_p, "%<goto%> is not a constant "
13662 : "expression");
13663 : return false;
13664 : }
13665 :
13666 : case ASSERTION_STMT:
13667 : case PRECONDITION_STMT:
13668 : case POSTCONDITION_STMT:
13669 : /* Contracts are not supposed to alter this; we have to check that this
13670 : is not violated at a later time. */
13671 : return true;
13672 :
13673 228 : case LABEL_EXPR:
13674 228 : t = LABEL_EXPR_LABEL (t);
13675 228 : if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
13676 : return true;
13677 25 : else if (flags & tf_error)
13678 5 : constexpr_error (loc, fundef_p, "label definition in %<constexpr%> "
13679 : "function only available with %<-std=c++23%> or "
13680 : "%<-std=gnu++23%>");
13681 : return false;
13682 :
13683 10318 : case ANNOTATE_EXPR:
13684 10318 : return RECUR (TREE_OPERAND (t, 0), rval);
13685 :
13686 188709 : case BIT_CAST_EXPR:
13687 188709 : return RECUR (TREE_OPERAND (t, 0), rval);
13688 :
13689 : /* Coroutine await, yield and return expressions are not. */
13690 768 : case CO_AWAIT_EXPR:
13691 768 : case CO_YIELD_EXPR:
13692 768 : case CO_RETURN_EXPR:
13693 768 : case TEMPLATE_FOR_STMT:
13694 768 : if (flags & tf_error)
13695 3 : constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p,
13696 : "%qE is not a constant expression", t);
13697 : return false;
13698 :
13699 : /* Assume a TU-local entity is not constant, we'll error later when
13700 : instantiating. */
13701 : case TU_LOCAL_ENTITY:
13702 : return false;
13703 :
13704 : /* A splice expression is dependent, but will be constant after
13705 : substitution. */
13706 : case SPLICE_EXPR:
13707 : return true;
13708 :
13709 30 : case NONTYPE_ARGUMENT_PACK:
13710 30 : {
13711 30 : tree args = ARGUMENT_PACK_ARGS (t);
13712 30 : int len = TREE_VEC_LENGTH (args);
13713 90 : for (int i = 0; i < len; ++i)
13714 60 : if (!RECUR (TREE_VEC_ELT (args, i), any))
13715 : return false;
13716 : return true;
13717 : }
13718 :
13719 0 : default:
13720 0 : if (objc_non_constant_expr_p (t))
13721 : return false;
13722 :
13723 0 : sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
13724 0 : gcc_unreachable ();
13725 : return false;
13726 : }
13727 : #undef RECUR
13728 4963232489 : }
13729 :
13730 : bool
13731 1777656030 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
13732 : bool fundef_p, tsubst_flags_t flags)
13733 : {
13734 1777656030 : if (flags & tf_error)
13735 : {
13736 : /* Check potentiality quietly first, as that could be performed more
13737 : efficiently in some cases (currently only for TRUTH_*_EXPR). If
13738 : that fails, replay the check noisily to give errors. */
13739 11132843 : flags &= ~tf_error;
13740 11132843 : if (potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13741 : flags))
13742 : return true;
13743 1073 : flags |= tf_error;
13744 : }
13745 :
13746 1766524260 : tree target = NULL_TREE;
13747 1766524260 : return potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13748 1766524260 : flags, &target);
13749 : }
13750 :
13751 : /* The main entry point to the above. */
13752 :
13753 : bool
13754 452748750 : potential_constant_expression (tree t)
13755 : {
13756 452748750 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13757 : /*now*/false, /*fundef_p*/false,
13758 452748750 : tf_none);
13759 : }
13760 :
13761 : /* As above, but require a constant rvalue. */
13762 :
13763 : bool
13764 35758414 : potential_rvalue_constant_expression (tree t)
13765 : {
13766 35758414 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13767 : /*now*/false, /*fundef_p*/false,
13768 35758414 : tf_none);
13769 : }
13770 :
13771 : /* Like above, but complain about non-constant expressions. */
13772 :
13773 : bool
13774 88 : require_potential_constant_expression (tree t)
13775 : {
13776 88 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13777 : /*now*/false, /*fundef_p*/false,
13778 88 : tf_warning_or_error);
13779 : }
13780 :
13781 : /* Cross product of the above. */
13782 :
13783 : bool
13784 133116 : require_potential_rvalue_constant_expression (tree t)
13785 : {
13786 133116 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13787 : /*now*/false, /*fundef_p*/false,
13788 133116 : tf_warning_or_error);
13789 : }
13790 :
13791 : /* Like require_potential_rvalue_constant_expression, but fundef_p is true. */
13792 :
13793 : bool
13794 290 : require_potential_rvalue_constant_expression_fncheck (tree t)
13795 : {
13796 290 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13797 : /*now*/false, /*fundef_p*/true,
13798 290 : tf_warning_or_error);
13799 : }
13800 :
13801 : /* Like above, but don't consider PARM_DECL a potential_constant_expression. */
13802 :
13803 : bool
13804 1143 : require_rvalue_constant_expression (tree t)
13805 : {
13806 1143 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13807 : /*now*/true, /*fundef_p*/false,
13808 1143 : tf_warning_or_error);
13809 : }
13810 :
13811 : /* Like potential_constant_expression, but don't consider possible constexpr
13812 : substitution of the current function. That is, PARM_DECL qualifies under
13813 : potential_constant_expression, but not here.
13814 :
13815 : This is basically what you can check when any actual constant values might
13816 : be value-dependent. */
13817 :
13818 : bool
13819 933888316 : is_constant_expression (tree t)
13820 : {
13821 933888316 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13822 : /*now*/true, /*fundef_p*/false,
13823 933888316 : tf_none);
13824 : }
13825 :
13826 : /* As above, but expect an rvalue. */
13827 :
13828 : bool
13829 157183189 : is_rvalue_constant_expression (tree t)
13830 : {
13831 157183189 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13832 : /*now*/true, /*fundef_p*/false,
13833 157183189 : tf_none);
13834 : }
13835 :
13836 : /* Like above, but complain about non-constant expressions. */
13837 :
13838 : bool
13839 10998206 : require_constant_expression (tree t)
13840 : {
13841 10998206 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13842 : /*now*/true, /*fundef_p*/false,
13843 10998206 : tf_warning_or_error);
13844 : }
13845 :
13846 : /* Like is_constant_expression, but allow const variables that are not allowed
13847 : under constexpr rules. */
13848 :
13849 : bool
13850 175811675 : is_static_init_expression (tree t)
13851 : {
13852 175811675 : return potential_constant_expression_1 (t, /*want_rval*/false,
13853 : /*strict*/false, /*now*/true,
13854 175811675 : /*fundef_p*/false, tf_none);
13855 : }
13856 :
13857 : /* Returns true if T is a potential constant expression that is not
13858 : instantiation-dependent, and therefore a candidate for constant folding even
13859 : in a template. */
13860 :
13861 : bool
13862 901855448 : is_nondependent_constant_expression (tree t)
13863 : {
13864 901855448 : return (!type_unknown_p (t)
13865 901855398 : && is_constant_expression (t)
13866 1692238923 : && !instantiation_dependent_expression_p (t));
13867 : }
13868 :
13869 : /* Returns true if T is a potential static initializer expression that is not
13870 : instantiation-dependent. */
13871 :
13872 : bool
13873 175811675 : is_nondependent_static_init_expression (tree t)
13874 : {
13875 175811675 : return (!type_unknown_p (t)
13876 175811675 : && is_static_init_expression (t)
13877 317889546 : && !instantiation_dependent_expression_p (t));
13878 : }
13879 :
13880 : /* True iff FN is an implicitly constexpr function. */
13881 :
13882 : bool
13883 465994 : decl_implicit_constexpr_p (tree fn)
13884 : {
13885 465994 : if (!(flag_implicit_constexpr
13886 3 : && TREE_CODE (fn) == FUNCTION_DECL
13887 3 : && DECL_DECLARED_CONSTEXPR_P (fn)))
13888 : return false;
13889 :
13890 3 : if (DECL_CLONED_FUNCTION_P (fn))
13891 0 : fn = DECL_CLONED_FUNCTION (fn);
13892 :
13893 3 : return (DECL_LANG_SPECIFIC (fn)
13894 3 : && DECL_LANG_SPECIFIC (fn)->u.fn.implicit_constexpr);
13895 : }
13896 :
13897 : /* Finalize constexpr processing after parsing. */
13898 :
13899 : void
13900 99724 : fini_constexpr (void)
13901 : {
13902 : /* The contexpr call and fundef copies tables are no longer needed. */
13903 99724 : constexpr_call_table = NULL;
13904 99724 : fundef_copies_table = NULL;
13905 99724 : }
13906 :
13907 : #include "gt-cp-constexpr.h"
|