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 234731579 : is_instantiation_of_constexpr (tree fun)
62 : {
63 311825213 : return ((DECL_TEMPLOID_INSTANTIATION (fun)
64 159158504 : && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
65 341424881 : || (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 202889956 : literal_type_p (tree t)
73 : {
74 199476179 : if (SCALAR_TYPE_P (t)
75 98428827 : || VECTOR_TYPE_P (t)
76 98408204 : || TYPE_REF_P (t)
77 284852608 : || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
78 : return true;
79 76585469 : if (CLASS_TYPE_P (t))
80 : {
81 75081208 : t = complete_type (t);
82 75081208 : gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
83 75081208 : return CLASSTYPE_LITERAL_P (t);
84 : }
85 1504261 : if (TREE_CODE (t) == ARRAY_TYPE)
86 1504074 : 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 329225487 : ensure_literal_type_for_constexpr_object (tree decl)
96 : {
97 329225487 : tree type = TREE_TYPE (decl);
98 329225487 : if (VAR_P (decl)
99 131128181 : && (DECL_DECLARED_CONSTEXPR_P (decl)
100 90860791 : || var_in_constexpr_fn (decl))
101 388791590 : && !processing_template_decl)
102 : {
103 41444043 : tree stype = strip_array_types (type);
104 41444043 : 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 41444037 : else if (!literal_type_p (type))
108 : {
109 23822 : 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 23769 : else if (cxx_dialect < cxx23)
119 : {
120 18041 : 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 18041 : cp_function_chain->invalid_constexpr = true;
131 : }
132 : }
133 41420215 : else if (DECL_DECLARED_CONSTEXPR_P (decl)
134 41420215 : && 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 329225487 : 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 961 : constexpr_error (location_t location, bool constexpr_fundef_p,
155 : const char *gmsgid, ...)
156 : {
157 961 : diagnostics::diagnostic_info diagnostic;
158 961 : va_list ap;
159 961 : rich_location richloc (line_table, location);
160 961 : va_start (ap, gmsgid);
161 961 : bool ret;
162 961 : if (!constexpr_fundef_p)
163 : {
164 : /* Report an error that cannot be suppressed. */
165 699 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
166 : diagnostics::kind::error);
167 699 : ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
168 : }
169 262 : else if (warn_invalid_constexpr)
170 : {
171 148 : diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
172 148 : (cxx_dialect < cxx23
173 : ? diagnostics::kind::pedwarn
174 : : diagnostics::kind::warning));
175 148 : diagnostic.m_option_id = OPT_Winvalid_constexpr;
176 148 : ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
177 : }
178 : else
179 : ret = false;
180 961 : va_end (ap);
181 1922 : return ret;
182 961 : }
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 844503652 : constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
201 : const constexpr_fundef *rhs)
202 : {
203 817359821 : 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 827905938 : constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
211 : {
212 827905938 : return DECL_UID (fundef->decl);
213 : }
214 :
215 : /* Return a previously saved definition of function FUN. */
216 :
217 : constexpr_fundef *
218 98314910 : retrieve_constexpr_fundef (tree fun)
219 : {
220 98314910 : if (constexpr_fundef_table == NULL)
221 : return NULL;
222 :
223 98311050 : constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
224 98311050 : 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 34250764 : is_valid_constexpr_fn (tree fun, bool complain)
232 : {
233 34250764 : bool ret = true;
234 :
235 68501528 : if (DECL_INHERITED_CTOR (fun)
236 4128030 : && 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 34250764 : for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
246 68065565 : parm != NULL_TREE; parm = TREE_CHAIN (parm))
247 33814801 : if (!literal_type_p (TREE_TYPE (parm)))
248 : {
249 13331 : ret = false;
250 13331 : if (complain)
251 : {
252 22 : auto_diagnostic_group d;
253 22 : if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
254 : "invalid type for parameter %d of "
255 : "%<constexpr%> function %q+#D",
256 22 : DECL_PARM_INDEX (parm), fun))
257 14 : explain_non_literal_class (TREE_TYPE (parm));
258 22 : }
259 : }
260 : }
261 :
262 57840571 : if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun)) && cxx_dialect < cxx17)
263 : {
264 3 : ret = false;
265 3 : if (complain)
266 3 : inform (DECL_SOURCE_LOCATION (fun),
267 : "lambdas are implicitly %<constexpr%> only in C++17 and later");
268 : }
269 68501522 : 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 34250761 : else if (!DECL_CONSTRUCTOR_P (fun) && !DECL_DESTRUCTOR_P (fun))
278 : {
279 29401583 : tree rettype = TREE_TYPE (TREE_TYPE (fun));
280 29401583 : if (!literal_type_p (rettype))
281 : {
282 50286 : ret = false;
283 50286 : if (complain)
284 : {
285 13 : auto_diagnostic_group d;
286 13 : if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
287 : "invalid return type %qT of %<constexpr%> "
288 : "function %q+D", rettype, fun))
289 9 : explain_non_literal_class (rettype);
290 13 : }
291 : }
292 :
293 : /* C++14 DR 1684 removed this restriction. */
294 29401583 : if (cxx_dialect < cxx14
295 31480 : && DECL_IOBJ_MEMBER_FUNCTION_P (fun)
296 29402672 : && !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 4849178 : 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 34250764 : 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 898 : 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 898 : auto_vec<tree, 2> fields;
344 1892 : do
345 : {
346 1892 : fields.safe_push (TREE_OPERAND (member, 1));
347 1892 : member = TREE_OPERAND (member, 0);
348 : }
349 1892 : while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
350 3790 : && 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 1892 : while (field = fields.pop(),
357 1892 : ANON_AGGR_TYPE_P (TREE_TYPE (field)))
358 : {
359 994 : tree ctor;
360 : /* If there is already an outer constructor entry for the anonymous
361 : aggregate FIELD, use it; otherwise, insert one. */
362 994 : if (vec_safe_is_empty (*vec)
363 198 : || (*vec)->last().index != field)
364 : {
365 892 : ctor = build_constructor (TREE_TYPE (field), NULL);
366 892 : CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
367 : }
368 : else
369 102 : ctor = (*vec)->last().value;
370 994 : 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 898 : gcc_assert (fields.is_empty());
376 898 : CONSTRUCTOR_APPEND_ELT (*vec, field, init);
377 :
378 898 : return true;
379 898 : }
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 6822807 : build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
389 : {
390 7476836 : tree member, init;
391 7476836 : if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
392 3556849 : t = TREE_OPERAND (t, 0);
393 7476836 : if (TREE_CODE (t) == EXPR_STMT)
394 3555995 : t = TREE_OPERAND (t, 0);
395 7476836 : if (t == error_mark_node)
396 : return false;
397 7476827 : if (TREE_CODE (t) == STATEMENT_LIST)
398 : {
399 8335505 : for (tree stmt : tsi_range (t))
400 862478 : if (! build_data_member_initialization (stmt, vec))
401 9 : return false;
402 : return true;
403 : }
404 6826598 : 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 616562 : return build_data_member_initialization (CLEANUP_BODY (t), vec);
412 : }
413 6210036 : if (TREE_CODE (t) == CONVERT_EXPR)
414 3515988 : t = TREE_OPERAND (t, 0);
415 6210036 : if (TREE_CODE (t) == INIT_EXPR)
416 : {
417 3342075 : member = TREE_OPERAND (t, 0);
418 3342075 : init = break_out_target_exprs (TREE_OPERAND (t, 1));
419 : }
420 2867961 : else if (TREE_CODE (t) == CALL_EXPR)
421 : {
422 2320905 : tree fn = get_callee_fndecl (t);
423 4641810 : if (!fn || !DECL_CONSTRUCTOR_P (fn))
424 : /* We're only interested in calls to subobject constructors. */
425 : return true;
426 1917801 : 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 1917801 : init = break_out_target_exprs (t);
431 : }
432 547056 : else if (TREE_CODE (t) == BIND_EXPR)
433 37467 : 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 5259876 : if (INDIRECT_REF_P (member))
438 58075 : member = TREE_OPERAND (member, 0);
439 5259876 : if (TREE_CODE (member) == NOP_EXPR)
440 : {
441 519547 : tree op = member;
442 519547 : STRIP_NOPS (op);
443 519547 : if (TREE_CODE (op) == ADDR_EXPR)
444 : {
445 564 : 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 518983 : else if (op == current_class_ptr
453 1037835 : && (same_type_ignoring_top_level_qualifiers_p
454 518852 : (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 448217 : gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
463 : }
464 : }
465 5259876 : if (TREE_CODE (member) == ADDR_EXPR)
466 1456893 : member = TREE_OPERAND (member, 0);
467 5259876 : if (TREE_CODE (member) == COMPONENT_REF)
468 : {
469 4709538 : tree aggr = TREE_OPERAND (member, 0);
470 4709538 : if (TREE_CODE (aggr) == VAR_DECL)
471 : /* Initializing a local variable, don't add anything. */
472 : return true;
473 4709536 : if (TREE_CODE (aggr) != COMPONENT_REF)
474 : /* Normal member initialization. */
475 4708635 : member = TREE_OPERAND (member, 1);
476 901 : else if (VAR_P (get_base_address (aggr)))
477 : /* Initializing a local variable, don't add anything. */
478 : return true;
479 898 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
480 : /* Initializing a member of an anonymous union. */
481 898 : 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 6653485 : if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
491 50 : (*vec)->last().value = init;
492 : else
493 5258923 : 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 2394 : check_constexpr_bind_expr_vars (tree t)
503 : {
504 2394 : gcc_assert (TREE_CODE (t) == BIND_EXPR);
505 :
506 3216 : for (tree var = BIND_EXPR_VARS (t); var; var = DECL_CHAIN (var))
507 834 : if (TREE_CODE (var) == TYPE_DECL
508 815 : && DECL_IMPLICIT_TYPEDEF_P (var)
509 856 : && !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 4133 : check_constexpr_ctor_body_1 (tree last, tree list)
518 : {
519 4133 : 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 2057 : case BIND_EXPR:
532 2057 : if (!check_constexpr_bind_expr_vars (list)
533 2057 : || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list),
534 : /*complain=*/false))
535 42 : 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 5405179 : 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 5405179 : if (cxx_dialect >= cxx14)
556 : return true;
557 :
558 13621 : bool ok = true;
559 13621 : if (TREE_CODE (list) == STATEMENT_LIST)
560 : {
561 13595 : tree_stmt_iterator i = tsi_last (list);
562 17633 : for (; !tsi_end_p (i); tsi_prev (&i))
563 : {
564 15510 : tree t = tsi_stmt (i);
565 15510 : if (t == last)
566 : break;
567 4107 : if (!check_constexpr_ctor_body_1 (last, t))
568 : {
569 : ok = false;
570 : break;
571 : }
572 : }
573 : }
574 26 : else if (list != last
575 26 : && !check_constexpr_ctor_body_1 (last, list))
576 : ok = false;
577 13621 : if (!ok && complain)
578 : {
579 48 : pedwarn (input_location, OPT_Wc__14_extensions,
580 : "%<constexpr%> constructor does not have empty body");
581 48 : 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 4056413 : sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
594 : {
595 4056413 : tree pri = CLASSTYPE_PRIMARY_BINFO (type);
596 4056413 : tree field_type;
597 4056413 : unsigned i;
598 4056413 : constructor_elt *ce;
599 :
600 4056413 : if (pri)
601 75565 : field_type = BINFO_TYPE (pri);
602 3980848 : else if (TYPE_CONTAINS_VPTR_P (type))
603 51987 : 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 184212 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
610 132105 : if (TREE_TYPE (ce->index) == field_type)
611 : break;
612 :
613 165766 : if (i > 0 && i < vec_safe_length (v))
614 : {
615 22 : vec<constructor_elt, va_gc> &vref = *v;
616 22 : constructor_elt elt = vref[i];
617 44 : for (; i > 0; --i)
618 22 : vref[i] = vref[i-1];
619 22 : 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 4127166 : build_constexpr_constructor_member_initializers (tree type, tree body)
630 : {
631 4127166 : vec<constructor_elt, va_gc> *vec = NULL;
632 4127166 : bool ok = true;
633 6222102 : while (true)
634 6222102 : switch (TREE_CODE (body))
635 : {
636 2094870 : case MUST_NOT_THROW_EXPR:
637 2094870 : case EH_SPEC_BLOCK:
638 2094870 : case TRY_FINALLY_EXPR: // For C++26 postconditions.
639 2094870 : body = TREE_OPERAND (body, 0);
640 2094870 : break;
641 :
642 66 : case STATEMENT_LIST:
643 6222187 : for (tree stmt : tsi_range (body))
644 : {
645 135 : body = stmt;
646 135 : if (TREE_CODE (body) == BIND_EXPR)
647 : break;
648 : }
649 : break;
650 :
651 4127166 : case BIND_EXPR:
652 4127166 : body = BIND_EXPR_BODY (body);
653 4127166 : goto found;
654 :
655 0 : default:
656 0 : gcc_unreachable ();
657 : }
658 4127166 : found:
659 4127166 : if (TREE_CODE (body) == TRY_BLOCK)
660 : {
661 29 : body = TREE_OPERAND (body, 0);
662 29 : if (TREE_CODE (body) == BIND_EXPR)
663 29 : body = BIND_EXPR_BODY (body);
664 : }
665 4127166 : if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
666 : {
667 2280967 : body = TREE_OPERAND (body, 0);
668 2280967 : if (TREE_CODE (body) == EXPR_STMT)
669 2280963 : body = TREE_OPERAND (body, 0);
670 2280967 : if (TREE_CODE (body) == INIT_EXPR
671 2280967 : && (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 2280967 : ok = build_data_member_initialization (body, &vec);
679 : }
680 1846199 : else if (TREE_CODE (body) == STATEMENT_LIST)
681 : {
682 5519120 : for (tree stmt : tsi_range (body))
683 : {
684 3676142 : ok = build_data_member_initialization (stmt, &vec);
685 3676142 : if (!ok)
686 : break;
687 : }
688 : }
689 3220 : else if (EXPR_P (body))
690 3220 : ok = build_data_member_initialization (body, &vec);
691 : else
692 0 : gcc_assert (errorcount > 0);
693 4127166 : if (ok)
694 : {
695 4127157 : if (vec_safe_length (vec) > 0)
696 : {
697 : /* In a delegating constructor, return the target. */
698 3865233 : constructor_elt *ce = &(*vec)[0];
699 3865233 : if (ce->index == current_class_ptr)
700 : {
701 70744 : body = ce->value;
702 70744 : vec_free (vec);
703 70744 : return body;
704 : }
705 : }
706 4056413 : vec = sort_constexpr_mem_initializers (type, vec);
707 4056413 : 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 602267573 : get_function_named_in_call (tree t)
719 : {
720 602267573 : tree callee = cp_get_callee (t);
721 602267573 : tree fun = cp_get_fndecl_from_callee (callee, /*fold*/false);
722 602267573 : 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 68587 : constexpr_fn_retval (tree body)
732 : {
733 75113 : switch (TREE_CODE (body))
734 : {
735 18518 : case STATEMENT_LIST:
736 18518 : {
737 18518 : tree expr = NULL_TREE;
738 55484 : for (tree stmt : tsi_range (body))
739 : {
740 36995 : tree s = constexpr_fn_retval (stmt);
741 36995 : if (s == error_mark_node)
742 : return error_mark_node;
743 36968 : else if (s == NULL_TREE)
744 : /* Keep iterating. */;
745 18483 : else if (expr)
746 : /* Multiple return statements. */
747 : return error_mark_node;
748 : else
749 : expr = s;
750 : }
751 : return expr;
752 : }
753 :
754 31542 : case RETURN_EXPR:
755 31542 : 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 6195 : case CLEANUP_POINT_EXPR:
768 6195 : return constexpr_fn_retval (TREE_OPERAND (body, 0));
769 :
770 337 : case BIND_EXPR:
771 337 : if (!check_constexpr_bind_expr_vars (body))
772 6 : return error_mark_node;
773 331 : 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 32829708 : massage_constexpr_body (tree fun, tree body)
799 : {
800 65659416 : if (DECL_CONSTRUCTOR_P (fun))
801 4127166 : body = build_constexpr_constructor_member_initializers
802 4127166 : (DECL_CONTEXT (fun), body);
803 28702542 : else if (cxx_dialect < cxx14)
804 : {
805 31357 : if (TREE_CODE (body) == EH_SPEC_BLOCK)
806 1 : body = EH_SPEC_STMTS (body);
807 31357 : if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
808 20268 : body = TREE_OPERAND (body, 0);
809 31357 : body = constexpr_fn_retval (body);
810 : }
811 32829708 : 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 3449867 : cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
819 : {
820 : /* We allow uninitialized bases/fields in C++20. */
821 3449867 : if (cxx_dialect >= cxx20)
822 : return false;
823 :
824 13332 : unsigned nelts = 0;
825 :
826 13332 : if (body)
827 : {
828 13328 : if (TREE_CODE (body) != CONSTRUCTOR)
829 : return false;
830 13277 : nelts = CONSTRUCTOR_NELTS (body);
831 : }
832 13281 : tree field = TYPE_FIELDS (ctype);
833 :
834 13281 : if (TREE_CODE (ctype) == UNION_TYPE)
835 : {
836 109 : 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 2 : return true;
842 : }
843 107 : 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 28028 : for (unsigned i = 0; i <= nelts; ++i)
850 : {
851 28028 : tree index = NULL_TREE;
852 28028 : if (i < nelts)
853 : {
854 14856 : index = CONSTRUCTOR_ELT (body, i)->index;
855 : /* Skip vptr adjustment represented with a COMPONENT_REF. */
856 14856 : if (TREE_CODE (index) != FIELD_DECL)
857 602 : continue;
858 : }
859 :
860 481006 : for (; field != index; field = DECL_CHAIN (field))
861 : {
862 453586 : tree ftype;
863 453586 : if (TREE_CODE (field) != FIELD_DECL)
864 905372 : continue;
865 1772 : if (DECL_UNNAMED_BIT_FIELD (field))
866 10 : continue;
867 : /* Artificial fields can be ignored unless they're bases. */
868 1762 : if (DECL_ARTIFICIAL (field) && !DECL_FIELD_IS_BASE (field))
869 6 : continue;
870 1756 : 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 1752 : ftype = TREE_TYPE (field);
880 1752 : if (!ftype || !TYPE_P (ftype) || !COMPLETE_TYPE_P (ftype))
881 : /* A flexible array can't be intialized here, so don't complain
882 : that it isn't. */
883 1 : continue;
884 1751 : if (is_empty_field (field))
885 : /* An empty field doesn't need an initializer. */
886 1716 : 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 27420 : if (field == NULL_TREE)
906 : break;
907 :
908 14254 : if (ANON_AGGR_TYPE_P (TREE_TYPE (index)))
909 : {
910 : /* Check the anonymous aggregate initializer is valid. */
911 76 : 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 14254 : 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 apropriate requirements and
924 : enter it in the constexpr function definition table. */
925 :
926 : void
927 165485805 : maybe_save_constexpr_fundef (tree fun)
928 : {
929 165485805 : if (processing_template_decl
930 73522837 : || cp_function_chain->invalid_constexpr
931 238990676 : || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
932 132656360 : 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 56334003 : bool implicit = false;
937 56334003 : if (flag_implicit_constexpr)
938 : {
939 19 : if (DECL_DELETING_DESTRUCTOR_P (fun)
940 19 : && 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 19 : if (!DECL_DECLARED_CONSTEXPR_P (fun)
946 16 : && DECL_DECLARED_INLINE_P (fun)
947 31 : && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fun)))
948 : implicit = true;
949 : }
950 :
951 56334003 : if (!DECL_DECLARED_CONSTEXPR_P (fun) && !implicit)
952 : return;
953 :
954 32884532 : bool complain = !DECL_GENERATED_P (fun) && !implicit;
955 :
956 32884532 : if (!is_valid_constexpr_fn (fun, complain))
957 : return;
958 :
959 32829645 : tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
960 32829645 : 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 36 : return;
966 : }
967 :
968 32829609 : bool potential = potential_rvalue_constant_expression (massaged);
969 32829609 : if (!potential && complain)
970 226 : require_potential_rvalue_constant_expression_fncheck (massaged);
971 :
972 36956754 : if (DECL_CONSTRUCTOR_P (fun) && potential
973 36954749 : && !DECL_DEFAULTED_FN (fun))
974 : {
975 3449813 : if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
976 : massaged, complain))
977 : potential = false;
978 3449787 : 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 3445075 : massaged = DECL_SAVED_TREE (fun);
983 3445075 : potential = potential_rvalue_constant_expression (massaged);
984 3445075 : if (!potential && complain)
985 16 : require_potential_rvalue_constant_expression_fncheck (massaged);
986 : }
987 : }
988 :
989 32829609 : 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 262 : && warn_invalid_constexpr != 0)
995 : return;
996 :
997 32829455 : if (implicit)
998 : {
999 12 : if (potential)
1000 : {
1001 2 : DECL_DECLARED_CONSTEXPR_P (fun) = true;
1002 2 : DECL_LANG_SPECIFIC (fun)->u.fn.implicit_constexpr = true;
1003 4 : 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 32829445 : constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
1013 32829445 : bool clear_ctx = false;
1014 32829445 : if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
1015 : {
1016 32829445 : clear_ctx = true;
1017 32829445 : DECL_CONTEXT (DECL_RESULT (fun)) = fun;
1018 : }
1019 32829445 : tree saved_fn = current_function_decl;
1020 32829445 : current_function_decl = fun;
1021 32829445 : entry.body = copy_fn (entry.decl, entry.parms, entry.result);
1022 32829445 : current_function_decl = saved_fn;
1023 32829445 : if (clear_ctx)
1024 32829445 : DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
1025 32829445 : 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 108497 : entry.result = error_mark_node;
1030 :
1031 32829445 : 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 32861612 : register_constexpr_fundef (const constexpr_fundef &value)
1039 : {
1040 : /* Create the constexpr function table if necessary. */
1041 32861612 : if (constexpr_fundef_table == NULL)
1042 25781 : constexpr_fundef_table
1043 25781 : = hash_table<constexpr_fundef_hasher>::create_ggc (101);
1044 :
1045 32861612 : constexpr_fundef **slot = constexpr_fundef_table->find_slot
1046 32861612 : (const_cast<constexpr_fundef *> (&value), INSERT);
1047 :
1048 32861612 : gcc_assert (*slot == NULL);
1049 32861612 : *slot = ggc_alloc<constexpr_fundef> ();
1050 32861612 : **slot = value;
1051 32861612 : }
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 759 : explain_invalid_constexpr_fn (tree fun)
1061 : {
1062 759 : static hash_set<tree> *diagnosed;
1063 759 : tree body;
1064 :
1065 : /* Don't try to explain a function we already complained about. */
1066 759 : if (function *f = DECL_STRUCT_FUNCTION (fun))
1067 572 : if (f->language->erroneous)
1068 759 : 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 710 : if (warn_invalid_constexpr == 0 && DECL_DECLARED_CONSTEXPR_P (fun))
1075 : /* Go on. */;
1076 : /* Only diagnose defaulted functions, lambdas, or instantiations. */
1077 682 : else if (!DECL_DEFAULTED_FN (fun)
1078 911 : && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
1079 653 : && !(flag_implicit_constexpr
1080 8 : && !DECL_DECLARED_CONSTEXPR_P (fun)
1081 8 : && DECL_DECLARED_INLINE_P (fun))
1082 1330 : && !is_instantiation_of_constexpr (fun))
1083 : {
1084 630 : inform (DECL_SOURCE_LOCATION (fun), "%qD declared here", fun);
1085 3 : if (flag_implicit_constexpr && !maybe_constexpr_fn (fun)
1086 633 : && decl_defined_p (fun))
1087 3 : inform (DECL_SOURCE_LOCATION (fun),
1088 : "%<-fimplicit-constexpr%> only affects %<inline%> functions");
1089 630 : return;
1090 : }
1091 80 : if (diagnosed == NULL)
1092 64 : diagnosed = new hash_set<tree>;
1093 80 : if (diagnosed->add (fun))
1094 : /* Already explained. */
1095 : return;
1096 :
1097 79 : iloc_sentinel ils = input_location;
1098 79 : 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 75 : input_location = DECL_SOURCE_LOCATION (fun);
1103 75 : inform (input_location,
1104 : "%qD is not usable as a %<constexpr%> function because:", fun);
1105 : }
1106 : /* First check the declaration. */
1107 79 : if (is_valid_constexpr_fn (fun, true))
1108 : {
1109 : /* Then if it's OK, the body. */
1110 73 : if (!DECL_DECLARED_CONSTEXPR_P (fun)
1111 73 : && DECL_DEFAULTED_FN (fun))
1112 10 : explain_implicit_non_constexpr (fun);
1113 : else
1114 : {
1115 63 : if (constexpr_fundef *fd = retrieve_constexpr_fundef (fun))
1116 46 : body = fd->body;
1117 : else
1118 17 : body = DECL_SAVED_TREE (fun);
1119 63 : tree massaged = massage_constexpr_body (fun, body);
1120 63 : require_potential_rvalue_constant_expression (massaged);
1121 126 : if (DECL_CONSTRUCTOR_P (fun))
1122 : {
1123 12 : cx_check_missing_mem_inits (DECL_CONTEXT (fun), massaged, true);
1124 12 : if (cxx_dialect > cxx11)
1125 : /* Also check the body, not just the ctor-initializer. */
1126 10 : require_potential_rvalue_constant_expression (body);
1127 : }
1128 51 : 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 79 : }
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 64399063 : 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'. */
1185 : hash_map<tree,tree> values;
1186 : public:
1187 : /* Number of cxx_eval_constant_expression calls (except skipped ones,
1188 : on simple constants or location wrappers) encountered during current
1189 : cxx_eval_outermost_constant_expr call. */
1190 : HOST_WIDE_INT constexpr_ops_count;
1191 : /* Heap VAR_DECLs created during the evaluation of the outermost constant
1192 : expression. */
1193 : auto_vec<tree, 16> heap_vars;
1194 : /* Vector of caught exceptions, including exceptions still not active at
1195 : the start of a handler (those are immediately followed up by HANDLER_TYPE
1196 : until __cxa_begin_catch finishes). */
1197 : auto_vec<tree, 2> caught_exceptions;
1198 : /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */
1199 : vec<tree> *cleanups;
1200 : /* If non-null, only allow modification of existing values of the variables
1201 : in this set. Set by modifiable_tracker, below. */
1202 : hash_set<tree> *modifiable;
1203 : /* If cxx_eval_outermost_constant_expr is called on the consteval block
1204 : operator (), this is the FUNCTION_DECL of that operator (). */
1205 : tree consteval_block;
1206 : /* Number of heap VAR_DECL deallocations. */
1207 : unsigned heap_dealloc_count;
1208 : /* Number of uncaught exceptions. */
1209 : unsigned uncaught_exceptions;
1210 : /* A contract statement that failed or was not constant, we only store the
1211 : first one that fails. */
1212 : tree contract_statement;
1213 : /* [basic.contract.eval]/7.3 if this expression would otherwise be constant
1214 : then a non-const contract makes the program ill-formed. */
1215 : bool contract_condition_non_const;
1216 : /* Some metafunctions aren't dependent just on their arguments, but also
1217 : on various other dependencies, e.g. has_identifier on a function parameter
1218 : reflection can change depending on further declarations of corresponding
1219 : function, is_complete_type depends on type definitions and template
1220 : specializations in between the calls, define_aggregate even defines
1221 : class types, etc. Thus, we need to arrange for calls which call
1222 : at least some metafunctions to be non-cacheable, because their behavior
1223 : might not be the same. Until we figure out which exact metafunctions
1224 : need this and which don't, do it for all of them. */
1225 : bool metafns_called;
1226 :
1227 : /* Constructor. */
1228 613234046 : constexpr_global_ctx ()
1229 1226468092 : : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
1230 613234046 : consteval_block (NULL_TREE), heap_dealloc_count (0),
1231 613234046 : uncaught_exceptions (0), contract_statement (NULL_TREE),
1232 613234046 : contract_condition_non_const (false), metafns_called (false) {}
1233 :
1234 414727612 : bool is_outside_lifetime (tree t)
1235 : {
1236 414727612 : if (tree *p = values.get (t))
1237 132505313 : if (*p == void_node)
1238 189 : return true;
1239 : return false;
1240 : }
1241 534390122 : tree get_value (tree t)
1242 : {
1243 534390122 : if (tree *p = values.get (t))
1244 227469871 : if (*p != void_node)
1245 223419160 : return *p;
1246 : return NULL_TREE;
1247 : }
1248 82636529 : tree *get_value_ptr (tree t, bool initializing)
1249 : {
1250 82636529 : if (modifiable && !modifiable->contains (t))
1251 : return nullptr;
1252 82636518 : if (tree *p = values.get (t))
1253 : {
1254 82631150 : if (*p != void_node)
1255 : return p;
1256 48 : else if (initializing)
1257 : {
1258 6 : *p = NULL_TREE;
1259 6 : return p;
1260 : }
1261 : }
1262 : return nullptr;
1263 : }
1264 279386536 : void put_value (tree t, tree v)
1265 : {
1266 279386536 : bool already_in_map = values.put (t, v);
1267 279386536 : if (!already_in_map && modifiable)
1268 30 : modifiable->add (t);
1269 279386536 : }
1270 201028736 : void destroy_value (tree t)
1271 : {
1272 201028736 : if (TREE_CODE (t) == VAR_DECL
1273 201028736 : || TREE_CODE (t) == PARM_DECL
1274 : || TREE_CODE (t) == RESULT_DECL)
1275 201022929 : values.put (t, void_node);
1276 : else
1277 5807 : values.remove (t);
1278 201028736 : }
1279 14404604 : void clear_value (tree t)
1280 : {
1281 28809208 : values.remove (t);
1282 : }
1283 : };
1284 :
1285 : /* Helper class for constexpr_global_ctx. In some cases we want to avoid
1286 : side-effects from evaluation of a particular subexpression of a
1287 : constant-expression. In such cases we use modifiable_tracker to prevent
1288 : modification of variables created outside of that subexpression.
1289 :
1290 : ??? We could change the hash_set to a hash_map, allow and track external
1291 : modifications, and roll them back in the destructor. It's not clear to me
1292 : that this would be worthwhile. */
1293 :
1294 : class modifiable_tracker
1295 : {
1296 : hash_set<tree> set;
1297 : constexpr_global_ctx *global;
1298 : public:
1299 173441 : modifiable_tracker (constexpr_global_ctx *g): global(g)
1300 : {
1301 173441 : global->modifiable = &set;
1302 173441 : }
1303 173441 : ~modifiable_tracker ()
1304 : {
1305 173471 : for (tree t: set)
1306 30 : global->clear_value (t);
1307 173441 : global->modifiable = nullptr;
1308 173441 : }
1309 : };
1310 :
1311 : /* The constexpr expansion context. CALL is the current function
1312 : expansion, CTOR is the current aggregate initializer, OBJECT is the
1313 : object being initialized by CTOR, either a VAR_DECL or a _REF. */
1314 :
1315 : struct constexpr_ctx {
1316 : /* The part of the context that needs to be unique to the whole
1317 : cxx_eval_outermost_constant_expr invocation. */
1318 : constexpr_global_ctx *global;
1319 : /* The innermost call we're evaluating. */
1320 : constexpr_call *call;
1321 : /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen
1322 : within the current LOOP_EXPR. NULL if we aren't inside a loop. */
1323 : vec<tree> *save_exprs;
1324 : /* The CONSTRUCTOR we're currently building up for an aggregate
1325 : initializer. */
1326 : tree ctor;
1327 : /* The object we're building the CONSTRUCTOR for. */
1328 : tree object;
1329 : /* If inside SWITCH_EXPR. */
1330 : constexpr_switch_state *css_state;
1331 : /* The aggregate initialization context inside which this one is nested. This
1332 : is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs. */
1333 : const constexpr_ctx *parent;
1334 :
1335 : /* Whether we should error on a non-constant expression or fail quietly.
1336 : This flag needs to be here, but some of the others could move to global
1337 : if they get larger than a word. */
1338 : bool quiet;
1339 : /* Whether we are strictly conforming to constant expression rules or
1340 : trying harder to get a constant value. */
1341 : bool strict;
1342 : /* Whether __builtin_is_constant_evaluated () should be true. */
1343 : mce_value manifestly_const_eval;
1344 : };
1345 :
1346 : /* Return ctx->quiet. For use in reflect.cc. */
1347 :
1348 : bool
1349 268 : cxx_constexpr_quiet_p (const constexpr_ctx *ctx)
1350 : {
1351 268 : return ctx->quiet;
1352 : }
1353 :
1354 : /* Return ctx->manifestly_const_eval. For use in reflect.cc. */
1355 :
1356 : mce_value
1357 108 : cxx_constexpr_manifestly_const_eval (const constexpr_ctx *ctx)
1358 : {
1359 108 : return ctx->manifestly_const_eval;
1360 : }
1361 :
1362 : /* Return ctx->call->fundef->decl or NULL_TREE. For use in
1363 : reflect.cc. */
1364 :
1365 : tree
1366 757 : cxx_constexpr_caller (const constexpr_ctx *ctx)
1367 : {
1368 757 : if (ctx->call)
1369 380 : return ctx->call->fundef->decl;
1370 : else
1371 : return NULL_TREE;
1372 : }
1373 :
1374 : /* Return ctx->global->consteval_block. For use in reflect.cc. */
1375 :
1376 : tree
1377 74 : cxx_constexpr_consteval_block (const constexpr_ctx *ctx)
1378 : {
1379 74 : return ctx->global->consteval_block;
1380 : }
1381 :
1382 : /* Predicates for the meaning of *jump_target. */
1383 :
1384 : static bool
1385 88247648 : returns (tree *jump_target)
1386 : {
1387 14699151 : return *jump_target && TREE_CODE (*jump_target) == RETURN_EXPR;
1388 : }
1389 :
1390 : static bool
1391 82611879 : breaks (tree *jump_target)
1392 : {
1393 82611879 : return (*jump_target
1394 82611879 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1395 91 : && LABEL_DECL_BREAK (*jump_target))
1396 977578 : || TREE_CODE (*jump_target) == BREAK_STMT
1397 936671 : || TREE_CODE (*jump_target) == EXIT_EXPR));
1398 : }
1399 :
1400 : static bool
1401 122504159 : continues (tree *jump_target)
1402 : {
1403 122504159 : return (*jump_target
1404 122504159 : && ((TREE_CODE (*jump_target) == LABEL_DECL
1405 163 : && LABEL_DECL_CONTINUE (*jump_target))
1406 955164 : || TREE_CODE (*jump_target) == CONTINUE_STMT));
1407 : }
1408 :
1409 : static bool
1410 9753003 : switches (tree *jump_target)
1411 : {
1412 48775 : return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST;
1413 : }
1414 :
1415 : static bool
1416 1922034122 : throws (tree *jump_target)
1417 : {
1418 : /* void_node is for use in potential_constant_expression_1, otherwise
1419 : it should an artificial VAR_DECL created by constant evaluation
1420 : of __cxa_allocate_exception (). */
1421 155222955 : return (*jump_target && (VAR_P (*jump_target) || *jump_target == void_node));
1422 : }
1423 :
1424 : /* True if the constexpr relaxations afforded by P2280R4 for unknown
1425 : references and objects are in effect. */
1426 :
1427 : static bool
1428 281925346 : p2280_active_p (const constexpr_ctx *ctx)
1429 : {
1430 47137854 : if (ctx->manifestly_const_eval != mce_true)
1431 : /* Disable these relaxations during speculative constexpr folding,
1432 : as it can significantly increase compile time/memory use
1433 : (PR119387). */
1434 : return false;
1435 :
1436 : /* P2280R4 was accepted as a DR against C++11. */
1437 0 : return cxx_dialect >= cxx11;
1438 : }
1439 :
1440 : /* Remove T from the global values map, checking for attempts to destroy
1441 : a value that has already finished its lifetime. */
1442 :
1443 : static void
1444 200853776 : destroy_value_checked (const constexpr_ctx* ctx, tree t, bool *non_constant_p)
1445 : {
1446 200853776 : if (t == error_mark_node || TREE_TYPE (t) == error_mark_node)
1447 : return;
1448 :
1449 : /* Don't error again here if we've already reported a problem. */
1450 200853759 : if (!*non_constant_p
1451 133344287 : && DECL_P (t)
1452 : /* Non-trivial destructors have their lifetimes ended explicitly
1453 : with a clobber, so don't worry about it here. */
1454 133338660 : && (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (t))
1455 : /* ...except parameters are remapped in cxx_eval_call_expression,
1456 : and the destructor call during cleanup won't be able to tell that
1457 : this value has already been destroyed, so complain now. This is
1458 : not quite unobservable, but is extremely unlikely to crop up in
1459 : practice; see g++.dg/cpp2a/constexpr-lifetime2.C. */
1460 751072 : || TREE_CODE (t) == PARM_DECL)
1461 333441999 : && ctx->global->is_outside_lifetime (t))
1462 : {
1463 54 : if (!ctx->quiet)
1464 : {
1465 18 : auto_diagnostic_group d;
1466 18 : error ("destroying %qE outside its lifetime", t);
1467 18 : inform (DECL_SOURCE_LOCATION (t), "declared here");
1468 18 : }
1469 54 : *non_constant_p = true;
1470 : }
1471 200853759 : ctx->global->destroy_value (t);
1472 : }
1473 :
1474 : /* This internal flag controls whether we should avoid doing anything during
1475 : constexpr evaluation that would cause extra DECL_UID generation, such as
1476 : template instantiation and function body copying. */
1477 :
1478 : static bool uid_sensitive_constexpr_evaluation_value;
1479 :
1480 : /* An internal counter that keeps track of the number of times
1481 : uid_sensitive_constexpr_evaluation_p returned true. */
1482 :
1483 : static unsigned uid_sensitive_constexpr_evaluation_true_counter;
1484 :
1485 : /* The accessor for uid_sensitive_constexpr_evaluation_value which also
1486 : increments the corresponding counter. */
1487 :
1488 : static bool
1489 10386823 : uid_sensitive_constexpr_evaluation_p ()
1490 : {
1491 10347084 : if (uid_sensitive_constexpr_evaluation_value)
1492 : {
1493 347389 : ++uid_sensitive_constexpr_evaluation_true_counter;
1494 347389 : return true;
1495 : }
1496 : else
1497 : return false;
1498 : }
1499 :
1500 : /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel
1501 : enables the internal flag for uid_sensitive_constexpr_evaluation_p
1502 : during the lifetime of the sentinel object. Upon its destruction, the
1503 : previous value of uid_sensitive_constexpr_evaluation_p is restored. */
1504 :
1505 84000578 : uid_sensitive_constexpr_evaluation_sentinel
1506 84000578 : ::uid_sensitive_constexpr_evaluation_sentinel ()
1507 84000578 : : ovr (uid_sensitive_constexpr_evaluation_value, true)
1508 : {
1509 84000578 : }
1510 :
1511 : /* The default constructor for uid_sensitive_constexpr_evaluation_checker
1512 : records the current number of times that uid_sensitive_constexpr_evaluation_p
1513 : has been called and returned true. */
1514 :
1515 4538885072 : uid_sensitive_constexpr_evaluation_checker
1516 4538885072 : ::uid_sensitive_constexpr_evaluation_checker ()
1517 4538885072 : : saved_counter (uid_sensitive_constexpr_evaluation_true_counter)
1518 : {
1519 4538885072 : }
1520 :
1521 : /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and
1522 : some constexpr evaluation was restricted due to u_s_c_e_p being called
1523 : and returning true during the lifetime of this checker object. */
1524 :
1525 : bool
1526 2983915940 : uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const
1527 : {
1528 2983915940 : return (uid_sensitive_constexpr_evaluation_value
1529 2983915940 : && saved_counter != uid_sensitive_constexpr_evaluation_true_counter);
1530 : }
1531 :
1532 :
1533 : /* A table of all constexpr calls that have been evaluated by the
1534 : compiler in this translation unit. */
1535 :
1536 : static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
1537 :
1538 : /* Compute a hash value for a constexpr call representation. */
1539 :
1540 : inline hashval_t
1541 188285541 : constexpr_call_hasher::hash (constexpr_call *info)
1542 : {
1543 188285541 : return info->hash;
1544 : }
1545 :
1546 : /* Return true if the objects pointed to by P and Q represent calls
1547 : to the same constexpr function with the same arguments.
1548 : Otherwise, return false. */
1549 :
1550 : bool
1551 202420034 : constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
1552 : {
1553 202420034 : if (lhs == rhs)
1554 : return true;
1555 202420034 : if (lhs->hash != rhs->hash)
1556 : return false;
1557 27143831 : if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
1558 : return false;
1559 27143831 : return cp_tree_equal (lhs->bindings, rhs->bindings);
1560 : }
1561 :
1562 : /* Initialize the constexpr call table, if needed. */
1563 :
1564 : static void
1565 33293488 : maybe_initialize_constexpr_call_table (void)
1566 : {
1567 33293488 : if (constexpr_call_table == NULL)
1568 16966 : constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
1569 33293488 : }
1570 :
1571 : /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
1572 : a function happens to get called recursively, we unshare the callee
1573 : function's body and evaluate this unshared copy instead of evaluating the
1574 : original body.
1575 :
1576 : FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function
1577 : copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map
1578 : that's keyed off of the original FUNCTION_DECL and whose value is a
1579 : TREE_LIST of this function's unused copies awaiting reuse.
1580 :
1581 : This is not GC-deletable to avoid GC affecting UID generation. */
1582 :
1583 : static GTY(()) decl_tree_map *fundef_copies_table;
1584 :
1585 : /* Reuse a copy or create a new unshared copy of the function FUN.
1586 : Return this copy. We use a TREE_LIST whose PURPOSE is body, VALUE
1587 : is parms, TYPE is result. */
1588 :
1589 : static tree
1590 77017423 : get_fundef_copy (constexpr_fundef *fundef)
1591 : {
1592 77017423 : tree copy;
1593 77017423 : bool existed;
1594 77017423 : tree *slot = &(hash_map_safe_get_or_insert<hm_ggc>
1595 77017423 : (fundef_copies_table, fundef->decl, &existed, 127));
1596 :
1597 77017423 : if (!existed)
1598 : {
1599 : /* There is no cached function available, or in use. We can use
1600 : the function directly. That the slot is now created records
1601 : that this function is now in use. */
1602 8753714 : copy = build_tree_list (fundef->body, fundef->parms);
1603 8753714 : TREE_TYPE (copy) = fundef->result;
1604 : }
1605 68263709 : else if (*slot == NULL_TREE)
1606 : {
1607 4346 : if (uid_sensitive_constexpr_evaluation_p ())
1608 0 : return NULL_TREE;
1609 :
1610 : /* We've already used the function itself, so make a copy. */
1611 4346 : copy = build_tree_list (NULL, NULL);
1612 4346 : tree saved_body = DECL_SAVED_TREE (fundef->decl);
1613 4346 : tree saved_parms = DECL_ARGUMENTS (fundef->decl);
1614 4346 : tree saved_result = DECL_RESULT (fundef->decl);
1615 4346 : tree saved_fn = current_function_decl;
1616 4346 : DECL_SAVED_TREE (fundef->decl) = fundef->body;
1617 4346 : DECL_ARGUMENTS (fundef->decl) = fundef->parms;
1618 4346 : DECL_RESULT (fundef->decl) = fundef->result;
1619 4346 : current_function_decl = fundef->decl;
1620 4346 : TREE_PURPOSE (copy) = copy_fn (fundef->decl, TREE_VALUE (copy),
1621 4346 : TREE_TYPE (copy));
1622 4346 : current_function_decl = saved_fn;
1623 4346 : DECL_RESULT (fundef->decl) = saved_result;
1624 4346 : DECL_ARGUMENTS (fundef->decl) = saved_parms;
1625 4346 : DECL_SAVED_TREE (fundef->decl) = saved_body;
1626 : }
1627 : else
1628 : {
1629 : /* We have a cached function available. */
1630 68259363 : copy = *slot;
1631 68259363 : *slot = TREE_CHAIN (copy);
1632 : }
1633 :
1634 : return copy;
1635 : }
1636 :
1637 : /* Save the copy COPY of function FUN for later reuse by
1638 : get_fundef_copy(). By construction, there will always be an entry
1639 : to find. */
1640 :
1641 : static void
1642 77017421 : save_fundef_copy (tree fun, tree copy)
1643 : {
1644 77017421 : tree *slot = fundef_copies_table->get (fun);
1645 77017421 : TREE_CHAIN (copy) = *slot;
1646 77017421 : *slot = copy;
1647 77017421 : }
1648 :
1649 : static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree,
1650 : value_cat, bool *, bool *, tree *);
1651 : static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree,
1652 : bool *, tree *);
1653 : static tree find_heap_var_refs (tree *, int *, void *);
1654 :
1655 : /* For exception object EXC if it has class type and usable what () method
1656 : which returns cv char * return the xmalloced string literal which it returns
1657 : if possible, otherwise return NULL. */
1658 :
1659 : static char *
1660 199 : exception_what_str (const constexpr_ctx *ctx, tree exc)
1661 : {
1662 199 : tree type = strip_array_types (TREE_TYPE (exc));
1663 199 : if (!CLASS_TYPE_P (type))
1664 : return NULL;
1665 158 : tree std_exception = lookup_qualified_name (std_node, "exception",
1666 : LOOK_want::NORMAL, false);
1667 158 : if (TREE_CODE (std_exception) != TYPE_DECL)
1668 : return NULL;
1669 155 : if (!CLASS_TYPE_P (TREE_TYPE (std_exception)))
1670 : return NULL;
1671 155 : base_kind b_kind;
1672 155 : tree binfo = lookup_base (type, TREE_TYPE (std_exception), ba_check, &b_kind,
1673 : tf_none);
1674 155 : if (binfo == NULL_TREE || binfo == error_mark_node)
1675 : return NULL;
1676 151 : if (type != TREE_TYPE (exc))
1677 113 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1678 151 : tree call
1679 151 : = finish_class_member_access_expr (exc, get_identifier ("what"), false,
1680 : tf_none);
1681 151 : if (call == error_mark_node)
1682 : return NULL;
1683 151 : releasing_vec what_args;
1684 151 : call = finish_call_expr (call, &what_args, false, false, tf_none);
1685 151 : if (call == error_mark_node)
1686 : return NULL;
1687 151 : if (TREE_CODE (TREE_TYPE (call)) != POINTER_TYPE
1688 151 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1689 151 : || !COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
1690 151 : || !tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (call))),
1691 151 : TYPE_SIZE_UNIT (char_type_node))
1692 302 : || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (call))) != BITS_PER_UNIT)
1693 0 : return NULL;
1694 151 : if (!potential_constant_expression (call))
1695 : return NULL;
1696 151 : bool non_constant_p = false, overflow_p = false;
1697 151 : tree jmp_target = NULL;
1698 151 : tree ptr = cxx_eval_constant_expression (ctx, call, vc_prvalue,
1699 : &non_constant_p, &overflow_p,
1700 : &jmp_target);
1701 151 : if (throws (&jmp_target) || non_constant_p)
1702 : return NULL;
1703 151 : if (reduced_constant_expression_p (ptr))
1704 40 : if (const char *msg = c_getstr (ptr))
1705 40 : return xstrdup (msg);
1706 111 : auto_vec <char, 32> v;
1707 4345 : for (unsigned i = 0; i < INT_MAX; ++i)
1708 : {
1709 4345 : tree t = call;
1710 4345 : if (i)
1711 4234 : t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, size_int (i));
1712 4345 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
1713 4345 : non_constant_p = false;
1714 4345 : overflow_p = false;
1715 4345 : jmp_target = NULL;
1716 4345 : tree t2 = cxx_eval_constant_expression (ctx, t, vc_prvalue,
1717 : &non_constant_p, &overflow_p,
1718 : &jmp_target);
1719 4345 : if (throws (&jmp_target)
1720 4345 : || non_constant_p
1721 4345 : || !tree_fits_shwi_p (t2))
1722 0 : return NULL;
1723 4345 : char c = tree_to_shwi (t2);
1724 4345 : v.safe_push (c);
1725 4345 : if (c == '\0')
1726 : break;
1727 : }
1728 222 : return xstrdup (v.address ());
1729 262 : }
1730 :
1731 : /* Diagnose constant expression evaluation encountering call to
1732 : std::terminate due to exception EXC. */
1733 :
1734 : static void
1735 11 : diagnose_std_terminate (location_t loc, const constexpr_ctx *ctx, tree exc)
1736 : {
1737 11 : tree type = strip_array_types (TREE_TYPE (exc));
1738 11 : if (char *str = exception_what_str (ctx, exc))
1739 : {
1740 2 : error_at (loc, "%qs called after throwing an exception of type %qT; "
1741 : "%<what()%>: %qs", "std::terminate", type, str);
1742 2 : free (str);
1743 : }
1744 : else
1745 : {
1746 9 : if (type != TREE_TYPE (exc))
1747 9 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1748 9 : bool non_constant_p = false, overflow_p = false;
1749 9 : tree jmp_target = NULL;
1750 9 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1751 : &non_constant_p, &overflow_p,
1752 : &jmp_target);
1753 9 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1754 9 : if (reduced_constant_expression_p (val))
1755 9 : error_at (loc, "%qs called after throwing an exception %qE",
1756 : "std::terminate", val);
1757 : else
1758 0 : error_at (loc, "%qs called after throwing an exception of type %qT",
1759 : "std::terminate", type);
1760 : }
1761 11 : }
1762 :
1763 : /* Diagnose constant expression evaluation encountering call to
1764 : uncaught exception EXC. */
1765 :
1766 : static void
1767 188 : diagnose_uncaught_exception (location_t loc, const constexpr_ctx *ctx, tree exc)
1768 : {
1769 188 : tree type = strip_array_types (TREE_TYPE (exc));
1770 188 : if (char *str = exception_what_str (ctx, exc))
1771 : {
1772 149 : error_at (loc, "uncaught exception of type %qT; %<what()%>: %qs", type, str);
1773 149 : free (str);
1774 : }
1775 : else
1776 : {
1777 39 : if (type != TREE_TYPE (exc))
1778 39 : exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
1779 39 : bool non_constant_p = false, overflow_p = false;
1780 39 : tree jmp_target = NULL;
1781 39 : tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
1782 : &non_constant_p, &overflow_p,
1783 : &jmp_target);
1784 39 : gcc_assert (!throws (&jmp_target) && !non_constant_p);
1785 39 : if (reduced_constant_expression_p (val))
1786 38 : error_at (loc, "uncaught exception %qE", val);
1787 : else
1788 1 : error_at (loc, "uncaught exception of type %qT", type);
1789 : }
1790 188 : }
1791 :
1792 : /* Kinds of __cxa_* functions (and a few other EH related ones) we handle as
1793 : magic constexpr functions for C++26. */
1794 :
1795 : enum cxa_builtin {
1796 : CXA_NONE = 0,
1797 : CXA_ALLOCATE_EXCEPTION = 1,
1798 : CXA_FREE_EXCEPTION = 2,
1799 : CXA_THROW = 3,
1800 : CXA_BEGIN_CATCH = 4,
1801 : CXA_END_CATCH = 5,
1802 : CXA_RETHROW = 6,
1803 : CXA_GET_EXCEPTION_PTR = 7,
1804 : CXA_BAD_CAST = 8,
1805 : CXA_BAD_TYPEID = 9,
1806 : CXA_THROW_BAD_ARRAY_NEW_LENGTH = 10,
1807 : STD_UNCAUGHT_EXCEPTIONS = 11,
1808 : STD_CURRENT_EXCEPTION = 12,
1809 : STD_RETHROW_EXCEPTION = 13,
1810 : BUILTIN_EH_PTR_ADJUST_REF = 14
1811 : };
1812 :
1813 : /* Return cxa_builtin if FNDECL is a __cxa_* function handled as
1814 : magic constexpr function for C++26. Return CXA_NONE otherwise. */
1815 :
1816 : static enum cxa_builtin
1817 40705514 : cxx_cxa_builtin_fn_p (tree fndecl)
1818 : {
1819 40705514 : if (cxx_dialect < cxx26)
1820 : return CXA_NONE;
1821 2697249 : if (DECL_LANGUAGE (fndecl) != lang_c)
1822 : {
1823 2368812 : if (!decl_in_std_namespace_p (fndecl))
1824 : return CXA_NONE;
1825 966586 : if (id_equal (DECL_NAME (fndecl), "uncaught_exceptions"))
1826 : return STD_UNCAUGHT_EXCEPTIONS;
1827 966530 : if (id_equal (DECL_NAME (fndecl), "current_exception"))
1828 : return STD_CURRENT_EXCEPTION;
1829 953914 : if (id_equal (DECL_NAME (fndecl), "rethrow_exception"))
1830 : return STD_RETHROW_EXCEPTION;
1831 : return CXA_NONE;
1832 : }
1833 328437 : if (!startswith (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__cxa_"))
1834 : return CXA_NONE;
1835 59104 : if (id_equal (DECL_NAME (fndecl), "__cxa_allocate_exception"))
1836 : return CXA_ALLOCATE_EXCEPTION;
1837 12394 : if (id_equal (DECL_NAME (fndecl), "__cxa_free_exception"))
1838 : return CXA_FREE_EXCEPTION;
1839 12393 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw"))
1840 : return CXA_THROW;
1841 7360 : if (id_equal (DECL_NAME (fndecl), "__cxa_begin_catch"))
1842 : return CXA_BEGIN_CATCH;
1843 2543 : if (id_equal (DECL_NAME (fndecl), "__cxa_end_catch"))
1844 : return CXA_END_CATCH;
1845 870 : if (id_equal (DECL_NAME (fndecl), "__cxa_rethrow"))
1846 : return CXA_RETHROW;
1847 814 : if (id_equal (DECL_NAME (fndecl), "__cxa_get_exception_ptr"))
1848 : return CXA_GET_EXCEPTION_PTR;
1849 784 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_cast"))
1850 : return CXA_BAD_CAST;
1851 500 : if (id_equal (DECL_NAME (fndecl), "__cxa_bad_typeid"))
1852 : return CXA_BAD_TYPEID;
1853 492 : if (id_equal (DECL_NAME (fndecl), "__cxa_throw_bad_array_new_length"))
1854 : return CXA_THROW_BAD_ARRAY_NEW_LENGTH;
1855 : return CXA_NONE;
1856 : }
1857 :
1858 : /* Helper function for cxx_eval_cxa_builtin_fn.
1859 : Check if ARG is a valid first argument of __cxa_throw or
1860 : __cxa_free_exception or __builtin_eh_ptr_adjust_ref. Return NULL_TREE if
1861 : not, otherwise return the artificial __cxa_allocate_exception allocated
1862 : VAR_DECL. FREE_EXC is true for __cxa_free_exception, false otherwise. */
1863 :
1864 : static tree
1865 833 : cxa_check_throw_arg (tree arg, bool free_exc)
1866 : {
1867 833 : STRIP_NOPS (arg);
1868 833 : if (TREE_CODE (arg) != ADDR_EXPR)
1869 : return NULL_TREE;
1870 833 : arg = TREE_OPERAND (arg, 0);
1871 833 : if (!VAR_P (arg)
1872 833 : || !DECL_ARTIFICIAL (arg)
1873 833 : || ((!free_exc || DECL_NAME (arg) != heap_uninit_identifier)
1874 833 : && DECL_NAME (arg) != heap_identifier)
1875 1666 : || !DECL_LANG_SPECIFIC (arg))
1876 0 : return NULL_TREE;
1877 : return arg;
1878 : }
1879 :
1880 : /* Helper function for cxx_eval_cxa_builtin_fn.
1881 : "Allocate" on the constexpr heap an exception object of TYPE
1882 : with REFCOUNT. */
1883 :
1884 : static tree
1885 17242 : cxa_allocate_exception (location_t loc, const constexpr_ctx *ctx, tree type,
1886 : tree refcount)
1887 : {
1888 17242 : tree var = build_decl (loc, VAR_DECL, heap_uninit_identifier, type);
1889 17242 : DECL_ARTIFICIAL (var) = 1;
1890 17242 : retrofit_lang_decl (var);
1891 17242 : DECL_EXCEPTION_REFCOUNT (var) = refcount;
1892 17242 : ctx->global->heap_vars.safe_push (var);
1893 17242 : return var;
1894 : }
1895 :
1896 : /* Evaluate various __cxa_* calls as magic constexpr builtins for
1897 : C++26 constexpr exception support (P3068R5). */
1898 :
1899 : static tree
1900 26736 : cxx_eval_cxa_builtin_fn (const constexpr_ctx *ctx, tree call,
1901 : enum cxa_builtin kind, tree fndecl,
1902 : bool *non_constant_p, bool *overflow_p,
1903 : tree *jump_target)
1904 : {
1905 26736 : int nargs = call_expr_nargs (call);
1906 26736 : location_t loc = cp_expr_loc_or_input_loc (call);
1907 26736 : tree args[4], arg;
1908 26736 : if (nargs > 4)
1909 : {
1910 0 : invalid_nargs:
1911 0 : if (!ctx->quiet)
1912 0 : error_at (loc, "call to %qD function with incorrect "
1913 : "number of arguments", fndecl);
1914 0 : *non_constant_p = true;
1915 0 : return call;
1916 : }
1917 26736 : if ((kind == CXA_BEGIN_CATCH || kind == CXA_GET_EXCEPTION_PTR)
1918 3268 : && nargs == 1
1919 3268 : && (arg = CALL_EXPR_ARG (call, 0))
1920 3268 : && TREE_CODE (arg) == CALL_EXPR
1921 3268 : && call_expr_nargs (arg) == 1
1922 30004 : && integer_zerop (CALL_EXPR_ARG (arg, 0)))
1923 3268 : if (tree fun = get_function_named_in_call (arg))
1924 3268 : if (fndecl_built_in_p (fun, BUILT_IN_EH_POINTER))
1925 : {
1926 3268 : if (ctx->global->caught_exceptions.length () < 2)
1927 : {
1928 1579 : no_caught_exceptions:
1929 1579 : if (!ctx->quiet)
1930 0 : error_at (loc, "%qD called with no caught exceptions pending",
1931 : fndecl);
1932 1579 : *non_constant_p = true;
1933 1579 : return call;
1934 : }
1935 : /* Both __cxa_get_exception_ptr (__builtin_eh_pointer (0))
1936 : and __cxa_begin_catch (__builtin_eh_pointer (0)) calls expect
1937 : ctx->global->caught_exceptions vector to end with
1938 : __cxa_allocate_exception created artificial VAR_DECL (the
1939 : exception object) followed by handler type, pushed by TRY_BLOCK
1940 : evaluation. The only difference between the functions is that
1941 : __cxa_begin_catch pops the handler type from the vector and keeps
1942 : the VAR_DECL last and decreases uncaught_exceptions. The
1943 : VAR_DECL after __cxa_begin_catch serves as the current exception
1944 : and is then popped in __cxa_end_catch evaluation. */
1945 1689 : tree handler_type = ctx->global->caught_exceptions.last ();
1946 1689 : if (handler_type && VAR_P (handler_type))
1947 0 : goto no_caught_exceptions;
1948 1689 : unsigned idx = ctx->global->caught_exceptions.length () - 2;
1949 1689 : arg = ctx->global->caught_exceptions[idx];
1950 1689 : gcc_assert (VAR_P (arg));
1951 1689 : if (kind == CXA_BEGIN_CATCH)
1952 : {
1953 1675 : ctx->global->caught_exceptions.pop ();
1954 1675 : --ctx->global->uncaught_exceptions;
1955 : }
1956 1689 : if (handler_type == NULL_TREE)
1957 : /* Used for catch (...). Just return void. */
1958 35 : return void_node;
1959 1654 : else if (POINTER_TYPE_P (handler_type))
1960 : {
1961 : /* Used for catch of a pointer. */
1962 33 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
1963 33 : arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
1964 : size_zero_node, NULL_TREE, NULL_TREE);
1965 33 : arg = cp_convert (handler_type, arg,
1966 33 : ctx->quiet ? tf_none : tf_warning_or_error);
1967 33 : if (arg == error_mark_node)
1968 : {
1969 0 : *non_constant_p = true;
1970 0 : return call;
1971 : }
1972 : }
1973 : else
1974 : {
1975 : /* Used for catch of a non-pointer type. */
1976 1621 : tree exc_type = strip_array_types (TREE_TYPE (arg));
1977 1621 : tree exc_ptr_type = build_pointer_type (exc_type);
1978 1621 : arg = build_fold_addr_expr_with_type (arg, exc_ptr_type);
1979 1621 : if (CLASS_TYPE_P (handler_type))
1980 : {
1981 1578 : tree ptr_type = build_pointer_type (handler_type);
1982 1578 : arg = cp_convert (ptr_type, arg,
1983 1578 : ctx->quiet ? tf_none
1984 : : tf_warning_or_error);
1985 1578 : if (arg == error_mark_node)
1986 : {
1987 0 : *non_constant_p = true;
1988 0 : return call;
1989 : }
1990 : }
1991 : }
1992 1654 : return cxx_eval_constant_expression (ctx, arg, vc_prvalue,
1993 : non_constant_p, overflow_p,
1994 1654 : jump_target);
1995 : }
1996 41500 : for (int i = 0; i < nargs; ++i)
1997 : {
1998 18032 : args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (call, i),
1999 : vc_prvalue, non_constant_p,
2000 : overflow_p, jump_target);
2001 18032 : if (*non_constant_p)
2002 : return call;
2003 18032 : if (*jump_target)
2004 : return NULL_TREE;
2005 : }
2006 23468 : switch (kind)
2007 : {
2008 15650 : case CXA_ALLOCATE_EXCEPTION:
2009 15650 : if (nargs != 1)
2010 0 : goto invalid_nargs;
2011 15650 : if (!tree_fits_uhwi_p (args[0]))
2012 : {
2013 0 : if (!ctx->quiet)
2014 0 : error_at (loc, "cannot allocate exception: size not constant");
2015 0 : *non_constant_p = true;
2016 0 : return call;
2017 : }
2018 : else
2019 : {
2020 31300 : tree type = build_array_type_nelts (char_type_node,
2021 15650 : tree_to_uhwi (args[0]));
2022 15650 : tree var = cxa_allocate_exception (loc, ctx, type, size_zero_node);
2023 15650 : ctx->global->put_value (var, NULL_TREE);
2024 15650 : return fold_convert (ptr_type_node, build_address (var));
2025 : }
2026 1 : case CXA_FREE_EXCEPTION:
2027 1 : if (nargs != 1)
2028 0 : goto invalid_nargs;
2029 1 : arg = cxa_check_throw_arg (args[0], true);
2030 1 : if (arg == NULL_TREE)
2031 : {
2032 0 : invalid_ptr:
2033 0 : if (!ctx->quiet)
2034 0 : error_at (loc, "first argument to %qD function not result of "
2035 : "%<__cxa_allocate_exception%>", fndecl);
2036 0 : *non_constant_p = true;
2037 0 : return call;
2038 : }
2039 1 : DECL_NAME (arg) = heap_deleted_identifier;
2040 1 : ctx->global->destroy_value (arg);
2041 1 : ctx->global->heap_dealloc_count++;
2042 1 : return void_node;
2043 739 : case CXA_THROW:
2044 739 : if (nargs != 3)
2045 0 : goto invalid_nargs;
2046 739 : arg = cxa_check_throw_arg (args[0], false);
2047 739 : if (arg == NULL_TREE)
2048 0 : goto invalid_ptr;
2049 739 : DECL_EXCEPTION_REFCOUNT (arg)
2050 739 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2051 : size_one_node);
2052 739 : ++ctx->global->uncaught_exceptions;
2053 739 : *jump_target = arg;
2054 739 : return void_node;
2055 0 : case CXA_BEGIN_CATCH:
2056 0 : case CXA_GET_EXCEPTION_PTR:
2057 0 : goto invalid_nargs;
2058 1673 : case CXA_END_CATCH:
2059 1673 : if (nargs != 0)
2060 0 : goto invalid_nargs;
2061 1673 : if (ctx->global->caught_exceptions.is_empty ())
2062 : {
2063 0 : no_active_exc:
2064 0 : if (!ctx->quiet)
2065 0 : error_at (loc, "%qD called with no caught exceptions active",
2066 : fndecl);
2067 0 : *non_constant_p = true;
2068 0 : return call;
2069 : }
2070 : else
2071 : {
2072 1673 : arg = ctx->global->caught_exceptions.pop ();
2073 1673 : if (arg == NULL_TREE || !VAR_P (arg))
2074 0 : goto no_active_exc;
2075 1673 : free_except:
2076 1716 : DECL_EXCEPTION_REFCOUNT (arg)
2077 1716 : = size_binop (MINUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2078 : size_one_node);
2079 1716 : if (integer_zerop (DECL_EXCEPTION_REFCOUNT (arg)))
2080 : {
2081 1610 : if (type_build_dtor_call (TREE_TYPE (arg)))
2082 : {
2083 : /* So that we don't complain about out-of-consteval use. */
2084 1534 : temp_override<tree> ovr (current_function_decl);
2085 1534 : if (ctx->call && ctx->call->fundef)
2086 1534 : current_function_decl = ctx->call->fundef->decl;
2087 1534 : tree cleanup
2088 1545 : = cxx_maybe_build_cleanup (arg, (ctx->quiet ? tf_none
2089 : : tf_warning_or_error));
2090 1534 : if (cleanup == error_mark_node)
2091 0 : *non_constant_p = true;
2092 1534 : tree jmp_target = NULL_TREE;
2093 1534 : cxx_eval_constant_expression (ctx, cleanup, vc_discard,
2094 : non_constant_p, overflow_p,
2095 : &jmp_target);
2096 1534 : if (throws (&jmp_target))
2097 0 : *jump_target = jmp_target;
2098 1534 : }
2099 1610 : DECL_NAME (arg) = heap_deleted_identifier;
2100 1610 : ctx->global->destroy_value (arg);
2101 1610 : ctx->global->heap_dealloc_count++;
2102 : }
2103 : }
2104 1716 : return void_node;
2105 50 : case CXA_RETHROW:
2106 50 : if (nargs != 0)
2107 0 : goto invalid_nargs;
2108 50 : unsigned idx;
2109 100 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2110 36 : if (arg == NULL_TREE || !VAR_P (arg))
2111 0 : --idx;
2112 : else
2113 : break;
2114 50 : if (arg == NULL_TREE)
2115 : {
2116 14 : if (!ctx->quiet)
2117 4 : error_at (loc, "%qD called with no caught exceptions active",
2118 : fndecl);
2119 14 : *non_constant_p = true;
2120 14 : return call;
2121 : }
2122 36 : DECL_EXCEPTION_REFCOUNT (arg)
2123 36 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2124 36 : ++ctx->global->uncaught_exceptions;
2125 36 : *jump_target = arg;
2126 36 : return void_node;
2127 143 : case CXA_BAD_CAST:
2128 143 : case CXA_BAD_TYPEID:
2129 143 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2130 143 : if (nargs != 0)
2131 0 : goto invalid_nargs;
2132 : else
2133 : {
2134 143 : tree name;
2135 143 : switch (kind)
2136 : {
2137 117 : case CXA_BAD_CAST:
2138 117 : name = get_identifier ("bad_cast");
2139 117 : break;
2140 5 : case CXA_BAD_TYPEID:
2141 5 : name = get_identifier ("bad_typeid");
2142 5 : break;
2143 21 : case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
2144 21 : name = get_identifier ("bad_array_new_length");
2145 21 : break;
2146 : default:
2147 : gcc_unreachable ();
2148 : }
2149 143 : tree decl = lookup_qualified_name (std_node, name);
2150 143 : if (TREE_CODE (decl) != TYPE_DECL
2151 128 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2152 271 : || !type_build_ctor_call (TREE_TYPE (decl)))
2153 : {
2154 15 : if (!ctx->quiet)
2155 4 : error_at (loc, "%qD called without %<std::%D%> being defined",
2156 : fndecl, name);
2157 15 : *non_constant_p = true;
2158 15 : return call;
2159 : }
2160 128 : tree type = TREE_TYPE (decl);
2161 128 : tree var = cxa_allocate_exception (loc, ctx, type, size_one_node);
2162 128 : tree ctor
2163 128 : = build_special_member_call (var, complete_ctor_identifier,
2164 : NULL, type, LOOKUP_NORMAL,
2165 128 : ctx->quiet ? tf_none
2166 : : tf_warning_or_error);
2167 128 : if (ctor == error_mark_node)
2168 : {
2169 0 : *non_constant_p = true;
2170 0 : return call;
2171 : }
2172 128 : if (TREE_CONSTANT (ctor))
2173 0 : ctx->global->put_value (var, ctor);
2174 : else
2175 : {
2176 128 : ctx->global->put_value (var, NULL_TREE);
2177 128 : cxx_eval_constant_expression (ctx, ctor, vc_discard,
2178 : non_constant_p, overflow_p,
2179 : jump_target);
2180 128 : if (*non_constant_p)
2181 : return call;
2182 128 : if (throws (jump_target))
2183 : return NULL_TREE;
2184 : }
2185 128 : ++ctx->global->uncaught_exceptions;
2186 128 : *jump_target = var;
2187 : }
2188 128 : return void_node;
2189 46 : case STD_UNCAUGHT_EXCEPTIONS:
2190 46 : if (nargs != 0)
2191 0 : goto invalid_nargs;
2192 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2193 : want to give a definite answer during mce_unknown evaluation,
2194 : because that might prevent evaluation later on when some
2195 : exceptions might be uncaught. But unlike that, we don't
2196 : want to constant fold it even during cp_fold, because at runtime
2197 : std::uncaught_exceptions () might still be non-zero. */
2198 46 : if (ctx->manifestly_const_eval != mce_true)
2199 : {
2200 25 : *non_constant_p = true;
2201 25 : return call;
2202 : }
2203 21 : return build_int_cst (integer_type_node,
2204 21 : ctx->global->uncaught_exceptions);
2205 5073 : case STD_CURRENT_EXCEPTION:
2206 5073 : if (nargs != 0)
2207 0 : goto invalid_nargs;
2208 : else
2209 : {
2210 5073 : tree name = get_identifier ("exception_ptr");
2211 5073 : tree decl = lookup_qualified_name (std_node, name);
2212 5073 : tree fld;
2213 5073 : if (TREE_CODE (decl) != TYPE_DECL
2214 5073 : || !CLASS_TYPE_P (TREE_TYPE (decl))
2215 5073 : || !COMPLETE_TYPE_P (TREE_TYPE (decl))
2216 5073 : || !(fld = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (decl))))
2217 5073 : || DECL_ARTIFICIAL (fld)
2218 5073 : || TREE_CODE (TREE_TYPE (fld)) != POINTER_TYPE
2219 5073 : || next_aggregate_field (DECL_CHAIN (fld))
2220 10146 : || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (decl)),
2221 5073 : TYPE_SIZE (TREE_TYPE (fld))))
2222 : {
2223 0 : if (!ctx->quiet)
2224 0 : error_at (loc, "%qD called without supportable %qs",
2225 : fndecl, "std::exception_ptr");
2226 0 : *non_constant_p = true;
2227 0 : return call;
2228 : }
2229 10146 : FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
2230 21 : if (arg == NULL_TREE || !VAR_P (arg))
2231 0 : --idx;
2232 : else
2233 : break;
2234 : /* Similarly to __builtin_is_constant_evaluated (), we don't
2235 : want to give a definite answer during mce_unknown evaluation,
2236 : because that might prevent evaluation later on when some
2237 : exceptions might be current. But unlike that, we don't
2238 : want to constant fold it to null even during cp_fold, because
2239 : at runtime std::current_exception () might still be non-null. */
2240 5073 : if (ctx->manifestly_const_eval != mce_true && arg == NULL_TREE)
2241 : {
2242 5041 : *non_constant_p = true;
2243 5041 : return call;
2244 : }
2245 32 : if (arg == NULL_TREE)
2246 11 : arg = build_zero_cst (TREE_TYPE (fld));
2247 : else
2248 : {
2249 21 : DECL_EXCEPTION_REFCOUNT (arg)
2250 21 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2251 : size_one_node);
2252 21 : arg = fold_convert (ptr_type_node, build_address (arg));
2253 : }
2254 32 : return build_constructor_single (TREE_TYPE (decl), fld, arg);
2255 : }
2256 22 : case STD_RETHROW_EXCEPTION:
2257 22 : if (nargs != 1)
2258 0 : goto invalid_nargs;
2259 22 : if (TYPE_REF_P (TREE_TYPE (args[0])))
2260 : {
2261 22 : arg = args[0];
2262 22 : STRIP_NOPS (arg);
2263 22 : if (TREE_CODE (arg) == ADDR_EXPR)
2264 : {
2265 22 : args[0]
2266 22 : = cxx_eval_constant_expression (ctx, TREE_OPERAND (arg, 0),
2267 : vc_prvalue, non_constant_p,
2268 : overflow_p, jump_target);
2269 22 : if (*non_constant_p)
2270 : return call;
2271 22 : if (*jump_target)
2272 : return NULL_TREE;
2273 : }
2274 : }
2275 22 : if (TREE_CODE (args[0]) != CONSTRUCTOR
2276 22 : || CONSTRUCTOR_NELTS (args[0]) != 1)
2277 : {
2278 0 : invalid_std_rethrow:
2279 0 : if (!ctx->quiet)
2280 0 : error_at (loc, "%qD called with unexpected %qs argument",
2281 : fndecl, "std::exception_ptr");
2282 0 : *non_constant_p = true;
2283 0 : return void_node;
2284 : }
2285 22 : arg = cxa_check_throw_arg (CONSTRUCTOR_ELT (args[0], 0)->value, false);
2286 22 : if (arg == NULL_TREE)
2287 0 : goto invalid_std_rethrow;
2288 22 : DECL_EXCEPTION_REFCOUNT (arg)
2289 22 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
2290 22 : ++ctx->global->uncaught_exceptions;
2291 22 : *jump_target = arg;
2292 22 : return void_node;
2293 71 : case BUILTIN_EH_PTR_ADJUST_REF:
2294 71 : if (nargs != 2)
2295 0 : goto invalid_nargs;
2296 71 : arg = cxa_check_throw_arg (args[0], false);
2297 71 : if (arg == NULL_TREE)
2298 0 : goto invalid_ptr;
2299 71 : if (integer_onep (args[1]))
2300 28 : DECL_EXCEPTION_REFCOUNT (arg)
2301 56 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
2302 : size_one_node);
2303 43 : else if (integer_minus_onep (args[1]))
2304 43 : goto free_except;
2305 : else
2306 : {
2307 0 : if (!ctx->quiet)
2308 0 : error_at (loc, "%qD called with second argument "
2309 : "other than 1 or -1", fndecl);
2310 0 : *non_constant_p = true;
2311 : }
2312 28 : return void_node;
2313 0 : default:
2314 0 : gcc_unreachable ();
2315 : }
2316 : }
2317 :
2318 : /* Variables and functions to manage constexpr call expansion context.
2319 : These do not need to be marked for PCH or GC. */
2320 :
2321 : /* FIXME remember and print actual constant arguments. */
2322 : static vec<tree> call_stack;
2323 : static int call_stack_tick;
2324 : static int last_cx_error_tick;
2325 :
2326 : /* Attempt to evaluate T which represents a call to __builtin_constexpr_diag.
2327 : The arguments should be an integer (0 for inform, 1 for warning, 2 for
2328 : error) optionally with 16 ored in if it should use caller's caller location
2329 : instead of caller's location and 2 messages which are either a pointer to
2330 : a STRING_CST or class with data () and size () member functions like
2331 : string_view or u8string_view. The first message is a tag, with "" passed
2332 : for no tag, data () should return const char *, the tag should only contain
2333 : alphanumeric letters or underscores. The second message is the diagnostic
2334 : message, data () can be either const char * or const char8_t *. size ()
2335 : should return the corresponding length of the strings in bytes as an
2336 : integer. */
2337 :
2338 : static tree
2339 101 : cxx_eval_constexpr_diag (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
2340 : bool *overflow_p, tree *jump_target)
2341 : {
2342 101 : location_t loc = EXPR_LOCATION (t);
2343 101 : if (call_expr_nargs (t) != 3)
2344 : {
2345 6 : if (!ctx->quiet)
2346 6 : error_at (loc, "wrong number of arguments to %qs call",
2347 : "__builtin_constexpr_diag");
2348 6 : *non_constant_p = true;
2349 6 : return t;
2350 : }
2351 : tree args[3];
2352 380 : for (int i = 0; i < 3; ++i)
2353 : {
2354 285 : tree arg = convert_from_reference (CALL_EXPR_ARG (t, i));
2355 285 : arg = cxx_eval_constant_expression (ctx, arg,
2356 : (i == 0
2357 257 : || POINTER_TYPE_P (TREE_TYPE (arg)))
2358 475 : ? vc_prvalue : vc_glvalue,
2359 : non_constant_p, overflow_p,
2360 : jump_target);
2361 285 : if (*jump_target)
2362 : return NULL_TREE;
2363 285 : if (*non_constant_p)
2364 : return t;
2365 285 : args[i] = arg;
2366 : }
2367 190 : if (TREE_CODE (args[0]) != INTEGER_CST
2368 95 : || wi::to_widest (args[0]) < 0
2369 93 : || wi::to_widest (args[0]) > 18
2370 190 : || (wi::to_widest (args[0]) & 15) > 2)
2371 : {
2372 4 : if (!ctx->quiet)
2373 4 : error_at (loc, "first %qs call argument should be 0, 1, 2, 16, 17 or "
2374 : "18", "__builtin_constexpr_diag");
2375 4 : *non_constant_p = true;
2376 4 : return t;
2377 : }
2378 91 : const char *msgs[2] = {};
2379 91 : int lens[3] = {};
2380 546 : cexpr_str cstrs[2];
2381 227 : diagnostics::kind kind = diagnostics::kind::error;
2382 227 : for (int i = 1; i < 3; ++i)
2383 : {
2384 164 : tree arg = args[i];
2385 164 : if (POINTER_TYPE_P (TREE_TYPE (arg)))
2386 : {
2387 97 : tree str = arg;
2388 97 : STRIP_NOPS (str);
2389 97 : if (TREE_CODE (str) == ADDR_EXPR
2390 97 : && TREE_CODE (TREE_OPERAND (str, 0)) == STRING_CST)
2391 : {
2392 97 : str = TREE_OPERAND (str, 0);
2393 97 : tree eltype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)));
2394 97 : if (eltype == char_type_node
2395 12 : || (i == 2 && eltype == char8_type_node))
2396 164 : arg = str;
2397 : }
2398 : }
2399 164 : cstrs[i - 1].message = arg;
2400 164 : if (!cstrs[i - 1].type_check (loc, i == 2))
2401 : {
2402 20 : *non_constant_p = true;
2403 20 : return t;
2404 : }
2405 144 : if (!cstrs[i - 1].extract (loc, msgs[i - 1], lens[i - 1], ctx,
2406 : non_constant_p, overflow_p, jump_target))
2407 : {
2408 8 : if (*jump_target)
2409 : return NULL_TREE;
2410 8 : *non_constant_p = true;
2411 8 : return t;
2412 : }
2413 : }
2414 63 : if (msgs[0])
2415 : {
2416 359 : for (int i = 0; i < lens[0]; ++i)
2417 298 : if (!ISALNUM (msgs[0][i]) && msgs[0][i] != '_')
2418 : {
2419 2 : if (!ctx->quiet)
2420 2 : error_at (loc, "%qs tag string contains %qc character other than"
2421 : " letters, digits or %<_%>",
2422 : "__builtin_constexpr_diag", msgs[0][i]);
2423 2 : *non_constant_p = true;
2424 2 : return t;
2425 : }
2426 : }
2427 61 : if (ctx->manifestly_const_eval == mce_unknown)
2428 : {
2429 0 : *non_constant_p = true;
2430 0 : return t;
2431 : }
2432 61 : int arg0 = tree_to_uhwi (args[0]);
2433 61 : if (arg0 & 16)
2434 : {
2435 16 : arg0 &= 15;
2436 16 : if (!call_stack.is_empty ())
2437 : {
2438 16 : tree call = call_stack.last ();
2439 16 : if (EXPR_HAS_LOCATION (call))
2440 16 : loc = EXPR_LOCATION (call);
2441 : }
2442 : }
2443 61 : if (arg0 == 0)
2444 : kind = diagnostics::kind::note;
2445 39 : else if (arg0 == 1)
2446 18 : kind = diagnostics::kind::warning;
2447 61 : if (lens[0])
2448 : {
2449 44 : const char *color = "error";
2450 44 : if (kind == diagnostics::kind::note)
2451 : color = "note";
2452 30 : else if (kind == diagnostics::kind::warning)
2453 16 : color = "warning";
2454 44 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s [%r%.*s%R]",
2455 : lens[1], msgs[1], color, lens[0], msgs[0]);
2456 : }
2457 : else
2458 17 : emit_diagnostic (kind, loc, 0, "constexpr message: %.*s",
2459 : lens[1], msgs[1]);
2460 61 : return void_node;
2461 273 : }
2462 :
2463 : /* Attempt to evaluate T which represents a call to a builtin function.
2464 : We assume here that all builtin functions evaluate to scalar types
2465 : represented by _CST nodes. */
2466 :
2467 : static tree
2468 16889484 : cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
2469 : value_cat lval,
2470 : bool *non_constant_p, bool *overflow_p,
2471 : tree *jump_target)
2472 : {
2473 16889484 : const int nargs = call_expr_nargs (t);
2474 16889484 : tree *args = (tree *) alloca (nargs * sizeof (tree));
2475 16889484 : tree new_call;
2476 16889484 : int i;
2477 :
2478 : /* Don't fold __builtin_constant_p within a constexpr function. */
2479 16889484 : bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
2480 :
2481 : /* If we aren't requiring a constant expression, defer __builtin_constant_p
2482 : in a constexpr function until we have values for the parameters. */
2483 2026319 : if (bi_const_p
2484 2026319 : && ctx->manifestly_const_eval != mce_true
2485 1914713 : && current_function_decl
2486 1913555 : && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2487 : {
2488 1630443 : *non_constant_p = true;
2489 1630443 : return t;
2490 : }
2491 :
2492 : /* For __builtin_is_constant_evaluated, defer it if not
2493 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
2494 : without manifestly_const_eval even expressions or parts thereof which
2495 : will later be manifestly const_eval evaluated), otherwise fold it to
2496 : true. */
2497 15259041 : if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
2498 : BUILT_IN_FRONTEND))
2499 : {
2500 5802388 : if (ctx->manifestly_const_eval == mce_unknown)
2501 : {
2502 5768729 : *non_constant_p = true;
2503 5768729 : return t;
2504 : }
2505 33659 : return constant_boolean_node (ctx->manifestly_const_eval == mce_true,
2506 33659 : boolean_type_node);
2507 : }
2508 :
2509 9456653 : if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND))
2510 : {
2511 4467 : temp_override<tree> ovr (current_function_decl);
2512 4467 : if (ctx->call && ctx->call->fundef)
2513 1404 : current_function_decl = ctx->call->fundef->decl;
2514 4467 : return fold_builtin_source_location (t);
2515 4467 : }
2516 :
2517 9452186 : if (fndecl_built_in_p (fun, CP_BUILT_IN_EH_PTR_ADJUST_REF,
2518 : BUILT_IN_FRONTEND))
2519 71 : return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_EH_PTR_ADJUST_REF,
2520 : fun, non_constant_p, overflow_p,
2521 71 : jump_target);
2522 :
2523 9452115 : if (fndecl_built_in_p (fun, CP_BUILT_IN_CONSTEXPR_DIAG, BUILT_IN_FRONTEND))
2524 101 : return cxx_eval_constexpr_diag (ctx, t, non_constant_p, overflow_p,
2525 101 : jump_target);
2526 :
2527 9452014 : int strops = 0;
2528 9452014 : int strret = 0;
2529 9452014 : if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
2530 8743952 : switch (DECL_FUNCTION_CODE (fun))
2531 : {
2532 : case BUILT_IN_STRLEN:
2533 : case BUILT_IN_STRNLEN:
2534 9451918 : strops = 1;
2535 : break;
2536 110374 : case BUILT_IN_MEMCHR:
2537 110374 : case BUILT_IN_STRCHR:
2538 110374 : case BUILT_IN_STRRCHR:
2539 110374 : strops = 1;
2540 110374 : strret = 1;
2541 110374 : break;
2542 71047 : case BUILT_IN_MEMCMP:
2543 71047 : case BUILT_IN_STRCMP:
2544 71047 : strops = 2;
2545 71047 : break;
2546 28542 : case BUILT_IN_STRSTR:
2547 28542 : strops = 2;
2548 28542 : strret = 1;
2549 28542 : break;
2550 42 : case BUILT_IN_ASAN_POINTER_COMPARE:
2551 42 : case BUILT_IN_ASAN_POINTER_SUBTRACT:
2552 42 : case BUILT_IN_OBSERVABLE_CHKPT:
2553 : /* These builtins shall be ignored during constant expression
2554 : evaluation. */
2555 42 : return void_node;
2556 54 : case BUILT_IN_UNREACHABLE:
2557 54 : case BUILT_IN_TRAP:
2558 54 : if (!*non_constant_p && !ctx->quiet)
2559 : {
2560 : /* Do not allow__builtin_unreachable in constexpr function.
2561 : The __builtin_unreachable call with BUILTINS_LOCATION
2562 : comes from cp_maybe_instrument_return. */
2563 13 : if (EXPR_LOCATION (t) == BUILTINS_LOCATION)
2564 0 : error ("%<constexpr%> call flows off the end of the function");
2565 : else
2566 13 : error ("%q+E is not a constant expression", t);
2567 : }
2568 54 : *non_constant_p = true;
2569 54 : return t;
2570 : default:
2571 : break;
2572 : }
2573 :
2574 : /* Be permissive for arguments to built-ins; __builtin_constant_p should
2575 : return constant false for a non-constant argument. */
2576 9451918 : constexpr_ctx new_ctx = *ctx;
2577 9451918 : new_ctx.quiet = true;
2578 26009625 : for (i = 0; i < nargs; ++i)
2579 : {
2580 16557708 : tree arg = CALL_EXPR_ARG (t, i);
2581 16557708 : tree oarg = arg;
2582 :
2583 : /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
2584 : expand_builtin doesn't know how to look in the values table. */
2585 16557708 : bool strop = i < strops;
2586 16557708 : if (strop)
2587 : {
2588 445085 : STRIP_NOPS (arg);
2589 445085 : if (TREE_CODE (arg) == ADDR_EXPR)
2590 7815 : arg = TREE_OPERAND (arg, 0);
2591 : else
2592 : strop = false;
2593 : }
2594 :
2595 : /* If builtin_valid_in_constant_expr_p is true,
2596 : potential_constant_expression_1 has not recursed into the arguments
2597 : of the builtin, verify it here. */
2598 16557708 : if (!builtin_valid_in_constant_expr_p (fun)
2599 16557708 : || potential_constant_expression (arg))
2600 : {
2601 16557577 : bool dummy1 = false, dummy2 = false;
2602 16557577 : tree jmp_target = NULL_TREE;
2603 16557577 : arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
2604 : &dummy1, &dummy2, &jmp_target);
2605 16557576 : if (jmp_target)
2606 : {
2607 0 : *jump_target = jmp_target;
2608 0 : return NULL_TREE;
2609 : }
2610 : }
2611 :
2612 16557707 : if (bi_const_p)
2613 : /* For __builtin_constant_p, fold all expressions with constant values
2614 : even if they aren't C++ constant-expressions. */
2615 395875 : arg = cp_fold_rvalue (arg);
2616 16161832 : else if (strop)
2617 : {
2618 7815 : if (TREE_CODE (arg) == CONSTRUCTOR)
2619 100 : arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
2620 7815 : if (TREE_CODE (arg) == STRING_CST)
2621 2900 : arg = build_address (arg);
2622 : else
2623 : arg = oarg;
2624 : }
2625 :
2626 16557707 : args[i] = arg;
2627 : }
2628 :
2629 9451917 : bool save_ffbcp = force_folding_builtin_constant_p;
2630 9451917 : force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true;
2631 9451917 : tree save_cur_fn = current_function_decl;
2632 : /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */
2633 9451917 : if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION)
2634 38 : && ctx->call
2635 9451921 : && ctx->call->fundef)
2636 4 : current_function_decl = ctx->call->fundef->decl;
2637 9451917 : if (fndecl_built_in_p (fun,
2638 : CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
2639 : BUILT_IN_FRONTEND))
2640 : {
2641 336 : location_t loc = EXPR_LOCATION (t);
2642 336 : if (nargs >= 1)
2643 333 : VERIFY_CONSTANT (args[0]);
2644 136 : new_call
2645 136 : = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
2646 : args);
2647 : }
2648 9451581 : else if (fndecl_built_in_p (fun,
2649 : CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
2650 : BUILT_IN_FRONTEND))
2651 : {
2652 471 : location_t loc = EXPR_LOCATION (t);
2653 471 : if (nargs >= 2)
2654 : {
2655 465 : VERIFY_CONSTANT (args[0]);
2656 237 : VERIFY_CONSTANT (args[1]);
2657 : }
2658 243 : new_call = fold_builtin_is_corresponding_member (loc, nargs, args);
2659 : }
2660 9451110 : else if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_STRING_LITERAL,
2661 : BUILT_IN_FRONTEND))
2662 : {
2663 1778 : location_t loc = EXPR_LOCATION (t);
2664 1778 : if (nargs >= 1)
2665 : {
2666 1778 : tree arg = CALL_EXPR_ARG (t, 0);
2667 1778 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
2668 : non_constant_p, overflow_p,
2669 : jump_target);
2670 1778 : if (*jump_target)
2671 : return NULL_TREE;
2672 1778 : args[0] = arg;
2673 : }
2674 1778 : new_call = fold_builtin_is_string_literal (loc, nargs, args);
2675 : }
2676 : else
2677 18898664 : new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
2678 9449332 : CALL_EXPR_FN (t), nargs, args);
2679 9451489 : current_function_decl = save_cur_fn;
2680 9451489 : force_folding_builtin_constant_p = save_ffbcp;
2681 9451489 : if (new_call == NULL)
2682 : {
2683 6574660 : if (!*non_constant_p && !ctx->quiet)
2684 : {
2685 0 : new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
2686 0 : CALL_EXPR_FN (t), nargs, args);
2687 0 : error ("%q+E is not a constant expression", new_call);
2688 : }
2689 6574660 : *non_constant_p = true;
2690 6574660 : return t;
2691 : }
2692 :
2693 2876829 : if (!potential_constant_expression (new_call))
2694 : {
2695 730 : if (!*non_constant_p && !ctx->quiet)
2696 4 : error ("%q+E is not a constant expression", new_call);
2697 730 : *non_constant_p = true;
2698 730 : return t;
2699 : }
2700 :
2701 2876099 : if (strret)
2702 : {
2703 : /* memchr returns a pointer into the first argument, but we replaced the
2704 : argument above with a STRING_CST; put it back it now. */
2705 119 : tree op = CALL_EXPR_ARG (t, strret-1);
2706 119 : STRIP_NOPS (new_call);
2707 119 : if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
2708 60 : TREE_OPERAND (new_call, 0) = op;
2709 59 : else if (TREE_CODE (new_call) == ADDR_EXPR)
2710 2876099 : new_call = op;
2711 : }
2712 :
2713 2876099 : return cxx_eval_constant_expression (&new_ctx, new_call, lval,
2714 : non_constant_p, overflow_p,
2715 2876099 : jump_target);
2716 : }
2717 :
2718 : /* TEMP is the constant value of a temporary object of type TYPE. Adjust
2719 : the type of the value to match. */
2720 :
2721 : static tree
2722 137976864 : adjust_temp_type (tree type, tree temp)
2723 : {
2724 137976864 : if (same_type_p (TREE_TYPE (temp), type))
2725 : return temp;
2726 : /* Avoid wrapping an aggregate value in a NOP_EXPR. */
2727 72419586 : if (TREE_CODE (temp) == CONSTRUCTOR)
2728 : {
2729 : /* build_constructor wouldn't retain various CONSTRUCTOR flags. */
2730 3325399 : tree t = copy_node (temp);
2731 3325399 : TREE_TYPE (t) = type;
2732 3325399 : return t;
2733 : }
2734 69094187 : if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
2735 0 : return build0 (EMPTY_CLASS_EXPR, type);
2736 69094187 : gcc_assert (scalarish_type_p (type));
2737 : /* Now we know we're dealing with a scalar, and a prvalue of non-class
2738 : type is cv-unqualified. */
2739 69094187 : return cp_fold_convert (cv_unqualified (type), temp);
2740 : }
2741 :
2742 : /* If T is a CONSTRUCTOR, return an unshared copy of T and any
2743 : sub-CONSTRUCTORs. Otherwise return T.
2744 :
2745 : We use this whenever we initialize an object as a whole, whether it's a
2746 : parameter, a local variable, or a subobject, so that subsequent
2747 : modifications don't affect other places where it was used. */
2748 :
2749 : tree
2750 86204649 : unshare_constructor (tree t MEM_STAT_DECL)
2751 : {
2752 86204649 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
2753 : return t;
2754 16294399 : auto_vec <tree*, 4> ptrs;
2755 16294399 : ptrs.safe_push (&t);
2756 16294399 : while (!ptrs.is_empty ())
2757 : {
2758 19353321 : tree *p = ptrs.pop ();
2759 19353321 : tree n = copy_node (*p PASS_MEM_STAT);
2760 30784799 : CONSTRUCTOR_ELTS (n) = vec_safe_copy (CONSTRUCTOR_ELTS (*p) PASS_MEM_STAT);
2761 19353321 : *p = n;
2762 19353321 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n);
2763 19353321 : constructor_elt *ce;
2764 78585329 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i)
2765 23584288 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
2766 3058922 : ptrs.safe_push (&ce->value);
2767 : }
2768 16294399 : return t;
2769 16294399 : }
2770 :
2771 : /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs. */
2772 :
2773 : static void
2774 865109 : free_constructor (tree t)
2775 : {
2776 865109 : if (!t || TREE_CODE (t) != CONSTRUCTOR)
2777 0 : return;
2778 865109 : releasing_vec ctors;
2779 865109 : vec_safe_push (ctors, t);
2780 1767961 : while (!ctors->is_empty ())
2781 : {
2782 902852 : tree c = ctors->pop ();
2783 902852 : if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c))
2784 : {
2785 : constructor_elt *ce;
2786 314934 : for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
2787 203149 : if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
2788 37743 : vec_safe_push (ctors, ce->value);
2789 111785 : ggc_free (elts);
2790 : }
2791 902852 : ggc_free (c);
2792 : }
2793 865109 : }
2794 :
2795 : /* Helper function of cxx_bind_parameters_in_call. Return non-NULL
2796 : if *TP is address of a static variable (or part of it) currently being
2797 : constructed or of a heap artificial variable. */
2798 :
2799 : static tree
2800 32861837 : addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data)
2801 : {
2802 32861837 : if (TREE_CODE (*tp) == ADDR_EXPR)
2803 5998278 : if (tree var = get_base_address (TREE_OPERAND (*tp, 0)))
2804 5998278 : if (VAR_P (var) && TREE_STATIC (var))
2805 : {
2806 2369210 : if (DECL_NAME (var) == heap_uninit_identifier
2807 2369210 : || DECL_NAME (var) == heap_identifier
2808 2369210 : || DECL_NAME (var) == heap_vec_uninit_identifier
2809 4738420 : || DECL_NAME (var) == heap_vec_identifier)
2810 : return var;
2811 :
2812 2369210 : constexpr_global_ctx *global = (constexpr_global_ctx *) data;
2813 2369210 : if (global->get_value (var))
2814 : return var;
2815 : }
2816 32497386 : if (TYPE_P (*tp))
2817 1778 : *walk_subtrees = false;
2818 : return NULL_TREE;
2819 : }
2820 :
2821 : /* Subroutine of cxx_eval_call_expression.
2822 : We are processing a call expression (either CALL_EXPR or
2823 : AGGR_INIT_EXPR) in the context of CTX. Evaluate
2824 : all arguments and bind their values to correspondings
2825 : parameters, making up the NEW_CALL context. */
2826 :
2827 : static tree
2828 181046300 : cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
2829 : tree orig_fun, bool *non_constant_p,
2830 : bool *overflow_p, bool *non_constant_args,
2831 : tree *jump_target)
2832 : {
2833 181046300 : int nargs = call_expr_nargs (t);
2834 181046300 : tree parms = DECL_ARGUMENTS (fun);
2835 181046300 : int i, j = 0;
2836 181046300 : if (DECL_HAS_IN_CHARGE_PARM_P (fun) && fun != orig_fun)
2837 1239 : ++nargs;
2838 181046300 : if (DECL_HAS_VTT_PARM_P (fun)
2839 1241 : && fun != orig_fun
2840 181047539 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
2841 902 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
2842 348 : ++nargs;
2843 : /* We don't record ellipsis args below. */
2844 181046300 : int nparms = list_length (parms);
2845 181046300 : int nbinds = nargs < nparms ? nargs : nparms;
2846 181046300 : tree binds = make_tree_vec (nbinds);
2847 :
2848 : /* The call is not a constant expression if it involves the cdtor for a type
2849 : with virtual bases before C++26. */
2850 181046300 : if (cxx_dialect < cxx26
2851 181046300 : && (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun)))
2852 : {
2853 17 : if (!ctx->quiet)
2854 : {
2855 3 : error_at (cp_expr_loc_or_input_loc (t),
2856 : "call to non-%<constexpr%> function %qD", fun);
2857 3 : explain_invalid_constexpr_fn (fun);
2858 : }
2859 17 : *non_constant_p = true;
2860 17 : return binds;
2861 : }
2862 :
2863 308548720 : for (i = 0; i < nargs; ++i)
2864 : {
2865 210604156 : tree x, arg;
2866 210604156 : tree type = parms ? TREE_TYPE (parms) : void_type_node;
2867 210604156 : if (parms && DECL_BY_REFERENCE (parms))
2868 8432 : type = TREE_TYPE (type);
2869 210604156 : if (i == 1
2870 210604156 : && j == 0
2871 44542362 : && DECL_HAS_IN_CHARGE_PARM_P (fun)
2872 210605284 : && orig_fun != fun)
2873 : {
2874 1128 : if (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
2875 1128 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))
2876 328 : x = boolean_true_node;
2877 : else
2878 800 : x = boolean_false_node;
2879 : j = -1;
2880 : }
2881 210603028 : else if (i == 2
2882 210603028 : && j == -1
2883 1128 : && DECL_HAS_VTT_PARM_P (fun)
2884 1128 : && orig_fun != fun
2885 210604156 : && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
2886 811 : || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
2887 : {
2888 328 : x = build_zero_cst (type);
2889 328 : j = -2;
2890 : }
2891 : else
2892 210602700 : x = get_nth_callarg (t, i + j);
2893 : /* For member function, the first argument is a pointer to the implied
2894 : object. For a constructor, it might still be a dummy object, in
2895 : which case we get the real argument from ctx. */
2896 316497566 : if (i == 0 && DECL_CONSTRUCTOR_P (fun)
2897 238301204 : && is_dummy_object (x))
2898 : {
2899 14078918 : x = ctx->object;
2900 14078918 : x = build_address (x);
2901 : }
2902 210604156 : if (TREE_ADDRESSABLE (type))
2903 : {
2904 : /* Undo convert_for_arg_passing work here. */
2905 14583 : x = convert_from_reference (x);
2906 14583 : arg = cxx_eval_constant_expression (ctx, x, vc_glvalue,
2907 : non_constant_p, overflow_p,
2908 : jump_target);
2909 : }
2910 : else
2911 : /* Normally we would strip a TARGET_EXPR in an initialization context
2912 : such as this, but here we do the elision differently: we keep the
2913 : TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */
2914 210589573 : arg = cxx_eval_constant_expression (ctx, x, vc_prvalue,
2915 : non_constant_p, overflow_p,
2916 : jump_target);
2917 210604156 : if (*jump_target)
2918 : break;
2919 : /* Check we aren't dereferencing a null pointer when calling a non-static
2920 : member function, which is undefined behaviour. */
2921 158248777 : if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun)
2922 107896548 : && integer_zerop (arg)
2923 : /* But ignore calls from within compiler-generated code, to handle
2924 : cases like lambda function pointer conversion operator thunks
2925 : which pass NULL as the 'this' pointer. */
2926 210752385 : && !(TREE_CODE (t) == CALL_EXPR && CALL_FROM_THUNK_P (t)))
2927 : {
2928 476 : if (!ctx->quiet)
2929 6 : error_at (cp_expr_loc_or_input_loc (x),
2930 : "dereferencing a null pointer");
2931 476 : *non_constant_p = true;
2932 : }
2933 : /* Don't VERIFY_CONSTANT here. */
2934 210604146 : if (*non_constant_p && ctx->quiet)
2935 : break;
2936 : /* Just discard ellipsis args after checking their constantitude. */
2937 127502437 : if (!parms)
2938 283 : continue;
2939 :
2940 127502154 : if (!*non_constant_p)
2941 : {
2942 : /* Make sure the binding has the same type as the parm. But
2943 : only for constant args. */
2944 127501555 : if (TREE_ADDRESSABLE (type))
2945 : {
2946 8987 : if (!same_type_p (type, TREE_TYPE (arg)))
2947 : {
2948 9 : arg = build_fold_addr_expr (arg);
2949 9 : arg = cp_fold_convert (build_reference_type (type), arg);
2950 9 : arg = convert_from_reference (arg);
2951 : }
2952 : }
2953 127492568 : else if (!TYPE_REF_P (type))
2954 104951221 : arg = adjust_temp_type (type, arg);
2955 127501555 : if (!TREE_CONSTANT (arg))
2956 90559656 : *non_constant_args = true;
2957 36941899 : else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
2958 : /* The destructor needs to see any modifications the callee makes
2959 : to the argument. */
2960 0 : *non_constant_args = true;
2961 : /* If arg is or contains address of a heap artificial variable or
2962 : of a static variable being constructed, avoid caching the
2963 : function call, as those variables might be modified by the
2964 : function, or might be modified by the callers in between
2965 : the cached function and just read by the function. */
2966 36941899 : else if (!*non_constant_args
2967 36941899 : && cp_walk_tree (&arg, addr_of_non_const_var, ctx->global,
2968 : NULL))
2969 364451 : *non_constant_args = true;
2970 :
2971 : /* For virtual calls, adjust the this argument, so that it is
2972 : the object on which the method is called, rather than
2973 : one of its bases. */
2974 127501555 : if (i == 0 && DECL_VIRTUAL_P (fun))
2975 : {
2976 20680 : tree addr = arg;
2977 20680 : STRIP_NOPS (addr);
2978 20680 : if (TREE_CODE (addr) == ADDR_EXPR)
2979 : {
2980 20660 : tree obj = TREE_OPERAND (addr, 0);
2981 20660 : while (TREE_CODE (obj) == COMPONENT_REF
2982 9787 : && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))
2983 30449 : && !same_type_ignoring_top_level_qualifiers_p
2984 9735 : (TREE_TYPE (obj), DECL_CONTEXT (fun)))
2985 54 : obj = TREE_OPERAND (obj, 0);
2986 20660 : if (obj != TREE_OPERAND (addr, 0))
2987 51 : arg = build_fold_addr_expr_with_type (obj,
2988 : TREE_TYPE (arg));
2989 : }
2990 : }
2991 127501555 : TREE_VEC_ELT (binds, i) = arg;
2992 : }
2993 127502154 : parms = TREE_CHAIN (parms);
2994 : }
2995 :
2996 : return binds;
2997 : }
2998 :
2999 : static int
3000 97277507 : push_cx_call_context (tree call)
3001 : {
3002 97277507 : ++call_stack_tick;
3003 97277507 : if (!EXPR_HAS_LOCATION (call))
3004 70797 : SET_EXPR_LOCATION (call, input_location);
3005 97277507 : call_stack.safe_push (call);
3006 97277507 : int len = call_stack.length ();
3007 97277507 : if (len > max_constexpr_depth)
3008 30 : return false;
3009 : return len;
3010 : }
3011 :
3012 : static void
3013 97277505 : pop_cx_call_context (void)
3014 : {
3015 97277505 : ++call_stack_tick;
3016 97277505 : call_stack.pop ();
3017 97277505 : }
3018 :
3019 : vec<tree>
3020 225403 : cx_error_context (void)
3021 : {
3022 225403 : vec<tree> r = vNULL;
3023 225403 : if (call_stack_tick != last_cx_error_tick
3024 225403 : && !call_stack.is_empty ())
3025 : r = call_stack;
3026 225403 : last_cx_error_tick = call_stack_tick;
3027 225403 : return r;
3028 : }
3029 :
3030 : /* E is an operand of a failed assertion, fold it either with or without
3031 : constexpr context. */
3032 :
3033 : static tree
3034 559 : fold_operand (tree e, const constexpr_ctx *ctx)
3035 : {
3036 559 : if (ctx)
3037 : {
3038 32 : bool new_non_constant_p = false, new_overflow_p = false;
3039 32 : tree jmp_target = NULL_TREE;
3040 32 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
3041 : &new_non_constant_p,
3042 : &new_overflow_p, &jmp_target);
3043 : }
3044 : else
3045 527 : e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true);
3046 559 : return e;
3047 : }
3048 :
3049 : /* If we have a condition in conjunctive normal form (CNF), find the first
3050 : failing clause. In other words, given an expression like
3051 :
3052 : true && true && false && true && false
3053 :
3054 : return the first 'false'. EXPR is the expression. */
3055 :
3056 : static tree
3057 320 : find_failing_clause_r (const constexpr_ctx *ctx, tree expr)
3058 : {
3059 421 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3060 : {
3061 : /* First check the left side... */
3062 186 : tree e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 0));
3063 186 : if (e == NULL_TREE)
3064 : /* ...if we didn't find a false clause, check the right side. */
3065 101 : e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 1));
3066 : return e;
3067 : }
3068 235 : tree e = contextual_conv_bool (expr, tf_none);
3069 235 : e = fold_operand (e, ctx);
3070 235 : if (integer_zerop (e))
3071 : /* This is the failing clause. */
3072 134 : return expr;
3073 : return NULL_TREE;
3074 : }
3075 :
3076 : /* Wrapper for find_failing_clause_r. */
3077 :
3078 : tree
3079 1586 : find_failing_clause (const constexpr_ctx *ctx, tree expr)
3080 : {
3081 1586 : if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
3082 134 : if (tree e = find_failing_clause_r (ctx, expr))
3083 1586 : expr = e;
3084 1586 : return expr;
3085 : }
3086 :
3087 : /* Emit additional diagnostics for failing condition BAD.
3088 : Used by finish_static_assert and IFN_ASSUME constexpr diagnostics.
3089 : If SHOW_EXPR_P is true, print the condition (because it was
3090 : instantiation-dependent). */
3091 :
3092 : void
3093 1586 : diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p,
3094 : const constexpr_ctx *ctx /* = nullptr */)
3095 : {
3096 : /* Nobody wants to see the artificial (bool) cast. */
3097 1586 : bad = tree_strip_nop_conversions (bad);
3098 1586 : if (TREE_CODE (bad) == CLEANUP_POINT_EXPR)
3099 3 : bad = TREE_OPERAND (bad, 0);
3100 :
3101 1586 : auto_diagnostic_nesting_level sentinel;
3102 :
3103 : /* Actually explain the failure if this is a concept check or a
3104 : requires-expression. */
3105 1586 : if (concept_check_p (bad) || TREE_CODE (bad) == REQUIRES_EXPR)
3106 287 : diagnose_constraints (cloc, bad, NULL_TREE);
3107 : /* Similarly if this is a standard trait. */
3108 1299 : else if (maybe_diagnose_standard_trait (cloc, bad))
3109 : ;
3110 971 : else if (COMPARISON_CLASS_P (bad)
3111 971 : && (ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))
3112 21 : || REFLECTION_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))))
3113 : {
3114 162 : tree op0 = fold_operand (TREE_OPERAND (bad, 0), ctx);
3115 162 : tree op1 = fold_operand (TREE_OPERAND (bad, 1), ctx);
3116 162 : tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
3117 162 : inform (cloc, "the comparison reduces to %qE", cond);
3118 : }
3119 809 : else if (show_expr_p)
3120 567 : inform (cloc, "%qE evaluates to false", bad);
3121 1586 : }
3122 :
3123 : /* Process an assert/assume of ORIG_ARG. If it's not supposed to be evaluated,
3124 : do it without changing the current evaluation state. If it evaluates to
3125 : false, complain and return false; otherwise, return true. */
3126 :
3127 : static bool
3128 173449 : cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg,
3129 : location_t loc, bool evaluated,
3130 : bool *non_constant_p, bool *overflow_p)
3131 : {
3132 173449 : if (*non_constant_p)
3133 : return true;
3134 :
3135 173449 : tree eval, jmp_target = NULL_TREE;
3136 173449 : if (!evaluated)
3137 : {
3138 173449 : if (!potential_rvalue_constant_expression (arg))
3139 16 : return true;
3140 :
3141 173433 : constexpr_ctx new_ctx = *ctx;
3142 173433 : new_ctx.quiet = true;
3143 173433 : bool new_non_constant_p = false, new_overflow_p = false;
3144 : /* Avoid modification of existing values. */
3145 173433 : modifiable_tracker ms (new_ctx.global);
3146 173433 : eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
3147 : &new_non_constant_p,
3148 : &new_overflow_p, &jmp_target);
3149 173433 : }
3150 : else
3151 0 : eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
3152 : non_constant_p,
3153 : overflow_p, &jmp_target);
3154 173433 : if (jmp_target)
3155 : return true;
3156 :
3157 173433 : if (!*non_constant_p && integer_zerop (eval))
3158 : {
3159 42 : if (!ctx->quiet)
3160 : {
3161 : /* See if we can find which clause was failing
3162 : (for logical AND). */
3163 13 : tree bad = find_failing_clause (ctx, arg);
3164 : /* If not, or its location is unusable, fall back to the
3165 : previous location. */
3166 13 : location_t cloc = cp_expr_loc_or_loc (bad, loc);
3167 :
3168 : /* Report the error. */
3169 13 : auto_diagnostic_group d;
3170 13 : error_at (cloc, msg);
3171 13 : diagnose_failing_condition (bad, cloc, true, ctx);
3172 13 : return bad;
3173 13 : }
3174 29 : *non_constant_p = true;
3175 29 : return false;
3176 : }
3177 :
3178 : return true;
3179 : }
3180 :
3181 : /* Evaluate a call T to a GCC internal function when possible and return
3182 : the evaluated result or, under the control of CTX, give an error, set
3183 : NON_CONSTANT_P, and return the unevaluated call T otherwise. */
3184 :
3185 : static tree
3186 365180 : cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
3187 : value_cat lval,
3188 : bool *non_constant_p, bool *overflow_p,
3189 : tree *jump_target)
3190 : {
3191 365180 : enum tree_code opcode = ERROR_MARK;
3192 :
3193 365180 : switch (CALL_EXPR_IFN (t))
3194 : {
3195 179 : case IFN_UBSAN_NULL:
3196 179 : case IFN_UBSAN_BOUNDS:
3197 179 : case IFN_UBSAN_VPTR:
3198 179 : case IFN_FALLTHROUGH:
3199 179 : return void_node;
3200 :
3201 173449 : case IFN_ASSUME:
3202 173449 : if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0),
3203 : G_("failed %<assume%> attribute assumption"),
3204 173449 : EXPR_LOCATION (t), /*eval*/false,
3205 : non_constant_p, overflow_p))
3206 : return t;
3207 173420 : return void_node;
3208 :
3209 : case IFN_ADD_OVERFLOW:
3210 : opcode = PLUS_EXPR;
3211 : break;
3212 360 : case IFN_SUB_OVERFLOW:
3213 360 : opcode = MINUS_EXPR;
3214 360 : break;
3215 188640 : case IFN_MUL_OVERFLOW:
3216 188640 : opcode = MULT_EXPR;
3217 188640 : break;
3218 :
3219 74 : case IFN_LAUNDER:
3220 74 : return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3221 : vc_prvalue, non_constant_p,
3222 74 : overflow_p, jump_target);
3223 :
3224 0 : case IFN_DEFERRED_INIT:
3225 0 : return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
3226 :
3227 2011 : case IFN_VEC_CONVERT:
3228 2011 : {
3229 2011 : tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
3230 : vc_prvalue, non_constant_p,
3231 : overflow_p, jump_target);
3232 2011 : if (*jump_target)
3233 : return NULL_TREE;
3234 2011 : if (TREE_CODE (arg) == VECTOR_CST)
3235 1912 : if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
3236 : return r;
3237 : }
3238 : /* FALLTHRU */
3239 :
3240 104 : default:
3241 104 : if (!ctx->quiet)
3242 0 : error_at (cp_expr_loc_or_input_loc (t),
3243 : "call to internal function %qE", t);
3244 104 : *non_constant_p = true;
3245 104 : return t;
3246 : }
3247 :
3248 : /* Evaluate constant arguments using OPCODE and return a complex
3249 : number containing the result and the overflow bit. */
3250 189467 : tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval,
3251 : non_constant_p, overflow_p,
3252 : jump_target);
3253 189467 : tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval,
3254 : non_constant_p, overflow_p,
3255 : jump_target);
3256 189467 : if (*jump_target)
3257 : return NULL_TREE;
3258 189467 : if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3259 : {
3260 2 : location_t loc = cp_expr_loc_or_input_loc (t);
3261 2 : tree type = TREE_TYPE (TREE_TYPE (t));
3262 2 : tree result = fold_binary_loc (loc, opcode, type,
3263 : fold_convert_loc (loc, type, arg0),
3264 : fold_convert_loc (loc, type, arg1));
3265 2 : tree ovf
3266 2 : = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1));
3267 : /* Reset TREE_OVERFLOW to avoid warnings for the overflow. */
3268 2 : if (TREE_OVERFLOW (result))
3269 0 : TREE_OVERFLOW (result) = 0;
3270 :
3271 2 : return build_complex (TREE_TYPE (t), result, ovf);
3272 : }
3273 :
3274 189465 : *non_constant_p = true;
3275 189465 : return t;
3276 : }
3277 :
3278 : /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates. */
3279 :
3280 : static void
3281 6230089 : clear_no_implicit_zero (tree ctor)
3282 : {
3283 6230089 : if (CONSTRUCTOR_NO_CLEARING (ctor))
3284 : {
3285 1535719 : CONSTRUCTOR_NO_CLEARING (ctor) = false;
3286 6806807 : for (auto &e: CONSTRUCTOR_ELTS (ctor))
3287 2268468 : if (TREE_CODE (e.value) == CONSTRUCTOR)
3288 398744 : clear_no_implicit_zero (e.value);
3289 : }
3290 6230089 : }
3291 :
3292 : /* Complain about a const object OBJ being modified in a constant expression.
3293 : EXPR is the MODIFY_EXPR expression performing the modification. */
3294 :
3295 : static void
3296 63 : modifying_const_object_error (tree expr, tree obj)
3297 : {
3298 63 : location_t loc = cp_expr_loc_or_input_loc (expr);
3299 63 : auto_diagnostic_group d;
3300 126 : error_at (loc, "modifying a const object %qE is not allowed in "
3301 63 : "a constant expression", TREE_OPERAND (expr, 0));
3302 :
3303 : /* Find the underlying object that was declared as const. */
3304 63 : location_t decl_loc = UNKNOWN_LOCATION;
3305 138 : for (tree probe = obj; decl_loc == UNKNOWN_LOCATION; )
3306 75 : switch (TREE_CODE (probe))
3307 : {
3308 39 : case BIT_FIELD_REF:
3309 39 : case COMPONENT_REF:
3310 39 : {
3311 39 : tree elt = TREE_OPERAND (probe, 1);
3312 39 : if (CP_TYPE_CONST_P (TREE_TYPE (elt)))
3313 27 : decl_loc = DECL_SOURCE_LOCATION (elt);
3314 39 : probe = TREE_OPERAND (probe, 0);
3315 : }
3316 39 : break;
3317 :
3318 0 : case ARRAY_REF:
3319 0 : case REALPART_EXPR:
3320 0 : case IMAGPART_EXPR:
3321 0 : probe = TREE_OPERAND (probe, 0);
3322 0 : break;
3323 :
3324 36 : default:
3325 36 : decl_loc = location_of (probe);
3326 36 : break;
3327 : }
3328 63 : inform (decl_loc, "originally declared %<const%> here");
3329 63 : }
3330 :
3331 : /* Return true if FNDECL is a replaceable global allocation function that
3332 : should be useable during constant expression evaluation. */
3333 :
3334 : static inline bool
3335 42294040 : cxx_replaceable_global_alloc_fn (tree fndecl)
3336 : {
3337 42294040 : return (cxx_dialect >= cxx20
3338 40734236 : && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))
3339 2178397 : && CP_DECL_CONTEXT (fndecl) == global_namespace
3340 44472047 : && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)
3341 1193580 : || DECL_IS_OPERATOR_DELETE_P (fndecl)));
3342 : }
3343 :
3344 : /* Return true if FNDECL is a placement new function that should be
3345 : useable during constant expression evaluation of std::construct_at. */
3346 :
3347 : static inline bool
3348 41118609 : cxx_placement_new_fn (tree fndecl)
3349 : {
3350 41118609 : return (cxx_dialect >= cxx20 && std_placement_new_fn_p (fndecl));
3351 : }
3352 :
3353 : /* Return true if FNDECL is std::construct_at. */
3354 :
3355 : static inline bool
3356 1419650 : is_std_construct_at (tree fndecl)
3357 : {
3358 1419650 : if (!decl_in_std_namespace_p (fndecl))
3359 : return false;
3360 :
3361 1393678 : tree name = DECL_NAME (fndecl);
3362 1393678 : return name && id_equal (name, "construct_at");
3363 : }
3364 :
3365 : /* Overload for the above taking constexpr_call*. */
3366 :
3367 : static inline bool
3368 1055223 : is_std_construct_at (const constexpr_call *call)
3369 : {
3370 1055223 : return (call
3371 789842 : && call->fundef
3372 1845065 : && is_std_construct_at (call->fundef->decl));
3373 : }
3374 :
3375 : /* True if CTX is an instance of std::NAME class. */
3376 :
3377 : bool
3378 17776014 : is_std_class (tree ctx, const char *name)
3379 : {
3380 17776014 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3381 : return false;
3382 :
3383 17775095 : tree decl = TYPE_MAIN_DECL (ctx);
3384 17775095 : tree dname = DECL_NAME (decl);
3385 17775095 : if (dname == NULL_TREE || !id_equal (dname, name))
3386 : return false;
3387 :
3388 563538 : return decl_in_std_namespace_p (decl);
3389 : }
3390 :
3391 : /* True if CTX is an instance of std::allocator. */
3392 :
3393 : bool
3394 418038 : is_std_allocator (tree ctx)
3395 : {
3396 418038 : return is_std_class (ctx, "allocator");
3397 : }
3398 :
3399 : /* Return true if FNDECL is std::allocator<T>::{,de}allocate. */
3400 :
3401 : static bool
3402 432856 : is_std_allocator_allocate (tree fndecl)
3403 : {
3404 432856 : tree name = DECL_NAME (fndecl);
3405 432856 : if (name == NULL_TREE
3406 432856 : || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
3407 : return false;
3408 :
3409 413398 : return is_std_allocator (DECL_CONTEXT (fndecl));
3410 : }
3411 :
3412 : /* Overload for the above taking constexpr_call*. */
3413 :
3414 : static inline bool
3415 264332 : is_std_allocator_allocate (const constexpr_call *call)
3416 : {
3417 264332 : return (call
3418 175467 : && call->fundef
3419 439799 : && is_std_allocator_allocate (call->fundef->decl));
3420 : }
3421 :
3422 : /* Return true if FNDECL is std::source_location::current. */
3423 :
3424 : static inline bool
3425 33337 : is_std_source_location_current (tree fndecl)
3426 : {
3427 33337 : if (!decl_in_std_namespace_p (fndecl))
3428 : return false;
3429 :
3430 24223 : tree name = DECL_NAME (fndecl);
3431 24223 : if (name == NULL_TREE || !id_equal (name, "current"))
3432 : return false;
3433 :
3434 159 : tree ctx = DECL_CONTEXT (fndecl);
3435 159 : if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
3436 : return false;
3437 :
3438 159 : name = DECL_NAME (TYPE_MAIN_DECL (ctx));
3439 159 : return name && id_equal (name, "source_location");
3440 : }
3441 :
3442 : /* Overload for the above taking constexpr_call*. */
3443 :
3444 : static inline bool
3445 41616 : is_std_source_location_current (const constexpr_call *call)
3446 : {
3447 41616 : return (call
3448 33337 : && call->fundef
3449 74953 : && is_std_source_location_current (call->fundef->decl));
3450 : }
3451 :
3452 : /* Return true if FNDECL is __dynamic_cast. */
3453 :
3454 : static inline bool
3455 40710874 : cxx_dynamic_cast_fn_p (tree fndecl)
3456 : {
3457 40710874 : return (cxx_dialect >= cxx20
3458 39151065 : && id_equal (DECL_NAME (fndecl), "__dynamic_cast")
3459 5364 : && CP_DECL_CONTEXT (fndecl) == abi_node
3460 : /* Only consider implementation-detail __dynamic_cast calls that
3461 : correspond to a dynamic_cast, and ignore direct calls to
3462 : abi::__dynamic_cast. */
3463 40716238 : && DECL_ARTIFICIAL (fndecl));
3464 : }
3465 :
3466 : /* Often, we have an expression in the form of address + offset, e.g.
3467 : "&_ZTV1A + 16". Extract the object from it, i.e. "_ZTV1A". */
3468 :
3469 : static tree
3470 4611 : extract_obj_from_addr_offset (tree expr)
3471 : {
3472 4611 : if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
3473 2174 : expr = TREE_OPERAND (expr, 0);
3474 4611 : STRIP_NOPS (expr);
3475 4611 : if (TREE_CODE (expr) == ADDR_EXPR)
3476 4600 : expr = TREE_OPERAND (expr, 0);
3477 4611 : return expr;
3478 : }
3479 :
3480 : /* Given a PATH like
3481 :
3482 : g.D.2181.D.2154.D.2102.D.2093
3483 :
3484 : find a component with type TYPE. Return NULL_TREE if not found, and
3485 : error_mark_node if the component is not accessible. If STOP is non-null,
3486 : this function will return NULL_TREE if STOP is found before TYPE. */
3487 :
3488 : static tree
3489 2219 : get_component_with_type (tree path, tree type, tree stop)
3490 : {
3491 6419 : while (true)
3492 : {
3493 4319 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path), type))
3494 : /* Found it. */
3495 : return path;
3496 3149 : else if (stop
3497 3149 : && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path),
3498 : stop)))
3499 : return NULL_TREE;
3500 3104 : else if (TREE_CODE (path) == COMPONENT_REF
3501 3104 : && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1)))
3502 : {
3503 : /* We need to check that the component we're accessing is in fact
3504 : accessible. */
3505 3104 : if (TREE_PRIVATE (TREE_OPERAND (path, 1))
3506 3104 : || TREE_PROTECTED (TREE_OPERAND (path, 1)))
3507 1004 : return error_mark_node;
3508 2100 : path = TREE_OPERAND (path, 0);
3509 : }
3510 : else
3511 : return NULL_TREE;
3512 : }
3513 : }
3514 :
3515 : /* Evaluate a call to __dynamic_cast (permitted by P1327R1).
3516 :
3517 : The declaration of __dynamic_cast is:
3518 :
3519 : void* __dynamic_cast (const void* __src_ptr,
3520 : const __class_type_info* __src_type,
3521 : const __class_type_info* __dst_type,
3522 : ptrdiff_t __src2dst);
3523 :
3524 : where src2dst has the following possible values
3525 :
3526 : >-1: src_type is a unique public non-virtual base of dst_type
3527 : dst_ptr + src2dst == src_ptr
3528 : -1: unspecified relationship
3529 : -2: src_type is not a public base of dst_type
3530 : -3: src_type is a multiple public non-virtual base of dst_type */
3531 :
3532 : static tree
3533 2556 : cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
3534 : bool *non_constant_p, bool *overflow_p,
3535 : tree *jump_target)
3536 : {
3537 : /* T will be something like
3538 : __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8)
3539 : dismantle it. */
3540 2556 : gcc_assert (call_expr_nargs (call) == 4);
3541 2556 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
3542 2556 : tree obj = CALL_EXPR_ARG (call, 0);
3543 2556 : tree type = CALL_EXPR_ARG (call, 2);
3544 2556 : HOST_WIDE_INT hint = int_cst_value (CALL_EXPR_ARG (call, 3));
3545 2556 : location_t loc = cp_expr_loc_or_input_loc (call);
3546 :
3547 : /* Get the target type of the dynamic_cast. */
3548 2556 : gcc_assert (TREE_CODE (type) == ADDR_EXPR);
3549 2556 : type = TREE_OPERAND (type, 0);
3550 2556 : type = TREE_TYPE (DECL_NAME (type));
3551 :
3552 : /* TYPE can only be either T* or T&. We can't know which of these it
3553 : is by looking at TYPE, but OBJ will be "(T*) x" in the first case,
3554 : and something like "(T*)(T&)(T*) x" in the second case.
3555 : This is true for the reference cases in C++ < 26 or when exceptions
3556 : aren't enabled, in that case we should diagnose errors. For C++26
3557 : with exceptions we should silently evaluate to null pointer and
3558 : let the callers call __cxa_bad_cast () later to throw an exception. */
3559 2556 : bool fail_for_non_constant_p = false;
3560 11601 : while (CONVERT_EXPR_P (obj) || TREE_CODE (obj) == SAVE_EXPR)
3561 : {
3562 9045 : if (cxx_dialect < cxx26 || !flag_exceptions)
3563 5557 : fail_for_non_constant_p |= TYPE_REF_P (TREE_TYPE (obj));
3564 9045 : obj = TREE_OPERAND (obj, 0);
3565 : }
3566 :
3567 : /* Evaluate the object so that we know its dynamic type. */
3568 2556 : obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p,
3569 : overflow_p, jump_target);
3570 2556 : if (*non_constant_p)
3571 : return call;
3572 2437 : if (*jump_target)
3573 : return NULL_TREE;
3574 :
3575 : /* For dynamic_cast from classes with virtual bases we can get something
3576 : like (virt_base *)(&d + 16) as OBJ. Try to convert that into
3577 : d.D.1234 using cxx_fold_indirect_ref. */
3578 2437 : if (cxx_dialect >= cxx26 && CONVERT_EXPR_P (obj))
3579 : {
3580 609 : tree objo = obj;
3581 609 : STRIP_NOPS (objo);
3582 609 : if (TREE_CODE (objo) == POINTER_PLUS_EXPR)
3583 : {
3584 576 : objo = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (TREE_TYPE (obj)),
3585 : obj, NULL, jump_target);
3586 576 : if (objo)
3587 576 : obj = build_fold_addr_expr (objo);
3588 : }
3589 : }
3590 :
3591 : /* We expect OBJ to be in form of &d.D.2102 when HINT == 0,
3592 : but when HINT is > 0, it can also be something like
3593 : &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET. */
3594 2437 : obj = extract_obj_from_addr_offset (obj);
3595 2437 : const tree objtype = TREE_TYPE (obj);
3596 : /* If OBJ doesn't refer to a base field, we're done. */
3597 4800 : if (tree t = (TREE_CODE (obj) == COMPONENT_REF
3598 2437 : ? TREE_OPERAND (obj, 1) : obj))
3599 2437 : if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t))
3600 : {
3601 74 : if (fail_for_non_constant_p)
3602 : {
3603 55 : if (!ctx->quiet)
3604 : {
3605 2 : auto_diagnostic_group d;
3606 2 : error_at (loc, "reference %<dynamic_cast%> failed");
3607 2 : inform (loc, "dynamic type %qT of its operand does "
3608 : "not have a base class of type %qT",
3609 : objtype, type);
3610 2 : }
3611 55 : *non_constant_p = true;
3612 : }
3613 74 : return integer_zero_node;
3614 : }
3615 :
3616 : /* [class.cdtor] When a dynamic_cast is used in a constructor ...
3617 : or in a destructor ... if the operand of the dynamic_cast refers
3618 : to the object under construction or destruction, this object is
3619 : considered to be a most derived object that has the type of the
3620 : constructor or destructor's class. */
3621 2363 : tree vtable = build_vfield_ref (obj, objtype);
3622 2363 : vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue,
3623 : non_constant_p, overflow_p,
3624 : jump_target);
3625 2363 : if (*non_constant_p)
3626 : return call;
3627 2186 : if (*jump_target)
3628 : return NULL_TREE;
3629 : /* With -fsanitize=vptr, we initialize all vtable pointers to null,
3630 : so it's possible that we got a null pointer now. */
3631 2186 : if (integer_zerop (vtable))
3632 : {
3633 12 : if (!ctx->quiet)
3634 3 : error_at (loc, "virtual table pointer is used uninitialized");
3635 12 : *non_constant_p = true;
3636 12 : return integer_zero_node;
3637 : }
3638 : /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A. */
3639 2174 : vtable = extract_obj_from_addr_offset (vtable);
3640 2174 : const tree mdtype = DECL_CONTEXT (vtable);
3641 :
3642 : /* Given dynamic_cast<T>(v),
3643 :
3644 : [expr.dynamic.cast] If C is the class type to which T points or refers,
3645 : the runtime check logically executes as follows:
3646 :
3647 : If, in the most derived object pointed (referred) to by v, v points
3648 : (refers) to a public base class subobject of a C object, and if only
3649 : one object of type C is derived from the subobject pointed (referred)
3650 : to by v the result points (refers) to that C object.
3651 :
3652 : In this case, HINT >= 0 or -3. */
3653 2174 : if (hint >= 0 || hint == -3)
3654 : {
3655 : /* Look for a component with type TYPE. */
3656 664 : tree t = get_component_with_type (obj, type, mdtype);
3657 : /* If not accessible, give an error. */
3658 664 : if (t == error_mark_node)
3659 : {
3660 198 : if (fail_for_non_constant_p)
3661 : {
3662 108 : if (!ctx->quiet)
3663 : {
3664 12 : auto_diagnostic_group d;
3665 12 : error_at (loc, "reference %<dynamic_cast%> failed");
3666 12 : inform (loc, "static type %qT of its operand is a "
3667 : "non-public base class of dynamic type %qT",
3668 : objtype, type);
3669 :
3670 12 : }
3671 108 : *non_constant_p = true;
3672 : }
3673 198 : return integer_zero_node;
3674 : }
3675 466 : else if (t)
3676 : /* The result points to the TYPE object. */
3677 421 : return cp_build_addr_expr (t, complain);
3678 : /* Else, TYPE was not found, because the HINT turned out to be wrong.
3679 : Fall through to the normal processing. */
3680 : }
3681 :
3682 : /* Otherwise, if v points (refers) to a public base class subobject of the
3683 : most derived object, and the type of the most derived object has a base
3684 : class, of type C, that is unambiguous and public, the result points
3685 : (refers) to the C subobject of the most derived object.
3686 :
3687 : But it can also be an invalid case. */
3688 :
3689 : /* Get the most derived object. */
3690 1555 : obj = get_component_with_type (obj, mdtype, NULL_TREE);
3691 1555 : if (obj == error_mark_node)
3692 : {
3693 806 : if (fail_for_non_constant_p)
3694 : {
3695 350 : if (!ctx->quiet)
3696 : {
3697 38 : auto_diagnostic_group d;
3698 38 : error_at (loc, "reference %<dynamic_cast%> failed");
3699 38 : inform (loc, "static type %qT of its operand is a non-public"
3700 : " base class of dynamic type %qT", objtype, mdtype);
3701 38 : }
3702 350 : *non_constant_p = true;
3703 : }
3704 806 : return integer_zero_node;
3705 : }
3706 : else
3707 749 : gcc_assert (obj);
3708 :
3709 : /* Check that the type of the most derived object has a base class
3710 : of type TYPE that is unambiguous and public. */
3711 749 : base_kind b_kind;
3712 749 : tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none);
3713 749 : if (!binfo || binfo == error_mark_node)
3714 : {
3715 339 : if (fail_for_non_constant_p)
3716 : {
3717 134 : if (!ctx->quiet)
3718 : {
3719 16 : auto_diagnostic_group d;
3720 16 : error_at (loc, "reference %<dynamic_cast%> failed");
3721 16 : if (b_kind == bk_ambig)
3722 6 : inform (loc, "%qT is an ambiguous base class of dynamic "
3723 : "type %qT of its operand", type, mdtype);
3724 : else
3725 10 : inform (loc, "dynamic type %qT of its operand does not "
3726 : "have an unambiguous public base class %qT",
3727 : mdtype, type);
3728 16 : }
3729 134 : *non_constant_p = true;
3730 : }
3731 339 : return integer_zero_node;
3732 : }
3733 : /* If so, return the TYPE subobject of the most derived object. */
3734 410 : obj = convert_to_base_statically (obj, binfo);
3735 410 : return cp_build_addr_expr (obj, complain);
3736 : }
3737 :
3738 : /* Data structure used by replace_decl and replace_decl_r. */
3739 :
3740 : struct replace_decl_data
3741 : {
3742 : /* The _DECL we want to replace. */
3743 : tree decl;
3744 : /* The replacement for DECL. */
3745 : tree replacement;
3746 : /* Trees we've visited. */
3747 : hash_set<tree> *pset;
3748 : /* Whether we've performed any replacements. */
3749 : bool changed;
3750 : };
3751 :
3752 : /* Helper function for replace_decl, called through cp_walk_tree. */
3753 :
3754 : static tree
3755 14316354 : replace_decl_r (tree *tp, int *walk_subtrees, void *data)
3756 : {
3757 14316354 : replace_decl_data *d = (replace_decl_data *) data;
3758 :
3759 : /* We could be replacing
3760 : &<retval>.bar -> &foo.bar
3761 : where foo is a static VAR_DECL, so we need to recompute TREE_CONSTANT
3762 : on the ADDR_EXPR around it. */
3763 14316354 : if (TREE_CODE (*tp) == ADDR_EXPR)
3764 : {
3765 1405103 : d->pset->add (*tp);
3766 1405103 : auto save_changed = d->changed;
3767 1405103 : d->changed = false;
3768 1405103 : cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr);
3769 1405103 : if (d->changed)
3770 : {
3771 289 : cxx_mark_addressable (*tp);
3772 289 : recompute_tree_invariant_for_addr_expr (*tp);
3773 : }
3774 : else
3775 1404814 : d->changed = save_changed;
3776 1405103 : *walk_subtrees = 0;
3777 : }
3778 12911251 : else if (*tp == d->decl)
3779 : {
3780 500 : *tp = unshare_expr (d->replacement);
3781 500 : d->changed = true;
3782 500 : *walk_subtrees = 0;
3783 : }
3784 12910751 : else if (TYPE_P (*tp)
3785 12910751 : || d->pset->add (*tp))
3786 2343514 : *walk_subtrees = 0;
3787 :
3788 14316354 : return NULL_TREE;
3789 : }
3790 :
3791 : /* Replace every occurrence of DECL with (an unshared copy of)
3792 : REPLACEMENT within the expression *TP. Returns true iff a
3793 : replacement was performed. */
3794 :
3795 : bool
3796 1884555 : replace_decl (tree *tp, tree decl, tree replacement)
3797 : {
3798 1884555 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
3799 : (TREE_TYPE (decl), TREE_TYPE (replacement)));
3800 1884555 : hash_set<tree> pset;
3801 1884555 : replace_decl_data data = { decl, replacement, &pset, false };
3802 1884555 : cp_walk_tree (tp, replace_decl_r, &data, NULL);
3803 1884555 : return data.changed;
3804 1884555 : }
3805 :
3806 : /* Evaluate the call T to virtual function thunk THUNK_FNDECL. */
3807 :
3808 : static tree
3809 30 : cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl,
3810 : value_cat lval,
3811 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
3812 : {
3813 30 : tree function = THUNK_TARGET (thunk_fndecl);
3814 :
3815 30 : if (THUNK_VIRTUAL_OFFSET (thunk_fndecl))
3816 : {
3817 13 : if (!ctx->quiet)
3818 : {
3819 3 : if (!DECL_DECLARED_CONSTEXPR_P (function))
3820 : {
3821 0 : error ("call to non-%<constexpr%> function %qD", function);
3822 0 : explain_invalid_constexpr_fn (function);
3823 : }
3824 : else
3825 : /* virtual_offset is only set for virtual bases, which make the
3826 : class non-literal, so we don't need to handle it here. */
3827 3 : error ("calling constexpr member function %qD through virtual "
3828 : "base subobject", function);
3829 : }
3830 13 : *non_constant_p = true;
3831 13 : return t;
3832 : }
3833 :
3834 17 : tree new_call = copy_node (t);
3835 17 : CALL_EXPR_FN (new_call) = function;
3836 17 : TREE_TYPE (new_call) = TREE_TYPE (TREE_TYPE (function));
3837 :
3838 17 : tree offset = size_int (THUNK_FIXED_OFFSET (thunk_fndecl));
3839 :
3840 17 : if (DECL_THIS_THUNK_P (thunk_fndecl))
3841 : {
3842 : /* 'this'-adjusting thunk. */
3843 11 : tree this_arg = CALL_EXPR_ARG (t, 0);
3844 11 : this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg),
3845 : this_arg, offset);
3846 11 : CALL_EXPR_ARG (new_call, 0) = this_arg;
3847 : }
3848 : else
3849 : /* Return-adjusting thunk. */
3850 6 : new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (new_call),
3851 : new_call, offset);
3852 :
3853 17 : return cxx_eval_constant_expression (ctx, new_call, lval,
3854 : non_constant_p, overflow_p,
3855 17 : jump_target);
3856 : }
3857 :
3858 : /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set
3859 : its TREE_READONLY flag according to READONLY_P. Used for constexpr
3860 : 'tors to detect modifying const objects in a constexpr context. */
3861 :
3862 : static void
3863 12001598 : cxx_set_object_constness (const constexpr_ctx *ctx, tree object,
3864 : bool readonly_p, bool *non_constant_p,
3865 : bool *overflow_p, tree *jump_target)
3866 : {
3867 24003196 : if (CLASS_TYPE_P (TREE_TYPE (object))
3868 24003196 : && CP_TYPE_CONST_P (TREE_TYPE (object)))
3869 : {
3870 : /* Subobjects might not be stored in ctx->global->values but we
3871 : can get its CONSTRUCTOR by evaluating *this. */
3872 1333674 : tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue,
3873 : non_constant_p, overflow_p,
3874 : jump_target);
3875 1333674 : if (!*non_constant_p
3876 13124169 : && !throws (jump_target)
3877 2456245 : && TREE_CODE (e) == CONSTRUCTOR)
3878 1122571 : TREE_READONLY (e) = readonly_p;
3879 : }
3880 12001598 : }
3881 :
3882 : /* Allocate an exception for OBJECT and throw it. */
3883 :
3884 : tree
3885 1464 : cxa_allocate_and_throw_exception (location_t loc, const constexpr_ctx *ctx,
3886 : tree object)
3887 : {
3888 1464 : tree type = TREE_TYPE (object);
3889 : /* This simulates a call to __cxa_allocate_exception. We need
3890 : (struct exception *) &heap -- memory on the heap so that
3891 : it can survive the stack being unwound. */
3892 1464 : tree arr = build_array_of_n_type (type, 1);
3893 1464 : tree var = cxa_allocate_exception (loc, ctx, arr, size_zero_node);
3894 1464 : DECL_NAME (var) = heap_identifier;
3895 1464 : ctx->global->put_value (var, NULL_TREE);
3896 :
3897 : /* *(struct exception *) &heap = exc{ ... } */
3898 1464 : tree ptr = build_nop (build_pointer_type (type), build_address (var));
3899 1464 : object = cp_build_init_expr (cp_build_fold_indirect_ref (ptr), object);
3900 1464 : bool non_constant_p = false, overflow_p = false;
3901 1464 : tree jump_target = NULL_TREE;
3902 1464 : cxx_eval_constant_expression (ctx, object, vc_prvalue, &non_constant_p,
3903 : &overflow_p, &jump_target);
3904 1464 : if (non_constant_p)
3905 : {
3906 0 : if (!ctx->quiet)
3907 0 : error_at (loc, "couldn%'t throw %qT", type);
3908 0 : return NULL_TREE;
3909 : }
3910 :
3911 : /* Now we can __cxa_throw. */
3912 1464 : DECL_EXCEPTION_REFCOUNT (var)
3913 1464 : = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (var), size_one_node);
3914 1464 : ++ctx->global->uncaught_exceptions;
3915 :
3916 1464 : return var;
3917 : }
3918 :
3919 : /* Subroutine of cxx_eval_constant_expression.
3920 : Evaluate the call expression tree T in the context of OLD_CALL expression
3921 : evaluation. */
3922 :
3923 : static tree
3924 199584393 : cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
3925 : value_cat lval,
3926 : bool *non_constant_p, bool *overflow_p,
3927 : tree *jump_target)
3928 : {
3929 199584393 : location_t loc = cp_expr_loc_or_input_loc (t);
3930 199584393 : tree fun = get_function_named_in_call (t);
3931 :
3932 199584393 : if (fun == NULL_TREE)
3933 365180 : return cxx_eval_internal_function (ctx, t, lval,
3934 : non_constant_p, overflow_p,
3935 365180 : jump_target);
3936 :
3937 199219213 : if (TREE_CODE (fun) != FUNCTION_DECL)
3938 : {
3939 : /* Might be a constexpr function pointer. */
3940 473692 : fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue,
3941 : non_constant_p, overflow_p,
3942 : jump_target);
3943 473692 : if (*jump_target)
3944 : return NULL_TREE;
3945 473692 : STRIP_NOPS (fun);
3946 473692 : if (TREE_CODE (fun) == ADDR_EXPR)
3947 24155 : fun = TREE_OPERAND (fun, 0);
3948 : /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
3949 : indirection, the called expression is a pointer into the
3950 : virtual table which should contain FDESC_EXPR. Extract the
3951 : FUNCTION_DECL from there. */
3952 : else if (TARGET_VTABLE_USES_DESCRIPTORS
3953 : && TREE_CODE (fun) == POINTER_PLUS_EXPR
3954 : && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
3955 : && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
3956 : {
3957 : tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
3958 : if (VAR_P (d)
3959 : && DECL_VTABLE_OR_VTT_P (d)
3960 : && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
3961 : && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
3962 : && DECL_INITIAL (d)
3963 : && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
3964 : {
3965 : tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
3966 : TYPE_SIZE_UNIT (vtable_entry_type));
3967 : HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
3968 : if (idx >= 0)
3969 : {
3970 : tree fdesc
3971 : = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
3972 : if (TREE_CODE (fdesc) == FDESC_EXPR
3973 : && integer_zerop (TREE_OPERAND (fdesc, 1)))
3974 : fun = TREE_OPERAND (fdesc, 0);
3975 : }
3976 : }
3977 : }
3978 : }
3979 199219213 : if (TREE_CODE (fun) != FUNCTION_DECL)
3980 : {
3981 449537 : if (!ctx->quiet && !*non_constant_p)
3982 0 : error_at (loc, "expression %qE does not designate a %<constexpr%> "
3983 : "function", fun);
3984 449537 : *non_constant_p = true;
3985 449537 : return t;
3986 : }
3987 198769676 : tree orig_fun = fun;
3988 198769676 : if (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun))
3989 28874774 : fun = DECL_CLONED_FUNCTION (fun);
3990 :
3991 198769676 : if (is_ubsan_builtin_p (fun))
3992 58 : return void_node;
3993 :
3994 198769618 : if (fndecl_built_in_p (fun))
3995 16889484 : return cxx_eval_builtin_function_call (ctx, t, fun,
3996 : lval, non_constant_p, overflow_p,
3997 16889483 : jump_target);
3998 181880134 : if (DECL_THUNK_P (fun))
3999 30 : return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p,
4000 30 : jump_target);
4001 181880104 : if (metafunction_p (fun))
4002 : {
4003 : /* To be able to evaluate a metafunction, we may have to instantiate
4004 : constexpr functions. If we're not allowed to instantiate, leave
4005 : this for later. Don't evaluate metafunctions at all when mce_unknown,
4006 : otherwise we might fold those prematurely. See
4007 : g++.dg/reflect/p2996-17.C. */
4008 35393 : if (uid_sensitive_constexpr_evaluation_p ()
4009 35130 : || ctx->manifestly_const_eval == mce_unknown)
4010 : {
4011 9513 : *non_constant_p = true;
4012 9513 : return t;
4013 : }
4014 25880 : ctx->global->metafns_called = true;
4015 25880 : tree e = process_metafunction (ctx, fun, t, non_constant_p, overflow_p,
4016 : jump_target);
4017 25880 : if (*jump_target)
4018 : return NULL_TREE;
4019 24410 : if (*non_constant_p)
4020 : return t;
4021 24323 : e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
4022 : non_constant_p, overflow_p,
4023 : jump_target);
4024 24323 : if (*jump_target)
4025 : return NULL_TREE;
4026 24323 : if (*non_constant_p)
4027 : return t;
4028 : return e;
4029 : }
4030 181844711 : bool non_constexpr_call = false;
4031 181844711 : if (!maybe_constexpr_fn (fun))
4032 : {
4033 850898 : if (TREE_CODE (t) == CALL_EXPR
4034 839318 : && cxx_replaceable_global_alloc_fn (fun)
4035 1333501 : && (CALL_FROM_NEW_OR_DELETE_P (t)
4036 174985 : || is_std_allocator_allocate (ctx->call)))
4037 : {
4038 402017 : const bool new_op_p = IDENTIFIER_NEW_OP_P (DECL_NAME (fun));
4039 402017 : const int nargs = call_expr_nargs (t);
4040 402017 : tree arg0 = NULL_TREE;
4041 696594 : for (int i = 0; i < nargs; ++i)
4042 : {
4043 402880 : tree arg = CALL_EXPR_ARG (t, i);
4044 402880 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4045 : non_constant_p, overflow_p,
4046 : jump_target);
4047 402880 : if (*jump_target)
4048 : return NULL_TREE;
4049 : /* Deleting a non-constant pointer has a better error message
4050 : below. */
4051 402872 : if (new_op_p || i != 0)
4052 355459 : VERIFY_CONSTANT (arg);
4053 247164 : if (i == 0)
4054 : arg0 = arg;
4055 : }
4056 293714 : gcc_assert (arg0);
4057 293714 : if (new_op_p)
4058 : {
4059 246301 : if (!tree_fits_uhwi_p (arg0))
4060 : {
4061 : /* We should not get here; the VERIFY_CONSTANT above
4062 : should have already caught it. */
4063 0 : gcc_checking_assert (false);
4064 : if (!ctx->quiet)
4065 : error_at (loc, "cannot allocate array: size not constant");
4066 : *non_constant_p = true;
4067 : return t;
4068 : }
4069 492602 : tree type = build_array_type_nelts (char_type_node,
4070 246301 : tree_to_uhwi (arg0));
4071 246301 : tree var = build_decl (loc, VAR_DECL,
4072 246301 : (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4073 : & OVL_OP_FLAG_VEC)
4074 : ? heap_vec_uninit_identifier
4075 : : heap_uninit_identifier,
4076 246301 : type);
4077 246301 : DECL_ARTIFICIAL (var) = 1;
4078 246301 : ctx->global->heap_vars.safe_push (var);
4079 246301 : ctx->global->put_value (var, NULL_TREE);
4080 246301 : return fold_convert (ptr_type_node, build_address (var));
4081 : }
4082 : else
4083 : {
4084 47413 : STRIP_NOPS (arg0);
4085 47413 : if (TREE_CODE (arg0) == ADDR_EXPR
4086 47413 : && VAR_P (TREE_OPERAND (arg0, 0)))
4087 : {
4088 47413 : tree var = TREE_OPERAND (arg0, 0);
4089 47413 : if (DECL_NAME (var) == heap_uninit_identifier
4090 47413 : || DECL_NAME (var) == heap_identifier)
4091 : {
4092 47247 : if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4093 : & OVL_OP_FLAG_VEC)
4094 : {
4095 9 : if (!ctx->quiet)
4096 : {
4097 3 : auto_diagnostic_group d;
4098 3 : error_at (loc, "array deallocation of object "
4099 : "allocated with non-array "
4100 : "allocation");
4101 3 : inform (DECL_SOURCE_LOCATION (var),
4102 : "allocation performed here");
4103 3 : }
4104 9 : *non_constant_p = true;
4105 9 : return t;
4106 : }
4107 47238 : DECL_NAME (var) = heap_deleted_identifier;
4108 47238 : ctx->global->destroy_value (var);
4109 47238 : ctx->global->heap_dealloc_count++;
4110 47238 : return void_node;
4111 : }
4112 166 : else if (DECL_NAME (var) == heap_vec_uninit_identifier
4113 166 : || DECL_NAME (var) == heap_vec_identifier)
4114 : {
4115 142 : if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
4116 : & OVL_OP_FLAG_VEC) == 0)
4117 : {
4118 9 : if (!ctx->quiet)
4119 : {
4120 3 : auto_diagnostic_group d;
4121 3 : error_at (loc, "non-array deallocation of "
4122 : "object allocated with array "
4123 : "allocation");
4124 3 : inform (DECL_SOURCE_LOCATION (var),
4125 : "allocation performed here");
4126 3 : }
4127 9 : *non_constant_p = true;
4128 9 : return t;
4129 : }
4130 133 : DECL_NAME (var) = heap_deleted_identifier;
4131 133 : ctx->global->destroy_value (var);
4132 133 : ctx->global->heap_dealloc_count++;
4133 133 : return void_node;
4134 : }
4135 24 : else if (DECL_NAME (var) == heap_deleted_identifier)
4136 : {
4137 15 : if (!ctx->quiet)
4138 6 : error_at (loc, "deallocation of already deallocated "
4139 : "storage");
4140 15 : *non_constant_p = true;
4141 15 : return t;
4142 : }
4143 : }
4144 9 : if (!ctx->quiet)
4145 3 : error_at (loc, "deallocation of storage that was "
4146 : "not previously allocated");
4147 9 : *non_constant_p = true;
4148 9 : return t;
4149 : }
4150 : }
4151 : /* Allow placement new in std::construct_at, just return the second
4152 : argument. */
4153 448881 : if (TREE_CODE (t) == CALL_EXPR
4154 437301 : && cxx_placement_new_fn (fun)
4155 736960 : && is_std_construct_at (ctx->call))
4156 : {
4157 30942 : const int nargs = call_expr_nargs (t);
4158 30942 : tree arg1 = NULL_TREE;
4159 92826 : for (int i = 0; i < nargs; ++i)
4160 : {
4161 61884 : tree arg = CALL_EXPR_ARG (t, i);
4162 61884 : arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
4163 : non_constant_p, overflow_p,
4164 : jump_target);
4165 61884 : if (*jump_target)
4166 : return NULL_TREE;
4167 61884 : if (i == 1)
4168 : arg1 = arg;
4169 : else
4170 61884 : VERIFY_CONSTANT (arg);
4171 : }
4172 30942 : gcc_assert (arg1);
4173 : return arg1;
4174 : }
4175 417939 : else if (cxx_dynamic_cast_fn_p (fun))
4176 2556 : return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p,
4177 2556 : jump_target);
4178 415383 : else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun))
4179 26665 : return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun,
4180 : non_constant_p, overflow_p,
4181 26665 : jump_target);
4182 :
4183 : /* Calls to non-constexpr functions can be diagnosed right away
4184 : before C++26, though in C++26 evaluation of the arguments might
4185 : throw and if caught it could be still constant expression.
4186 : So for C++26 this is diagnosed only after
4187 : cxx_bind_parameters_in_call. */
4188 388718 : if (cxx_dialect >= cxx26)
4189 : non_constexpr_call = true;
4190 : else
4191 : {
4192 336231 : if (!ctx->quiet)
4193 : {
4194 188 : if (!lambda_static_thunk_p (fun))
4195 188 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4196 188 : explain_invalid_constexpr_fn (fun);
4197 : }
4198 336231 : *non_constant_p = true;
4199 336231 : return t;
4200 : }
4201 : }
4202 :
4203 181046300 : constexpr_ctx new_ctx = *ctx;
4204 181046300 : ctx = &new_ctx;
4205 208743365 : if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
4206 185531184 : && TREE_CODE (t) == AGGR_INIT_EXPR)
4207 : {
4208 : /* We want to have an initialization target for an AGGR_INIT_EXPR.
4209 : If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT. */
4210 1816 : new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
4211 1816 : tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
4212 1816 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
4213 1816 : ctx->global->put_value (new_ctx.object, ctor);
4214 : }
4215 : /* An immediate invocation is manifestly constant evaluated including the
4216 : arguments of the call, so use mce_true even for the argument
4217 : evaluation. */
4218 362092600 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
4219 4649349 : new_ctx.manifestly_const_eval = mce_true;
4220 :
4221 : /* We used to shortcut trivial constructor/op= here, but nowadays
4222 : we can only get a trivial function here with -fno-elide-constructors. */
4223 181046300 : gcc_checking_assert (!trivial_fn_p (fun)
4224 : || !flag_elide_constructors
4225 : /* Or it's a call from maybe_thunk_body (111075). */
4226 : || (TREE_CODE (t) == CALL_EXPR ? CALL_FROM_THUNK_P (t)
4227 : : AGGR_INIT_FROM_THUNK_P (t))
4228 : /* We don't elide constructors when processing
4229 : a noexcept-expression. */
4230 : || cp_noexcept_operand);
4231 :
4232 181046300 : bool non_constant_args = false;
4233 181046300 : constexpr_call new_call;
4234 181046300 : new_call.bindings
4235 181046300 : = cxx_bind_parameters_in_call (ctx, t, fun, orig_fun, non_constant_p,
4236 : overflow_p, &non_constant_args,
4237 : jump_target);
4238 :
4239 : /* We build up the bindings list before we know whether we already have this
4240 : call cached. If we don't end up saving these bindings, ggc_free them when
4241 : this function exits. */
4242 181046300 : class free_bindings
4243 : {
4244 : tree *bindings;
4245 : public:
4246 181046300 : free_bindings (tree &b): bindings (&b) { }
4247 181046298 : ~free_bindings () { if (bindings) ggc_free (*bindings); }
4248 5055706 : void preserve () { bindings = NULL; }
4249 181046300 : } fb (new_call.bindings);
4250 :
4251 181046300 : if (*jump_target)
4252 : return NULL_TREE;
4253 181046290 : if (*non_constant_p)
4254 : return t;
4255 97943974 : if (non_constexpr_call)
4256 : {
4257 4324 : if (!ctx->quiet)
4258 : {
4259 191 : if (!lambda_static_thunk_p (fun))
4260 191 : error_at (loc, "call to non-%<constexpr%> function %qD", fun);
4261 191 : explain_invalid_constexpr_fn (fun);
4262 : }
4263 4324 : *non_constant_p = true;
4264 4324 : return t;
4265 : }
4266 :
4267 : /* We can't defer instantiating the function any longer. */
4268 97939650 : if (!DECL_INITIAL (fun)
4269 3493970 : && (DECL_TEMPLOID_INSTANTIATION (fun) || DECL_DEFAULTED_FN (fun))
4270 97939650 : && !uid_sensitive_constexpr_evaluation_p ())
4271 : {
4272 3147011 : location_t save_loc = input_location;
4273 3147011 : input_location = loc;
4274 3147011 : ++function_depth;
4275 3147011 : if (ctx->manifestly_const_eval == mce_true)
4276 396521 : FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true;
4277 3147011 : if (DECL_TEMPLOID_INSTANTIATION (fun))
4278 3147004 : instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
4279 : else
4280 7 : synthesize_method (fun);
4281 3147011 : --function_depth;
4282 3147011 : input_location = save_loc;
4283 : }
4284 :
4285 : /* If in direct recursive call, optimize definition search. */
4286 97939650 : if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun)
4287 27550 : new_call.fundef = ctx->call->fundef;
4288 : else
4289 : {
4290 97912100 : new_call.fundef = retrieve_constexpr_fundef (fun);
4291 97912100 : if (new_call.fundef == NULL || new_call.fundef->body == NULL
4292 97317377 : || new_call.fundef->result == error_mark_node
4293 97249960 : || fun == current_function_decl)
4294 : {
4295 662143 : if (!ctx->quiet)
4296 : {
4297 : /* We need to check for current_function_decl here in case we're
4298 : being called during cp_fold_function, because at that point
4299 : DECL_INITIAL is set properly and we have a fundef but we
4300 : haven't lowered invisirefs yet (c++/70344). */
4301 168 : if (DECL_INITIAL (fun) == error_mark_node
4302 168 : || fun == current_function_decl)
4303 15 : error_at (loc, "%qD called in a constant expression before its "
4304 : "definition is complete", fun);
4305 153 : else if (DECL_INITIAL (fun))
4306 : {
4307 : /* The definition of fun was somehow unsuitable. But pretend
4308 : that lambda static thunks don't exist. */
4309 116 : if (!lambda_static_thunk_p (fun))
4310 112 : error_at (loc, "%qD called in a constant expression", fun);
4311 116 : explain_invalid_constexpr_fn (fun);
4312 : }
4313 : else
4314 37 : error_at (loc, "%qD used before its definition", fun);
4315 : }
4316 662143 : *non_constant_p = true;
4317 662143 : return t;
4318 : }
4319 : }
4320 :
4321 : /* Don't complain about problems evaluating an ill-formed function. */
4322 97277507 : if (function *f = DECL_STRUCT_FUNCTION (fun))
4323 97277507 : if (f->language->erroneous)
4324 664 : new_ctx.quiet = true;
4325 :
4326 97277507 : int depth_ok = push_cx_call_context (t);
4327 :
4328 : /* Remember the object we are constructing or destructing. */
4329 97277507 : tree new_obj = NULL_TREE;
4330 194555014 : if (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))
4331 : {
4332 : /* In a cdtor, it should be the first `this' argument.
4333 : At this point it has already been evaluated in the call
4334 : to cxx_bind_parameters_in_call. */
4335 14860252 : new_obj = TREE_VEC_ELT (new_call.bindings, 0);
4336 14860252 : bool empty_base = false;
4337 14860252 : new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj,
4338 : &empty_base, jump_target);
4339 14860252 : if (*jump_target)
4340 0 : return NULL_TREE;
4341 : /* If we're initializing an empty class, don't set constness, because
4342 : cxx_fold_indirect_ref will return the wrong object to set constness
4343 : of. */
4344 14860252 : if (empty_base)
4345 : new_obj = NULL_TREE;
4346 6159020 : else if (ctx->call && ctx->call->fundef
4347 24359916 : && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl))
4348 : {
4349 3596118 : tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0);
4350 3596118 : STRIP_NOPS (cur_obj);
4351 3596118 : if (TREE_CODE (cur_obj) == ADDR_EXPR)
4352 3594946 : cur_obj = TREE_OPERAND (cur_obj, 0);
4353 3596118 : if (new_obj == cur_obj)
4354 : /* We're calling the target constructor of a delegating
4355 : constructor, or accessing a base subobject through a
4356 : NOP_EXPR as part of a call to a base constructor, so
4357 : there is no new (sub)object. */
4358 2858640 : new_obj = NULL_TREE;
4359 : }
4360 : }
4361 :
4362 97277507 : tree result = NULL_TREE;
4363 :
4364 97277507 : constexpr_call *entry = NULL;
4365 97277507 : if (depth_ok && !non_constant_args && ctx->strict)
4366 : {
4367 33293488 : new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
4368 33293488 : new_call.hash
4369 33293488 : = iterative_hash_template_arg (new_call.bindings, new_call.hash);
4370 :
4371 : /* If we have seen this call before, we are done. */
4372 33293488 : maybe_initialize_constexpr_call_table ();
4373 33293488 : bool insert = depth_ok < constexpr_cache_depth;
4374 33293488 : constexpr_call **slot
4375 39976278 : = constexpr_call_table->find_slot (&new_call,
4376 : insert ? INSERT : NO_INSERT);
4377 33293488 : entry = slot ? *slot : NULL;
4378 32199529 : if (entry == NULL)
4379 : {
4380 : /* Only cache up to constexpr_cache_depth to limit memory use. */
4381 6149665 : if (insert)
4382 : {
4383 : /* We need to keep a pointer to the entry, not just the slot, as
4384 : the slot can move during evaluation of the body. */
4385 5055706 : *slot = entry = ggc_alloc<constexpr_call> ();
4386 5055706 : *entry = new_call;
4387 5055706 : entry->result (ctx->manifestly_const_eval) = unknown_type_node;
4388 5055706 : fb.preserve ();
4389 : }
4390 : }
4391 : /* Calls that are in progress have their result set to unknown_type_node,
4392 : so that we can detect circular dependencies. Now that we only cache
4393 : up to constexpr_cache_depth this won't catch circular dependencies that
4394 : start deeper, but they'll hit the recursion or ops limit. */
4395 27143823 : else if (entry->result (ctx->manifestly_const_eval) == unknown_type_node)
4396 : {
4397 6 : if (!ctx->quiet)
4398 0 : error ("call has circular dependency");
4399 6 : *non_constant_p = true;
4400 6 : entry->result (ctx->manifestly_const_eval) = result = error_mark_node;
4401 : }
4402 : else
4403 27143817 : result = entry->result (ctx->manifestly_const_eval);
4404 : }
4405 :
4406 97277507 : if (!depth_ok)
4407 : {
4408 30 : if (!ctx->quiet)
4409 3 : error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
4410 : "%<-fconstexpr-depth=%> to increase the maximum)",
4411 : max_constexpr_depth);
4412 30 : *non_constant_p = true;
4413 30 : result = error_mark_node;
4414 : }
4415 : else
4416 : {
4417 97277477 : bool cacheable = !!entry;
4418 97277477 : if (result && result != error_mark_node)
4419 : /* OK */;
4420 77017423 : else if (!DECL_SAVED_TREE (fun))
4421 : {
4422 : /* When at_eof >= 3, cgraph has started throwing away
4423 : DECL_SAVED_TREE, so fail quietly. FIXME we get here because of
4424 : late code generation for VEC_INIT_EXPR, which needs to be
4425 : completely reconsidered. */
4426 0 : gcc_assert (at_eof >= 3 && ctx->quiet);
4427 0 : *non_constant_p = true;
4428 : }
4429 77017423 : else if (tree copy = get_fundef_copy (new_call.fundef))
4430 : {
4431 77017423 : tree body, parms, res;
4432 77017423 : releasing_vec ctors;
4433 :
4434 : /* Reuse or create a new unshared copy of this function's body. */
4435 77017423 : body = TREE_PURPOSE (copy);
4436 77017423 : parms = TREE_VALUE (copy);
4437 77017423 : res = TREE_TYPE (copy);
4438 :
4439 : /* Associate the bindings with the remapped parms. */
4440 77017423 : tree bound = new_call.bindings;
4441 77017423 : tree remapped = parms;
4442 179537295 : for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
4443 : {
4444 102519872 : tree arg = TREE_VEC_ELT (bound, i);
4445 102519872 : if (entry)
4446 : {
4447 : /* Unshare args going into the hash table to separate them
4448 : from the caller's context, for better GC and to avoid
4449 : problems with verify_gimple. */
4450 3654401 : arg = unshare_expr_without_location (arg);
4451 3654401 : TREE_VEC_ELT (bound, i) = arg;
4452 :
4453 : /* And then unshare again so the callee doesn't change the
4454 : argument values in the hash table. XXX Could we unshare
4455 : lazily in cxx_eval_store_expression? */
4456 3654401 : arg = unshare_constructor (arg);
4457 3654401 : if (TREE_CODE (arg) == CONSTRUCTOR)
4458 864628 : vec_safe_push (ctors, arg);
4459 : }
4460 102519872 : ctx->global->put_value (remapped, arg);
4461 102519872 : remapped = DECL_CHAIN (remapped);
4462 : }
4463 77017423 : if (remapped)
4464 : {
4465 : /* We shouldn't have any parms without args, but fail gracefully
4466 : in error recovery. */
4467 6 : gcc_checking_assert (seen_error ());
4468 6 : *non_constant_p = true;
4469 : }
4470 : /* Add the RESULT_DECL to the values map, too. */
4471 77017423 : gcc_assert (!DECL_BY_REFERENCE (res));
4472 77017423 : ctx->global->put_value (res, NULL_TREE);
4473 :
4474 : /* Remember the current call we're evaluating. */
4475 77017423 : constexpr_ctx call_ctx = *ctx;
4476 77017423 : call_ctx.call = &new_call;
4477 77017423 : unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
4478 77017423 : unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
4479 77017423 : bool save_metafns_called = ctx->global->metafns_called;
4480 :
4481 : /* Make sure we fold std::is_constant_evaluated to true in an
4482 : immediate function. */
4483 154034846 : if (DECL_IMMEDIATE_FUNCTION_P (fun))
4484 2363280 : call_ctx.manifestly_const_eval = mce_true;
4485 :
4486 : /* If this is a constexpr destructor, the object's const and volatile
4487 : semantics are no longer in effect; see [class.dtor]p5. */
4488 89019021 : if (new_obj && DECL_DESTRUCTOR_P (fun))
4489 990995 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false,
4490 : non_constant_p, overflow_p, jump_target);
4491 :
4492 : /* If this is a constructor, we are beginning the lifetime of the
4493 : object we are initializing. */
4494 77017423 : if (new_obj
4495 24003196 : && DECL_CONSTRUCTOR_P (fun)
4496 11010603 : && TREE_CODE (new_obj) == COMPONENT_REF
4497 79947217 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE)
4498 : {
4499 4607 : tree ctor = build_constructor (TREE_TYPE (new_obj), NULL);
4500 4607 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
4501 4607 : tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj),
4502 : new_obj, ctor);
4503 4607 : cxx_eval_constant_expression (ctx, activate,
4504 : lval, non_constant_p, overflow_p,
4505 : jump_target);
4506 4607 : ggc_free (activate);
4507 4607 : if (*jump_target)
4508 0 : return NULL_TREE;
4509 : }
4510 :
4511 77017423 : ctx->global->metafns_called = false;
4512 :
4513 77017423 : tree jmp_target = NULL_TREE;
4514 77017423 : cxx_eval_constant_expression (&call_ctx, body,
4515 : vc_discard, non_constant_p, overflow_p,
4516 : &jmp_target);
4517 :
4518 77017421 : if (!*non_constant_p && throws (&jmp_target))
4519 : {
4520 1293 : result = NULL_TREE;
4521 1293 : cacheable = false;
4522 1293 : *jump_target = jmp_target;
4523 : }
4524 154032256 : else if (DECL_CONSTRUCTOR_P (fun))
4525 : /* This can be null for a subobject constructor call, in
4526 : which case what we care about is the initialization
4527 : side-effects rather than the value. We could get at the
4528 : value by evaluating *this, but we don't bother; there's
4529 : no need to put such a call in the hash table. */
4530 13786530 : result = lval ? ctx->object : ctx->ctor;
4531 63229598 : else if (VOID_TYPE_P (TREE_TYPE (res)))
4532 4423237 : result = void_node;
4533 : else
4534 : {
4535 58806361 : result = ctx->global->get_value (res);
4536 23419381 : if (result == NULL_TREE && !*non_constant_p
4537 58806567 : && !DECL_DESTRUCTOR_P (fun))
4538 : {
4539 103 : if (!ctx->quiet)
4540 6 : error ("%<constexpr%> call flows off the end "
4541 : "of the function");
4542 103 : *non_constant_p = true;
4543 : }
4544 : }
4545 :
4546 77017421 : if (ctx->global->metafns_called)
4547 29194 : cacheable = false;
4548 77017421 : ctx->global->metafns_called |= save_metafns_called;
4549 :
4550 : /* At this point, the object's constructor will have run, so
4551 : the object is no longer under construction, and its possible
4552 : 'const' semantics now apply. Make a note of this fact by
4553 : marking the CONSTRUCTOR TREE_READONLY. */
4554 89019019 : if (new_obj && DECL_CONSTRUCTOR_P (fun))
4555 11010603 : cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true,
4556 : non_constant_p, overflow_p, jump_target);
4557 :
4558 : /* Remove the parms/result from the values map. */
4559 77017421 : destroy_value_checked (ctx, res, non_constant_p);
4560 179537298 : for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
4561 102519877 : destroy_value_checked (ctx, parm, non_constant_p);
4562 :
4563 : /* Free any parameter CONSTRUCTORs we aren't returning directly. */
4564 77882049 : while (!ctors->is_empty ())
4565 : {
4566 864628 : tree c = ctors->pop ();
4567 864628 : if (c != result)
4568 864628 : free_constructor (c);
4569 : }
4570 :
4571 : /* Make the unshared function copy we used available for re-use. */
4572 77017421 : save_fundef_copy (fun, copy);
4573 :
4574 : /* If the call allocated some heap object that hasn't been
4575 : deallocated during the call, or if it deallocated some heap
4576 : object it has not allocated, the call isn't really stateless
4577 : for the constexpr evaluation and should not be cached.
4578 : It is fine if the call allocates something and deallocates it
4579 : too. */
4580 77017421 : if (cacheable
4581 88954716 : && (save_heap_alloc_count != ctx->global->heap_vars.length ()
4582 11934151 : || (save_heap_dealloc_count
4583 11934151 : != ctx->global->heap_dealloc_count)))
4584 : {
4585 3494 : tree heap_var;
4586 3494 : unsigned int i;
4587 3494 : if ((ctx->global->heap_vars.length ()
4588 3494 : - ctx->global->heap_dealloc_count)
4589 3494 : != save_heap_alloc_count - save_heap_dealloc_count)
4590 : cacheable = false;
4591 : else
4592 85109 : FOR_EACH_VEC_ELT_FROM (ctx->global->heap_vars, i, heap_var,
4593 : save_heap_alloc_count)
4594 83538 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
4595 : {
4596 : cacheable = false;
4597 : break;
4598 : }
4599 : }
4600 :
4601 : /* Rewrite all occurrences of the function's RESULT_DECL with the
4602 : current object under construction. */
4603 77017421 : if (!*non_constant_p
4604 46781616 : && ctx->object
4605 13772268 : && CLASS_TYPE_P (TREE_TYPE (res))
4606 79748029 : && !is_empty_class (TREE_TYPE (res)))
4607 : {
4608 1884435 : if (!same_type_ignoring_top_level_qualifiers_p
4609 1884435 : (TREE_TYPE (res), TREE_TYPE (ctx->object)))
4610 0 : *non_constant_p = true;
4611 1884435 : else if (replace_decl (&result, res, ctx->object))
4612 : {
4613 236 : cacheable = false;
4614 236 : result = cxx_eval_constant_expression (ctx, result, lval,
4615 : non_constant_p,
4616 : overflow_p,
4617 : jump_target);
4618 236 : if (*jump_target)
4619 : {
4620 0 : cacheable = false;
4621 0 : result = NULL_TREE;
4622 : }
4623 : }
4624 : }
4625 :
4626 : /* Only cache a permitted result of a constant expression. */
4627 77017185 : if (cacheable && !reduced_constant_expression_p (result))
4628 : cacheable = false;
4629 77017421 : }
4630 : else
4631 : /* Couldn't get a function copy to evaluate. */
4632 0 : *non_constant_p = true;
4633 :
4634 97277475 : if (result == error_mark_node)
4635 0 : *non_constant_p = true;
4636 97277475 : if (*non_constant_p || *overflow_p)
4637 30235961 : result = error_mark_node;
4638 67041514 : else if (!result)
4639 4454240 : result = void_node;
4640 97277475 : if (entry)
4641 : {
4642 64399056 : entry->result (ctx->manifestly_const_eval)
4643 32199528 : = cacheable ? result : error_mark_node;
4644 :
4645 32199528 : if (result != error_mark_node
4646 25402872 : && ctx->manifestly_const_eval == mce_unknown)
4647 : {
4648 : /* Evaluation succeeded and was independent of whether we're in a
4649 : manifestly constant-evaluated context, so we can also reuse
4650 : this result when evaluating this call with a fixed context. */
4651 2368112 : if (!entry->result (mce_true))
4652 850135 : entry->result (mce_true) = entry->result (mce_unknown);
4653 2368112 : if (!entry->result (mce_false))
4654 832540 : entry->result (mce_false) = entry->result (mce_unknown);
4655 : }
4656 : }
4657 : }
4658 :
4659 : /* The result of a constexpr function must be completely initialized.
4660 :
4661 : However, in C++20, a constexpr constructor doesn't necessarily have
4662 : to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
4663 : in order to detect reading an unitialized object in constexpr instead
4664 : of value-initializing it. (reduced_constant_expression_p is expected to
4665 : take care of clearing the flag.) */
4666 97277505 : if (TREE_CODE (result) == CONSTRUCTOR
4667 97277505 : && (cxx_dialect < cxx20
4668 22824304 : || !DECL_CONSTRUCTOR_P (fun)))
4669 5831345 : clear_no_implicit_zero (result);
4670 :
4671 97277505 : pop_cx_call_context ();
4672 97277505 : return result;
4673 181046298 : }
4674 :
4675 : /* Return true if T is a valid constant initializer. If a CONSTRUCTOR
4676 : initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
4677 : cleared. If called recursively on a FIELD_DECL's CONSTRUCTOR, SZ
4678 : is DECL_SIZE of the FIELD_DECL, otherwise NULL.
4679 : FIXME speed this up, it's taking 16% of compile time on sieve testcase. */
4680 :
4681 : bool
4682 1195187478 : reduced_constant_expression_p (tree t, tree sz /* = NULL_TREE */)
4683 : {
4684 1195187478 : if (t == NULL_TREE)
4685 : return false;
4686 :
4687 1188393816 : switch (TREE_CODE (t))
4688 : {
4689 : case PTRMEM_CST:
4690 : case REFLECT_EXPR:
4691 : /* Even if we can't lower this yet, it's constant. */
4692 : return true;
4693 :
4694 : case OMP_DECLARE_MAPPER:
4695 : return true;
4696 :
4697 67884200 : case CONSTRUCTOR:
4698 : /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
4699 67884200 : tree field;
4700 67884200 : if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
4701 : /* A constant vector would be folded to VECTOR_CST.
4702 : A CONSTRUCTOR of scalar type means uninitialized. */
4703 : return false;
4704 67868229 : if (CONSTRUCTOR_NO_CLEARING (t))
4705 : {
4706 4670117 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
4707 : {
4708 : /* There must be a valid constant initializer at every array
4709 : index. */
4710 1940 : tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
4711 1940 : tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
4712 1940 : tree cursor = min;
4713 27445 : for (auto &e: CONSTRUCTOR_ELTS (t))
4714 : {
4715 21735 : if (!reduced_constant_expression_p (e.value))
4716 : return false;
4717 21685 : if (array_index_cmp (cursor, e.index) != 0)
4718 : return false;
4719 21625 : if (TREE_CODE (e.index) == RANGE_EXPR)
4720 0 : cursor = TREE_OPERAND (e.index, 1);
4721 21625 : if (TREE_CODE (e.value) == RAW_DATA_CST)
4722 0 : cursor
4723 0 : = int_const_binop (PLUS_EXPR, cursor,
4724 0 : size_int (RAW_DATA_LENGTH (e.value)));
4725 : else
4726 21625 : cursor = int_const_binop (PLUS_EXPR, cursor,
4727 21625 : size_one_node);
4728 : }
4729 1830 : if (find_array_ctor_elt (t, max) == -1)
4730 : return false;
4731 1742 : goto ok;
4732 : }
4733 4668177 : else if (cxx_dialect >= cxx20
4734 4668177 : && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
4735 : {
4736 9227938 : if (CONSTRUCTOR_NELTS (t) == 0)
4737 : /* An initialized union has a constructor element. */
4738 : return false;
4739 : /* And it only initializes one member. */
4740 : field = NULL_TREE;
4741 : }
4742 : else
4743 4666209 : field = next_subobject_field (TYPE_FIELDS (TREE_TYPE (t)));
4744 : }
4745 : else
4746 : field = NULL_TREE;
4747 595152086 : for (auto &e: CONSTRUCTOR_ELTS (t))
4748 : {
4749 : /* If VAL is null, we're in the middle of initializing this
4750 : element. */
4751 455494370 : if (!reduced_constant_expression_p (e.value,
4752 455494370 : (e.index
4753 455494352 : && (TREE_CODE (e.index)
4754 : == FIELD_DECL))
4755 69638384 : ? DECL_SIZE (e.index)
4756 : : NULL_TREE))
4757 : return false;
4758 : /* We want to remove initializers for empty fields in a struct to
4759 : avoid confusing output_constructor. */
4760 453737988 : if (is_empty_field (e.index)
4761 453737988 : && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
4762 : return false;
4763 : /* Check for non-empty fields between initialized fields when
4764 : CONSTRUCTOR_NO_CLEARING. */
4765 453519145 : for (; field && e.index != field;
4766 400254 : field = next_subobject_field (DECL_CHAIN (field)))
4767 436840 : if (!is_really_empty_class (TREE_TYPE (field),
4768 : /*ignore_vptr*/false))
4769 : return false;
4770 453082305 : if (field)
4771 5084529 : field = next_subobject_field (DECL_CHAIN (field));
4772 : }
4773 : /* There could be a non-empty field at the end. */
4774 65783328 : for (; field; field = next_subobject_field (DECL_CHAIN (field)))
4775 335400 : if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false))
4776 : {
4777 : /* Ignore FIELD_DECLs with bit positions beyond DECL_SIZE of
4778 : the parent FIELD_DECL (if any) for classes with virtual
4779 : bases. */
4780 4328 : if (cxx_dialect >= cxx26
4781 2493 : && sz
4782 4709 : && tree_int_cst_le (sz, bit_position (field)))
4783 : break;
4784 4074 : return false;
4785 : }
4786 65447928 : ok:
4787 65449924 : if (CONSTRUCTOR_NO_CLEARING (t))
4788 : /* All the fields are initialized. */
4789 4091124 : CONSTRUCTOR_NO_CLEARING (t) = false;
4790 : return true;
4791 :
4792 1120317261 : default:
4793 : /* FIXME are we calling this too much? */
4794 1120317261 : return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
4795 : }
4796 : }
4797 :
4798 : /* *TP was not deemed constant by reduced_constant_expression_p. Explain
4799 : why and suggest what could be done about it. */
4800 :
4801 : static tree
4802 989 : verify_constant_explain_r (tree *tp, int *walk_subtrees, void *)
4803 : {
4804 989 : bool ref_p = false;
4805 :
4806 : /* No need to look into types or unevaluated operands. */
4807 989 : if (TYPE_P (*tp) || unevaluated_p (TREE_CODE (*tp)))
4808 : {
4809 0 : *walk_subtrees = false;
4810 0 : return NULL_TREE;
4811 : }
4812 :
4813 989 : switch (TREE_CODE (*tp))
4814 : {
4815 81 : CASE_CONVERT:
4816 81 : if (TREE_CODE (TREE_OPERAND (*tp, 0)) != ADDR_EXPR)
4817 : break;
4818 62 : ref_p = TYPE_REF_P (TREE_TYPE (*tp));
4819 62 : *tp = TREE_OPERAND (*tp, 0);
4820 194 : gcc_fallthrough ();
4821 194 : case ADDR_EXPR:
4822 194 : {
4823 194 : tree op = TREE_OPERAND (*tp, 0);
4824 194 : if (VAR_P (op)
4825 111 : && DECL_DECLARED_CONSTEXPR_P (op)
4826 39 : && !TREE_STATIC (op)
4827 : /* ??? We should also say something about temporaries. */
4828 230 : && !DECL_ARTIFICIAL (op))
4829 : {
4830 33 : if (ref_p)
4831 12 : inform (location_of (*tp), "reference to %qD is not a constant "
4832 : "expression", op);
4833 : else
4834 21 : inform (location_of (*tp), "pointer to %qD is not a constant "
4835 : "expression", op);
4836 33 : const location_t op_loc = DECL_SOURCE_LOCATION (op);
4837 33 : rich_location richloc (line_table, op_loc);
4838 33 : richloc.add_fixit_insert_before (op_loc, "static ");
4839 33 : inform (&richloc,
4840 : "address of non-static constexpr variable %qD may differ on "
4841 : "each invocation of the enclosing function; add %<static%> "
4842 : "to give it a constant address", op);
4843 33 : }
4844 : break;
4845 : }
4846 : default:
4847 : break;
4848 : }
4849 :
4850 : return NULL_TREE;
4851 : }
4852 :
4853 : /* Some expressions may have constant operands but are not constant
4854 : themselves, such as 1/0. Call this function to check for that
4855 : condition.
4856 :
4857 : We only call this in places that require an arithmetic constant, not in
4858 : places where we might have a non-constant expression that can be a
4859 : component of a constant expression, such as the address of a constexpr
4860 : variable that might be dereferenced later. */
4861 :
4862 : static bool
4863 632989937 : verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
4864 : bool *overflow_p)
4865 : {
4866 613717022 : if (!*non_constant_p && !reduced_constant_expression_p (t)
4867 638188414 : && t != void_node)
4868 : {
4869 5198275 : if (!allow_non_constant)
4870 : {
4871 260 : auto_diagnostic_group d;
4872 373 : error_at (cp_expr_loc_or_input_loc (t),
4873 : "%q+E is not a constant expression", t);
4874 260 : cp_walk_tree_without_duplicates (&t, verify_constant_explain_r,
4875 : nullptr);
4876 260 : }
4877 5198275 : *non_constant_p = true;
4878 : }
4879 632989937 : if (TREE_OVERFLOW_P (t))
4880 : {
4881 678 : if (!allow_non_constant)
4882 : {
4883 155 : permerror (input_location, "overflow in constant expression");
4884 : /* If we're being permissive (and are in an enforcing
4885 : context), ignore the overflow. */
4886 155 : if (flag_permissive)
4887 75 : return *non_constant_p;
4888 : }
4889 603 : *overflow_p = true;
4890 : }
4891 632989862 : return *non_constant_p;
4892 : }
4893 :
4894 : /* Check whether the shift operation with code CODE and type TYPE on LHS
4895 : and RHS is undefined. If it is, give an error with an explanation,
4896 : and return true; return false otherwise. */
4897 :
4898 : static bool
4899 60451251 : cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
4900 : enum tree_code code, tree type, tree lhs, tree rhs)
4901 : {
4902 60451251 : if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
4903 3637696 : || TREE_CODE (lhs) != INTEGER_CST
4904 3637584 : || TREE_CODE (rhs) != INTEGER_CST)
4905 : return false;
4906 :
4907 3637584 : tree lhstype = TREE_TYPE (lhs);
4908 3637584 : unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
4909 :
4910 : /* [expr.shift] The behavior is undefined if the right operand
4911 : is negative, or greater than or equal to the length in bits
4912 : of the promoted left operand. */
4913 3637584 : if (tree_int_cst_sgn (rhs) == -1)
4914 : {
4915 126 : if (!ctx->quiet)
4916 35 : permerror (loc, "right operand of shift expression %q+E is negative",
4917 : build2_loc (loc, code, type, lhs, rhs));
4918 126 : return (!flag_permissive || ctx->quiet);
4919 : }
4920 3637458 : if (compare_tree_int (rhs, uprec) >= 0)
4921 : {
4922 200 : if (!ctx->quiet)
4923 34 : permerror (loc, "right operand of shift expression %q+E is greater "
4924 : "than or equal to the precision %wu of the left operand",
4925 : build2_loc (loc, code, type, lhs, rhs), uprec);
4926 200 : return (!flag_permissive || ctx->quiet);
4927 : }
4928 :
4929 : /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
4930 : if E1 has a signed type and non-negative value, and E1x2^E2 is
4931 : representable in the corresponding unsigned type of the result type,
4932 : then that value, converted to the result type, is the resulting value;
4933 : otherwise, the behavior is undefined.
4934 : For C++20:
4935 : The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
4936 : 2^N, where N is the range exponent of the type of the result. */
4937 3637258 : if (code == LSHIFT_EXPR
4938 3465757 : && !TYPE_OVERFLOW_WRAPS (lhstype)
4939 2046516 : && cxx_dialect >= cxx11
4940 5666699 : && cxx_dialect < cxx20)
4941 : {
4942 53478 : if (tree_int_cst_sgn (lhs) == -1)
4943 : {
4944 74 : if (!ctx->quiet)
4945 18 : permerror (loc,
4946 : "left operand of shift expression %q+E is negative",
4947 : build2_loc (loc, code, type, lhs, rhs));
4948 74 : return (!flag_permissive || ctx->quiet);
4949 : }
4950 : /* For signed x << y the following:
4951 : (unsigned) x >> ((prec (lhs) - 1) - y)
4952 : if > 1, is undefined. The right-hand side of this formula
4953 : is the highest bit of the LHS that can be set (starting from 0),
4954 : so that the shift doesn't overflow. We then right-shift the LHS
4955 : to see whether any other bit is set making the original shift
4956 : undefined -- the result is not representable in the corresponding
4957 : unsigned type. */
4958 53404 : tree t = build_int_cst (unsigned_type_node, uprec - 1);
4959 53404 : t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
4960 53404 : tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
4961 53404 : t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
4962 53404 : if (tree_int_cst_lt (integer_one_node, t))
4963 : {
4964 41 : if (!ctx->quiet)
4965 7 : permerror (loc, "shift expression %q+E overflows",
4966 : build2_loc (loc, code, type, lhs, rhs));
4967 41 : return (!flag_permissive || ctx->quiet);
4968 : }
4969 : }
4970 : return false;
4971 : }
4972 :
4973 : /* Subroutine of cxx_eval_constant_expression.
4974 : Attempt to reduce the unary expression tree T to a compile time value.
4975 : If successful, return the value. Otherwise issue a diagnostic
4976 : and return error_mark_node. */
4977 :
4978 : static tree
4979 24089950 : cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
4980 : bool /*lval*/,
4981 : bool *non_constant_p, bool *overflow_p,
4982 : tree *jump_target)
4983 : {
4984 24089950 : tree r;
4985 24089950 : tree orig_arg = TREE_OPERAND (t, 0);
4986 24089950 : tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue,
4987 : non_constant_p, overflow_p,
4988 : jump_target);
4989 24089949 : if (*jump_target)
4990 : return NULL_TREE;
4991 24089948 : VERIFY_CONSTANT (arg);
4992 18947391 : location_t loc = EXPR_LOCATION (t);
4993 18947391 : enum tree_code code = TREE_CODE (t);
4994 18947391 : tree type = TREE_TYPE (t);
4995 18947391 : r = fold_unary_loc (loc, code, type, arg);
4996 18947391 : if (r == NULL_TREE)
4997 : {
4998 17 : if (arg == orig_arg)
4999 : r = t;
5000 : else
5001 13 : r = build1_loc (loc, code, type, arg);
5002 : }
5003 18947391 : VERIFY_CONSTANT (r);
5004 : return r;
5005 : }
5006 :
5007 : /* Helper function for cxx_eval_binary_expression. Try to optimize
5008 : original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
5009 : generic folding should be used. */
5010 :
5011 : static tree
5012 8351866 : cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
5013 : tree lhs, tree rhs, bool *non_constant_p,
5014 : bool *overflow_p, tree *jump_target)
5015 : {
5016 8351866 : STRIP_NOPS (lhs);
5017 8351866 : if (TREE_CODE (lhs) != ADDR_EXPR)
5018 : return NULL_TREE;
5019 :
5020 7431123 : lhs = TREE_OPERAND (lhs, 0);
5021 :
5022 : /* &A[i] p+ j => &A[i + j] */
5023 7431123 : if (TREE_CODE (lhs) == ARRAY_REF
5024 95094 : && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
5025 95094 : && TREE_CODE (rhs) == INTEGER_CST
5026 95094 : && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
5027 7526217 : && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
5028 : {
5029 95094 : tree orig_type = TREE_TYPE (t);
5030 95094 : location_t loc = EXPR_LOCATION (t);
5031 95094 : tree type = TREE_TYPE (lhs);
5032 :
5033 95094 : t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
5034 95094 : tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
5035 95094 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
5036 : non_constant_p, overflow_p,
5037 : jump_target);
5038 95094 : if (*non_constant_p)
5039 : return NULL_TREE;
5040 95082 : if (*jump_target)
5041 : return NULL_TREE;
5042 : /* Don't fold an out-of-bound access. */
5043 95082 : if (!tree_int_cst_le (t, nelts))
5044 : return NULL_TREE;
5045 95082 : rhs = cp_fold_convert (ssizetype, rhs);
5046 : /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
5047 : constexpr int A[1]; ... (char *)&A[0] + 1 */
5048 95082 : if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
5049 95082 : rhs, TYPE_SIZE_UNIT (type))))
5050 : return NULL_TREE;
5051 : /* Make sure to treat the second operand of POINTER_PLUS_EXPR
5052 : as signed. */
5053 95050 : rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
5054 95050 : TYPE_SIZE_UNIT (type));
5055 95050 : t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
5056 95050 : t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
5057 : t, NULL_TREE, NULL_TREE);
5058 95050 : t = cp_build_addr_expr (t, tf_warning_or_error);
5059 95050 : t = cp_fold_convert (orig_type, t);
5060 95050 : return cxx_eval_constant_expression (ctx, t, vc_prvalue,
5061 : non_constant_p, overflow_p,
5062 95050 : jump_target);
5063 : }
5064 :
5065 : return NULL_TREE;
5066 : }
5067 :
5068 : /* Try to fold expressions like
5069 : (struct S *) (&a[0].D.2378 + 12)
5070 : into
5071 : &MEM <struct T> [(void *)&a + 12B]
5072 : This is something normally done by gimple_fold_stmt_to_constant_1
5073 : on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
5074 : dereference the address because some details are lost.
5075 : For pointer comparisons we want such folding though so that
5076 : match.pd address_compare optimization works. */
5077 :
5078 : static tree
5079 7240046 : cxx_maybe_fold_addr_pointer_plus (tree t)
5080 : {
5081 14480095 : while (CONVERT_EXPR_P (t)
5082 7703694 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
5083 463645 : t = TREE_OPERAND (t, 0);
5084 7240046 : if (TREE_CODE (t) != POINTER_PLUS_EXPR)
5085 : return NULL_TREE;
5086 6120072 : tree op0 = TREE_OPERAND (t, 0);
5087 6120072 : tree op1 = TREE_OPERAND (t, 1);
5088 6120072 : if (TREE_CODE (op1) != INTEGER_CST)
5089 : return NULL_TREE;
5090 6120072 : while (CONVERT_EXPR_P (op0)
5091 12238092 : && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
5092 6118020 : op0 = TREE_OPERAND (op0, 0);
5093 6120072 : if (TREE_CODE (op0) != ADDR_EXPR)
5094 : return NULL_TREE;
5095 6120072 : op1 = fold_convert (ptr_type_node, op1);
5096 6120072 : tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
5097 6120072 : return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
5098 : }
5099 :
5100 : /* Subroutine of cxx_eval_constant_expression.
5101 : Like cxx_eval_unary_expression, except for binary expressions. */
5102 :
5103 : static tree
5104 93791707 : cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
5105 : value_cat lval,
5106 : bool *non_constant_p, bool *overflow_p,
5107 : tree *jump_target)
5108 : {
5109 93791707 : tree r = NULL_TREE;
5110 93791707 : tree orig_lhs = TREE_OPERAND (t, 0);
5111 93791707 : tree orig_rhs = TREE_OPERAND (t, 1);
5112 93791707 : tree lhs, rhs;
5113 93791707 : lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue,
5114 : non_constant_p, overflow_p,
5115 : jump_target);
5116 : /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
5117 : subtraction. */
5118 93791706 : if (*non_constant_p)
5119 : return t;
5120 68224430 : if (*jump_target)
5121 : return NULL_TREE;
5122 68224379 : rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue,
5123 : non_constant_p, overflow_p,
5124 : jump_target);
5125 68224379 : if (*non_constant_p)
5126 : return t;
5127 66938965 : if (*jump_target)
5128 : return NULL_TREE;
5129 :
5130 66938960 : location_t loc = EXPR_LOCATION (t);
5131 66938960 : enum tree_code code = TREE_CODE (t);
5132 66938960 : tree type = TREE_TYPE (t);
5133 :
5134 66938960 : if (code == EQ_EXPR || code == NE_EXPR)
5135 : {
5136 10432015 : bool is_code_eq = (code == EQ_EXPR);
5137 :
5138 10432015 : if (TREE_CODE (lhs) == PTRMEM_CST
5139 192 : && TREE_CODE (rhs) == PTRMEM_CST)
5140 : {
5141 61 : tree lmem = PTRMEM_CST_MEMBER (lhs);
5142 61 : tree rmem = PTRMEM_CST_MEMBER (rhs);
5143 61 : bool eq;
5144 61 : if (TREE_CODE (lmem) == TREE_CODE (rmem)
5145 61 : && TREE_CODE (lmem) == FIELD_DECL
5146 61 : && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
5147 88 : && same_type_p (DECL_CONTEXT (lmem),
5148 : DECL_CONTEXT (rmem)))
5149 : /* If both refer to (possibly different) members of the same union
5150 : (12.3), they compare equal. */
5151 : eq = true;
5152 : else
5153 34 : eq = cp_tree_equal (lhs, rhs);
5154 61 : r = constant_boolean_node (eq == is_code_eq, type);
5155 61 : }
5156 10431954 : else if ((TREE_CODE (lhs) == PTRMEM_CST
5157 10431823 : || TREE_CODE (rhs) == PTRMEM_CST)
5158 10431954 : && (null_member_pointer_value_p (lhs)
5159 131 : || null_member_pointer_value_p (rhs)))
5160 131 : r = constant_boolean_node (!is_code_eq, type);
5161 10431823 : else if (TREE_CODE (lhs) == PTRMEM_CST)
5162 0 : lhs = cplus_expand_constant (lhs);
5163 10431823 : else if (TREE_CODE (rhs) == PTRMEM_CST)
5164 0 : rhs = cplus_expand_constant (rhs);
5165 10431823 : else if (REFLECT_EXPR_P (lhs) && REFLECT_EXPR_P (rhs))
5166 : {
5167 1784 : const bool eq = compare_reflections (lhs, rhs);
5168 1784 : r = constant_boolean_node (eq == is_code_eq, type);
5169 : }
5170 : }
5171 0 : if (r == NULL_TREE
5172 66936984 : && TREE_CODE_CLASS (code) == tcc_comparison
5173 25743012 : && POINTER_TYPE_P (TREE_TYPE (lhs)))
5174 : {
5175 3620023 : if (tree lhso = cxx_maybe_fold_addr_pointer_plus (lhs))
5176 2986704 : lhs = fold_convert (TREE_TYPE (lhs), lhso);
5177 3620023 : if (tree rhso = cxx_maybe_fold_addr_pointer_plus (rhs))
5178 3133368 : rhs = fold_convert (TREE_TYPE (rhs), rhso);
5179 : }
5180 8352021 : if (code == POINTER_PLUS_EXPR && !*non_constant_p
5181 75290981 : && integer_zerop (lhs) && !integer_zerop (rhs))
5182 : {
5183 155 : if (!ctx->quiet)
5184 45 : error ("arithmetic involving a null pointer in %qE", lhs);
5185 155 : *non_constant_p = true;
5186 155 : return t;
5187 : }
5188 66938805 : else if (code == POINTER_PLUS_EXPR)
5189 : {
5190 8351866 : r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
5191 : overflow_p, jump_target);
5192 8351866 : if (*jump_target)
5193 : return NULL_TREE;
5194 : }
5195 58586939 : else if (code == SPACESHIP_EXPR)
5196 : {
5197 25360 : r = genericize_spaceship (loc, type, lhs, rhs);
5198 25360 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
5199 25360 : overflow_p, jump_target);
5200 : }
5201 :
5202 66913445 : if (r == NULL_TREE)
5203 : {
5204 66816419 : if (ctx->manifestly_const_eval == mce_true
5205 46707700 : && (flag_constexpr_fp_except
5206 46707697 : || TREE_CODE (type) != REAL_TYPE))
5207 : {
5208 46660125 : auto ofcc = make_temp_override (folding_cxx_constexpr, true);
5209 46660125 : r = fold_binary_initializer_loc (loc, code, type, lhs, rhs);
5210 46660125 : }
5211 : else
5212 20156294 : r = fold_binary_loc (loc, code, type, lhs, rhs);
5213 : }
5214 :
5215 66816419 : if (r == NULL_TREE
5216 6462292 : && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
5217 100 : && TREE_CODE (lhs) == INTEGER_CST
5218 98 : && TREE_CODE (rhs) == INTEGER_CST
5219 73375737 : && wi::neg_p (wi::to_wide (rhs)))
5220 : {
5221 : /* For diagnostics and -fpermissive emulate previous behavior of
5222 : handling shifts by negative amount. */
5223 98 : tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
5224 98 : if (nrhs)
5225 119 : r = fold_binary_loc (loc,
5226 : code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
5227 : type, lhs, nrhs);
5228 : }
5229 :
5230 66913445 : if (r == NULL_TREE)
5231 : {
5232 6462194 : if (lhs == orig_lhs && rhs == orig_rhs)
5233 : r = t;
5234 : else
5235 2492854 : r = build2_loc (loc, code, type, lhs, rhs);
5236 : }
5237 60451251 : else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
5238 433 : *non_constant_p = true;
5239 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
5240 : a local array in a constexpr function. */
5241 66913445 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
5242 54438830 : if (!ptr)
5243 54438830 : VERIFY_CONSTANT (r);
5244 : return r;
5245 : }
5246 :
5247 : /* Subroutine of cxx_eval_constant_expression.
5248 : Attempt to evaluate condition expressions. */
5249 :
5250 : static tree
5251 27469243 : cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
5252 : value_cat lval,
5253 : bool *non_constant_p, bool *overflow_p,
5254 : tree *jump_target)
5255 : {
5256 27469243 : tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5257 : vc_prvalue,
5258 : non_constant_p, overflow_p,
5259 : jump_target);
5260 27469243 : if (*jump_target)
5261 : return NULL_TREE;
5262 27469234 : VERIFY_CONSTANT (val);
5263 21600759 : if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
5264 : {
5265 : /* Evaluate the condition as if it was
5266 : if (__builtin_is_constant_evaluated ()), i.e. defer it if not
5267 : ctx->manifestly_const_eval (as sometimes we try to constant evaluate
5268 : without manifestly_const_eval even expressions or parts thereof which
5269 : will later be manifestly const_eval evaluated), otherwise fold it to
5270 : true. */
5271 687990 : if (ctx->manifestly_const_eval == mce_unknown)
5272 : {
5273 679062 : *non_constant_p = true;
5274 679062 : return t;
5275 : }
5276 8928 : val = constant_boolean_node (ctx->manifestly_const_eval == mce_true,
5277 : boolean_type_node);
5278 : }
5279 : /* Don't VERIFY_CONSTANT the other operands. */
5280 20921697 : const bool zero_p = integer_zerop (val);
5281 20921697 : if (zero_p)
5282 13776270 : val = TREE_OPERAND (t, 2);
5283 : else
5284 7145427 : val = TREE_OPERAND (t, 1);
5285 20921697 : if (TREE_CODE (t) == IF_STMT && !val)
5286 7614112 : val = void_node;
5287 :
5288 : /* P2564: If we aren't in immediate function context (including a manifestly
5289 : constant-evaluated expression), check any uses of immediate functions in
5290 : the arm we're discarding. But don't do this inside a call; we already
5291 : checked when parsing the function. */
5292 20921697 : if (ctx->manifestly_const_eval != mce_true
5293 5224959 : && !in_immediate_context ()
5294 4791427 : && !ctx->call
5295 21688620 : && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2),
5296 766923 : ctx->manifestly_const_eval))
5297 : {
5298 7 : *non_constant_p = true;
5299 7 : return t;
5300 : }
5301 :
5302 : /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still
5303 : serve as the initializer for the same object as the outer TARGET_EXPR,
5304 : as in
5305 : A a = true ? A{} : A{};
5306 : so strip the inner TARGET_EXPR so we don't materialize a temporary. */
5307 20921690 : if (TREE_CODE (val) == TARGET_EXPR)
5308 2250 : val = TARGET_EXPR_INITIAL (val);
5309 20921690 : return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
5310 20921690 : overflow_p, jump_target);
5311 : }
5312 :
5313 : /* Subroutine of cxx_eval_constant_expression.
5314 : Attempt to evaluate vector condition expressions. Unlike
5315 : cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
5316 : ternary arithmetics operation, where all 3 arguments have to be
5317 : evaluated as constants and then folding computes the result from
5318 : them. */
5319 :
5320 : static tree
5321 4788 : cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
5322 : bool *non_constant_p, bool *overflow_p,
5323 : tree *jump_target)
5324 : {
5325 4788 : tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
5326 : vc_prvalue,
5327 : non_constant_p, overflow_p,
5328 : jump_target);
5329 4788 : if (*jump_target)
5330 : return NULL_TREE;
5331 4788 : VERIFY_CONSTANT (arg1);
5332 2694 : tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
5333 : vc_prvalue,
5334 : non_constant_p, overflow_p,
5335 : jump_target);
5336 2694 : if (*jump_target)
5337 : return NULL_TREE;
5338 2694 : VERIFY_CONSTANT (arg2);
5339 2567 : tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
5340 : vc_prvalue,
5341 : non_constant_p, overflow_p,
5342 : jump_target);
5343 2567 : if (*jump_target)
5344 : return NULL_TREE;
5345 2567 : VERIFY_CONSTANT (arg3);
5346 2567 : location_t loc = EXPR_LOCATION (t);
5347 2567 : tree type = TREE_TYPE (t);
5348 2567 : tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5349 2567 : if (r == NULL_TREE)
5350 : {
5351 0 : if (arg1 == TREE_OPERAND (t, 0)
5352 0 : && arg2 == TREE_OPERAND (t, 1)
5353 0 : && arg3 == TREE_OPERAND (t, 2))
5354 : r = t;
5355 : else
5356 0 : r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
5357 : }
5358 2567 : VERIFY_CONSTANT (r);
5359 : return r;
5360 : }
5361 :
5362 : /* Returns less than, equal to, or greater than zero if KEY is found to be
5363 : less than, to match, or to be greater than the constructor_elt's INDEX. */
5364 :
5365 : static int
5366 432048 : array_index_cmp (tree key, tree index)
5367 : {
5368 432048 : gcc_assert (TREE_CODE (key) == INTEGER_CST);
5369 :
5370 432048 : switch (TREE_CODE (index))
5371 : {
5372 429163 : case INTEGER_CST:
5373 429163 : return tree_int_cst_compare (key, index);
5374 2885 : case RANGE_EXPR:
5375 2885 : {
5376 2885 : tree lo = TREE_OPERAND (index, 0);
5377 2885 : tree hi = TREE_OPERAND (index, 1);
5378 2885 : if (tree_int_cst_lt (key, lo))
5379 : return -1;
5380 2593 : else if (tree_int_cst_lt (hi, key))
5381 : return 1;
5382 : else
5383 2593 : return 0;
5384 : }
5385 0 : default:
5386 0 : gcc_unreachable ();
5387 : }
5388 : }
5389 :
5390 : /* Extract a single INTEGER_CST from RAW_DATA_CST RAW_DATA at
5391 : relative index OFF. */
5392 :
5393 : static tree
5394 29316 : raw_data_cst_elt (tree raw_data, unsigned int off)
5395 : {
5396 29316 : return build_int_cst (TREE_TYPE (raw_data),
5397 29316 : TYPE_UNSIGNED (TREE_TYPE (raw_data))
5398 58632 : ? (HOST_WIDE_INT)
5399 29073 : RAW_DATA_UCHAR_ELT (raw_data, off)
5400 : : (HOST_WIDE_INT)
5401 243 : RAW_DATA_SCHAR_ELT (raw_data, off));
5402 : }
5403 :
5404 : /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
5405 : if none. If INSERT is true, insert a matching element rather than fail. */
5406 :
5407 : static HOST_WIDE_INT
5408 7450381 : find_array_ctor_elt (tree ary, tree dindex, bool insert)
5409 : {
5410 7450381 : if (tree_int_cst_sgn (dindex) < 0)
5411 : return -1;
5412 :
5413 7450381 : unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex);
5414 7450381 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary);
5415 7450381 : unsigned HOST_WIDE_INT len = vec_safe_length (elts);
5416 :
5417 10801668 : unsigned HOST_WIDE_INT end = len;
5418 10801668 : unsigned HOST_WIDE_INT begin = 0;
5419 :
5420 : /* If the last element of the CONSTRUCTOR has its own index, we can assume
5421 : that the same is true of the other elements and index directly. */
5422 6958008 : if (end > 0)
5423 : {
5424 6835440 : tree cindex = (*elts)[end - 1].index;
5425 6835440 : if (cindex == NULL_TREE)
5426 : {
5427 : /* Verify that if the last index is missing, all indexes
5428 : are missing and there is no RAW_DATA_CST. */
5429 19502 : if (flag_checking)
5430 204088 : for (unsigned int j = 0; j < len - 1; ++j)
5431 184586 : gcc_assert ((*elts)[j].index == NULL_TREE
5432 : && TREE_CODE ((*elts)[j].value) != RAW_DATA_CST);
5433 19502 : if (i < end)
5434 19502 : return i;
5435 : else
5436 : {
5437 0 : begin = end;
5438 0 : if (i == end)
5439 : /* If the element is to be added right at the end,
5440 : make sure it is added with cleared index too. */
5441 3843660 : dindex = NULL_TREE;
5442 0 : else if (insert)
5443 : /* Otherwise, in order not to break the assumption
5444 : that CONSTRUCTOR either has all indexes or none,
5445 : we need to add indexes to all elements. */
5446 0 : for (unsigned int j = 0; j < len; ++j)
5447 0 : (*elts)[j].index = build_int_cst (TREE_TYPE (dindex), j);
5448 : }
5449 : }
5450 6815938 : else if (TREE_CODE (cindex) == INTEGER_CST
5451 6815938 : && compare_tree_int (cindex, end - 1) == 0)
5452 : {
5453 6557318 : tree value = (*elts)[end - 1].value;
5454 6557318 : if (i < end)
5455 : {
5456 3587309 : if (i == end - 1 && TREE_CODE (value) == RAW_DATA_CST)
5457 : begin = end - 1;
5458 : else
5459 3587219 : return i;
5460 : }
5461 2970009 : else if (TREE_CODE (value) == RAW_DATA_CST
5462 3002165 : && wi::to_offset (dindex) < (wi::to_offset (cindex)
5463 32156 : + RAW_DATA_LENGTH (value)))
5464 16078 : begin = end - 1;
5465 : else
5466 2953931 : begin = end;
5467 : }
5468 : }
5469 :
5470 : /* Otherwise, find a matching index by means of a binary search. */
5471 4077814 : while (begin != end)
5472 : {
5473 410360 : unsigned HOST_WIDE_INT middle = (begin + end) / 2;
5474 410360 : constructor_elt &elt = (*elts)[middle];
5475 410360 : tree idx = elt.index;
5476 :
5477 410360 : int cmp = array_index_cmp (dindex, idx);
5478 410360 : if (cmp > 0
5479 62913 : && TREE_CODE (elt.value) == RAW_DATA_CST
5480 493690 : && wi::to_offset (dindex) < (wi::to_offset (idx)
5481 83330 : + RAW_DATA_LENGTH (elt.value)))
5482 29178 : cmp = 0;
5483 410360 : if (cmp < 0)
5484 : end = middle;
5485 209941 : else if (cmp > 0)
5486 33735 : begin = middle + 1;
5487 : else
5488 : {
5489 176206 : if (insert && TREE_CODE (elt.value) == RAW_DATA_CST)
5490 : {
5491 : /* We need to split the RAW_DATA_CST elt. */
5492 122 : constructor_elt e;
5493 122 : gcc_checking_assert (TREE_CODE (idx) != RANGE_EXPR);
5494 244 : unsigned int off = (wi::to_offset (dindex)
5495 244 : - wi::to_offset (idx)).to_uhwi ();
5496 122 : tree value = elt.value;
5497 122 : unsigned int len = RAW_DATA_LENGTH (value);
5498 122 : if (off > 1 && len >= off + 3)
5499 22 : value = copy_node (elt.value);
5500 122 : if (off)
5501 : {
5502 33 : if (off > 1)
5503 33 : RAW_DATA_LENGTH (elt.value) = off;
5504 : else
5505 0 : elt.value = raw_data_cst_elt (elt.value, 0);
5506 33 : e.index = size_binop (PLUS_EXPR, elt.index,
5507 : build_int_cst (TREE_TYPE (elt.index),
5508 : off));
5509 33 : e.value = NULL_TREE;
5510 33 : ++middle;
5511 33 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
5512 : }
5513 122 : (*elts)[middle].value = raw_data_cst_elt (value, off);
5514 122 : if (len >= off + 2)
5515 : {
5516 111 : e.index = (*elts)[middle].index;
5517 111 : e.index = size_binop (PLUS_EXPR, e.index,
5518 : build_one_cst (TREE_TYPE (e.index)));
5519 111 : if (len >= off + 3)
5520 : {
5521 111 : RAW_DATA_LENGTH (value) -= off + 1;
5522 111 : RAW_DATA_POINTER (value) += off + 1;
5523 111 : e.value = value;
5524 : }
5525 : else
5526 0 : e.value = raw_data_cst_elt (value, off + 1);
5527 111 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
5528 : }
5529 122 : return middle;
5530 : }
5531 31669 : if (insert && TREE_CODE (idx) == RANGE_EXPR)
5532 : {
5533 : /* We need to split the range. */
5534 345 : constructor_elt e;
5535 345 : tree lo = TREE_OPERAND (idx, 0);
5536 345 : tree hi = TREE_OPERAND (idx, 1);
5537 345 : tree value = elt.value;
5538 345 : dindex = fold_convert (sizetype, dindex);
5539 345 : if (tree_int_cst_lt (lo, dindex))
5540 : {
5541 : /* There are still some lower elts; shorten the range. */
5542 170 : tree new_hi = int_const_binop (MINUS_EXPR, dindex,
5543 85 : size_one_node);
5544 85 : if (tree_int_cst_equal (lo, new_hi))
5545 : /* Only one element left, no longer a range. */
5546 33 : elt.index = lo;
5547 : else
5548 52 : TREE_OPERAND (idx, 1) = new_hi;
5549 : /* Append the element we want to insert. */
5550 85 : ++middle;
5551 85 : e.index = dindex;
5552 85 : e.value = unshare_constructor (value);
5553 85 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
5554 : }
5555 : else
5556 : /* No lower elts, the range elt is now ours. */
5557 260 : elt.index = dindex;
5558 :
5559 345 : if (tree_int_cst_lt (dindex, hi))
5560 : {
5561 : /* There are still some higher elts; append a range. */
5562 478 : tree new_lo = int_const_binop (PLUS_EXPR, dindex,
5563 239 : size_one_node);
5564 239 : if (tree_int_cst_equal (new_lo, hi))
5565 98 : e.index = hi;
5566 : else
5567 141 : e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
5568 239 : e.value = unshare_constructor (value);
5569 239 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
5570 : }
5571 : }
5572 176084 : return middle;
5573 : }
5574 : }
5575 :
5576 3667454 : if (insert)
5577 : {
5578 3545000 : constructor_elt e = { dindex, NULL_TREE };
5579 3545000 : vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e);
5580 3545000 : return end;
5581 : }
5582 :
5583 : return -1;
5584 : }
5585 :
5586 : /* Return a pointer to the constructor_elt of CTOR which matches INDEX. If no
5587 : matching constructor_elt exists, then add one to CTOR.
5588 :
5589 : As an optimization, if POS_HINT is non-negative then it is used as a guess
5590 : for the (integer) index of the matching constructor_elt within CTOR.
5591 :
5592 : If POS_HINT is -2, it means do not insert. */
5593 :
5594 : static constructor_elt *
5595 33873587 : get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
5596 : {
5597 : /* Check the hint first. */
5598 3332952 : if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)
5599 37206539 : && CONSTRUCTOR_ELT (ctor, pos_hint)->index == index)
5600 : return CONSTRUCTOR_ELT (ctor, pos_hint);
5601 :
5602 30540646 : bool insertp = (pos_hint != -2);
5603 30540646 : tree type = TREE_TYPE (ctor);
5604 30540646 : if (TREE_CODE (type) == VECTOR_TYPE && index == NULL_TREE)
5605 : {
5606 8216 : gcc_assert (insertp);
5607 8216 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE);
5608 8216 : return &CONSTRUCTOR_ELTS (ctor)->last();
5609 : }
5610 30532430 : else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
5611 : {
5612 4710445 : if (TREE_CODE (index) == RANGE_EXPR)
5613 : {
5614 : /* Support for RANGE_EXPR index lookups is currently limited to
5615 : accessing an existing element via POS_HINT, or appending a new
5616 : element to the end of CTOR. ??? Support for other access
5617 : patterns may also be needed. */
5618 3 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5619 3 : if (vec_safe_length (elts))
5620 : {
5621 3 : tree lo = TREE_OPERAND (index, 0);
5622 3 : gcc_assert (array_index_cmp (elts->last().index, lo) < 0);
5623 : }
5624 3 : gcc_assert (insertp);
5625 3 : CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE);
5626 3 : return &elts->last();
5627 : }
5628 :
5629 4710442 : HOST_WIDE_INT i = find_array_ctor_elt (ctor, index, insertp);
5630 4710442 : if (i < 0)
5631 : {
5632 917 : gcc_assert (!insertp);
5633 : return nullptr;
5634 : }
5635 4709525 : constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i);
5636 4709525 : if (!insertp && cep->index && TREE_CODE (cep->index) == RANGE_EXPR)
5637 : {
5638 : /* Split a range even if we aren't inserting new entries. */
5639 0 : gcc_assert (!insertp);
5640 0 : i = find_array_ctor_elt (ctor, index, /*insert*/true);
5641 0 : gcc_assert (i >= 0);
5642 0 : cep = CONSTRUCTOR_ELT (ctor, i);
5643 : }
5644 4709525 : gcc_assert (cep->index == NULL_TREE
5645 : || TREE_CODE (cep->index) != RANGE_EXPR);
5646 : return cep;
5647 : }
5648 : else
5649 : {
5650 25821985 : gcc_assert (TREE_CODE (index) == FIELD_DECL
5651 : && (same_type_ignoring_top_level_qualifiers_p
5652 : (DECL_CONTEXT (index), TREE_TYPE (ctor))));
5653 :
5654 : /* We must keep the CONSTRUCTOR's ELTS in FIELD order.
5655 : Usually we meet initializers in that order, but it is
5656 : possible for base types to be placed not in program
5657 : order. */
5658 25821985 : tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
5659 25821985 : unsigned HOST_WIDE_INT idx = 0;
5660 25821985 : constructor_elt *cep = NULL;
5661 :
5662 : /* Check if we're changing the active member of a union. */
5663 453457 : if (TREE_CODE (type) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)
5664 25964037 : && CONSTRUCTOR_ELT (ctor, 0)->index != index)
5665 2572 : vec_safe_truncate (CONSTRUCTOR_ELTS (ctor), 0);
5666 : /* If the bit offset of INDEX is larger than that of the last
5667 : constructor_elt, then we can just immediately append a new
5668 : constructor_elt to the end of CTOR. */
5669 25819413 : else if (CONSTRUCTOR_NELTS (ctor)
5670 31696787 : && tree_int_cst_compare (bit_position (index),
5671 30807254 : bit_position (CONSTRUCTOR_ELTS (ctor)
5672 15403627 : ->last().index)) > 0)
5673 : {
5674 5875089 : idx = CONSTRUCTOR_NELTS (ctor);
5675 5875089 : goto insert;
5676 : }
5677 :
5678 : /* Otherwise, we need to iterate over CTOR to find or insert INDEX
5679 : appropriately. */
5680 :
5681 21648979 : for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor), idx, &cep);
5682 1702083 : idx++, fields = DECL_CHAIN (fields))
5683 : {
5684 11230621 : if (index == cep->index)
5685 9470055 : goto found;
5686 :
5687 : /* The field we're initializing must be on the field
5688 : list. Look to see if it is present before the
5689 : field the current ELT initializes. */
5690 18380225 : for (; fields != cep->index; fields = DECL_CHAIN (fields))
5691 16678142 : if (index == fields)
5692 58483 : goto insert;
5693 : }
5694 : /* We fell off the end of the CONSTRUCTOR, so insert a new
5695 : entry at the end. */
5696 :
5697 16351930 : insert:
5698 16351930 : if (!insertp)
5699 : return nullptr;
5700 :
5701 16351927 : {
5702 16351927 : constructor_elt ce = { index, NULL_TREE };
5703 :
5704 16351927 : vec_safe_insert (CONSTRUCTOR_ELTS (ctor), idx, ce);
5705 16351927 : cep = CONSTRUCTOR_ELT (ctor, idx);
5706 : }
5707 25821982 : found:;
5708 :
5709 25821982 : return cep;
5710 : }
5711 : }
5712 :
5713 : /* Under the control of CTX, issue a detailed diagnostic for
5714 : an out-of-bounds subscript INDEX into the expression ARRAY. */
5715 :
5716 : static void
5717 566 : diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index)
5718 : {
5719 566 : if (!ctx->quiet)
5720 : {
5721 116 : tree arraytype = TREE_TYPE (array);
5722 :
5723 : /* Convert the unsigned array subscript to a signed integer to avoid
5724 : printing huge numbers for small negative values. */
5725 116 : tree sidx = fold_convert (ssizetype, index);
5726 116 : STRIP_ANY_LOCATION_WRAPPER (array);
5727 116 : if (DECL_P (array))
5728 : {
5729 75 : auto_diagnostic_group d;
5730 75 : if (TYPE_DOMAIN (arraytype))
5731 69 : error_at (loc, "array subscript value %qE is outside the bounds "
5732 : "of array %qD of type %qT", sidx, array, arraytype);
5733 : else
5734 6 : error_at (loc, "nonzero array subscript %qE is used with array %qD of "
5735 : "type %qT with unknown bounds", sidx, array, arraytype);
5736 75 : inform (DECL_SOURCE_LOCATION (array), "declared here");
5737 75 : }
5738 41 : else if (TYPE_DOMAIN (arraytype))
5739 38 : error_at (loc, "array subscript value %qE is outside the bounds "
5740 : "of array type %qT", sidx, arraytype);
5741 : else
5742 3 : error_at (loc, "nonzero array subscript %qE is used with array of type %qT "
5743 : "with unknown bounds", sidx, arraytype);
5744 : }
5745 566 : }
5746 :
5747 : /* Return the number of elements for TYPE (which is an ARRAY_TYPE or
5748 : a VECTOR_TYPE). */
5749 :
5750 : static tree
5751 14932104 : get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
5752 : bool *non_constant_p, bool *overflow_p,
5753 : tree *jump_target)
5754 : {
5755 14932104 : tree nelts;
5756 14932104 : if (TREE_CODE (type) == ARRAY_TYPE)
5757 : {
5758 14932104 : if (TYPE_DOMAIN (type))
5759 14931856 : nelts = array_type_nelts_top (type);
5760 : else
5761 248 : nelts = size_zero_node;
5762 : }
5763 0 : else if (VECTOR_TYPE_P (type))
5764 0 : nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
5765 : else
5766 0 : gcc_unreachable ();
5767 :
5768 : /* For VLAs, the number of elements won't be an integer constant. */
5769 14932104 : nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
5770 : non_constant_p, overflow_p,
5771 : jump_target);
5772 14932104 : return nelts;
5773 : }
5774 :
5775 : /* Extract element INDEX consisting of CHARS_PER_ELT chars from
5776 : STRING_CST STRING. */
5777 :
5778 : static tree
5779 2684932 : extract_string_elt (tree string, unsigned chars_per_elt, unsigned index)
5780 : {
5781 2684932 : tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string)));
5782 2684932 : tree r;
5783 :
5784 2684932 : if (chars_per_elt == 1)
5785 2004539 : r = build_int_cst (type, TREE_STRING_POINTER (string)[index]);
5786 : else
5787 : {
5788 680393 : const unsigned char *ptr
5789 680393 : = ((const unsigned char *)TREE_STRING_POINTER (string)
5790 680393 : + index * chars_per_elt);
5791 680393 : r = native_interpret_expr (type, ptr, chars_per_elt);
5792 : }
5793 2684932 : return r;
5794 : }
5795 :
5796 : /* Subroutine of cxx_eval_array_reference. T is an ARRAY_REF; evaluate the
5797 : subscript, diagnose any problems with it, and return the result. */
5798 :
5799 : static tree
5800 15116401 : eval_and_check_array_index (const constexpr_ctx *ctx,
5801 : tree t, bool allow_one_past,
5802 : bool *non_constant_p, bool *overflow_p,
5803 : tree *jump_target)
5804 : {
5805 15116401 : location_t loc = cp_expr_loc_or_input_loc (t);
5806 15116401 : tree ary = TREE_OPERAND (t, 0);
5807 15116401 : t = TREE_OPERAND (t, 1);
5808 15116401 : tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue,
5809 : non_constant_p, overflow_p,
5810 : jump_target);
5811 15116401 : if (*jump_target)
5812 : return NULL_TREE;
5813 15116401 : VERIFY_CONSTANT (index);
5814 :
5815 14931570 : if (!tree_fits_shwi_p (index)
5816 14931570 : || tree_int_cst_sgn (index) < 0)
5817 : {
5818 108 : diag_array_subscript (loc, ctx, ary, index);
5819 108 : *non_constant_p = true;
5820 108 : return t;
5821 : }
5822 :
5823 14931462 : tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
5824 : overflow_p, jump_target);
5825 14931462 : if (*jump_target)
5826 : return NULL_TREE;
5827 14931462 : VERIFY_CONSTANT (nelts);
5828 14931399 : if (allow_one_past
5829 14931399 : ? !tree_int_cst_le (index, nelts)
5830 9954333 : : !tree_int_cst_lt (index, nelts))
5831 : {
5832 458 : diag_array_subscript (loc, ctx, ary, index);
5833 458 : *non_constant_p = true;
5834 458 : return t;
5835 : }
5836 :
5837 : return index;
5838 : }
5839 :
5840 : /* Subroutine of cxx_eval_constant_expression.
5841 : Attempt to reduce a reference to an array slot. */
5842 :
5843 : static tree
5844 10827587 : cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
5845 : value_cat lval,
5846 : bool *non_constant_p, bool *overflow_p,
5847 : tree *jump_target)
5848 : {
5849 10827587 : tree oldary = TREE_OPERAND (t, 0);
5850 10827587 : tree ary = cxx_eval_constant_expression (ctx, oldary,
5851 : lval,
5852 : non_constant_p, overflow_p,
5853 : jump_target);
5854 10827587 : if (*non_constant_p)
5855 : return t;
5856 10628774 : if (*jump_target)
5857 : return NULL_TREE;
5858 10628774 : if (!lval
5859 5650435 : && TREE_CODE (ary) == VIEW_CONVERT_EXPR
5860 54102 : && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
5861 10682876 : && (TYPE_MAIN_VARIANT (TREE_TYPE (t))
5862 54102 : == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))))
5863 54102 : ary = TREE_OPERAND (ary, 0);
5864 :
5865 10628774 : tree oldidx = TREE_OPERAND (t, 1);
5866 10628774 : tree index = eval_and_check_array_index (ctx, t, lval,
5867 : non_constant_p, overflow_p,
5868 : jump_target);
5869 10628774 : if (*non_constant_p)
5870 : return t;
5871 10443380 : if (*jump_target)
5872 : return NULL_TREE;
5873 :
5874 10443380 : if (lval && ary == oldary && index == oldidx)
5875 : return t;
5876 6656158 : else if (lval == vc_discard)
5877 : return t;
5878 6656158 : else if (lval)
5879 1189604 : return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
5880 :
5881 5466554 : unsigned len = 0, elem_nchars = 1;
5882 5466554 : tree elem_type = TREE_TYPE (TREE_TYPE (ary));
5883 5466554 : if (TREE_CODE (ary) == CONSTRUCTOR)
5884 2738109 : len = CONSTRUCTOR_NELTS (ary);
5885 2728445 : else if (TREE_CODE (ary) == STRING_CST)
5886 : {
5887 2674351 : elem_nchars = (TYPE_PRECISION (elem_type)
5888 2674351 : / TYPE_PRECISION (char_type_node));
5889 2674351 : len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
5890 : }
5891 54094 : else if (TREE_CODE (ary) == VECTOR_CST)
5892 : /* We don't create variable-length VECTOR_CSTs. */
5893 54094 : len = VECTOR_CST_NELTS (ary).to_constant ();
5894 : else
5895 : {
5896 : /* We can't do anything with other tree codes, so use
5897 : VERIFY_CONSTANT to complain and fail. */
5898 0 : VERIFY_CONSTANT (ary);
5899 0 : gcc_unreachable ();
5900 : }
5901 :
5902 5466554 : bool found;
5903 5466554 : HOST_WIDE_INT i = 0;
5904 5466554 : if (TREE_CODE (ary) == CONSTRUCTOR)
5905 : {
5906 2738109 : HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
5907 2738109 : found = (ix >= 0);
5908 2738109 : if (found)
5909 2616660 : i = ix;
5910 : }
5911 : else
5912 : {
5913 2728445 : i = tree_to_shwi (index);
5914 2728445 : found = (i < len);
5915 : }
5916 :
5917 5466554 : if (found)
5918 : {
5919 5344654 : tree r;
5920 5344654 : if (TREE_CODE (ary) == CONSTRUCTOR)
5921 : {
5922 2616660 : r = (*CONSTRUCTOR_ELTS (ary))[i].value;
5923 2616660 : if (TREE_CODE (r) == RAW_DATA_CST)
5924 : {
5925 29194 : tree ridx = (*CONSTRUCTOR_ELTS (ary))[i].index;
5926 29194 : gcc_checking_assert (ridx);
5927 29194 : unsigned int off
5928 29194 : = (wi::to_offset (index) - wi::to_offset (ridx)).to_uhwi ();
5929 29194 : r = raw_data_cst_elt (r, off);
5930 : }
5931 : }
5932 2727994 : else if (TREE_CODE (ary) == VECTOR_CST)
5933 54094 : r = VECTOR_CST_ELT (ary, i);
5934 : else
5935 2673900 : r = extract_string_elt (ary, elem_nchars, i);
5936 :
5937 2757188 : if (r)
5938 : /* Don't VERIFY_CONSTANT here. */
5939 5344654 : return r;
5940 :
5941 : /* Otherwise the element doesn't have a value yet. */
5942 : }
5943 :
5944 : /* Not found. */
5945 :
5946 121900 : if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
5947 63 : return build_constructor (elem_type, NULL);
5948 :
5949 121837 : if (TREE_CODE (ary) == CONSTRUCTOR
5950 121837 : && CONSTRUCTOR_NO_CLEARING (ary))
5951 : {
5952 : /* 'ary' is part of the aggregate initializer we're currently
5953 : building; if there's no initializer for this element yet,
5954 : that's an error. */
5955 51 : if (!ctx->quiet)
5956 16 : error ("accessing uninitialized array element");
5957 51 : *non_constant_p = true;
5958 51 : return t;
5959 : }
5960 :
5961 : /* If it's within the array bounds but doesn't have an explicit
5962 : initializer, it's initialized from {}. But use build_value_init
5963 : directly for non-aggregates to avoid creating a garbage CONSTRUCTOR. */
5964 121786 : tree val;
5965 121786 : constexpr_ctx new_ctx;
5966 121786 : if (CP_AGGREGATE_TYPE_P (elem_type))
5967 : {
5968 479 : tree empty_ctor = build_constructor (init_list_type_node, NULL);
5969 479 : val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
5970 : }
5971 : else
5972 121307 : val = build_value_init (elem_type, tf_warning_or_error);
5973 :
5974 : /* Create a new constructor only if we don't already have a suitable one. */
5975 121786 : const bool new_ctor = (!SCALAR_TYPE_P (elem_type)
5976 122297 : && (!ctx->ctor
5977 45 : || !same_type_ignoring_top_level_qualifiers_p
5978 45 : (elem_type, TREE_TYPE (ctx->ctor))));
5979 502 : if (new_ctor)
5980 : {
5981 502 : new_ctx = *ctx;
5982 : /* We clear the object here. We used to replace it with T, but that
5983 : caused problems (101371, 108158); and anyway, T is the initializer,
5984 : not the target object. */
5985 502 : new_ctx.object = NULL_TREE;
5986 502 : new_ctx.ctor = build_constructor (elem_type, NULL);
5987 502 : ctx = &new_ctx;
5988 : }
5989 121786 : t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
5990 : overflow_p, jump_target);
5991 121786 : if (new_ctor && t != ctx->ctor)
5992 481 : free_constructor (ctx->ctor);
5993 : return t;
5994 : }
5995 :
5996 : /* Subroutine of cxx_eval_constant_expression.
5997 : Attempt to reduce a field access of a value of class type. */
5998 :
5999 : static tree
6000 106441801 : cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
6001 : value_cat lval,
6002 : bool *non_constant_p, bool *overflow_p,
6003 : tree *jump_target)
6004 : {
6005 106441801 : unsigned HOST_WIDE_INT i;
6006 106441801 : tree field;
6007 106441801 : tree value;
6008 106441801 : tree part = TREE_OPERAND (t, 1);
6009 106441801 : tree orig_whole = TREE_OPERAND (t, 0);
6010 106441801 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6011 : lval,
6012 : non_constant_p, overflow_p,
6013 : jump_target);
6014 106441801 : if (*non_constant_p)
6015 : return t;
6016 63807083 : if (*jump_target)
6017 : return NULL_TREE;
6018 63807083 : if (INDIRECT_REF_P (whole)
6019 63807083 : && integer_zerop (TREE_OPERAND (whole, 0)))
6020 : {
6021 177 : if (!ctx->quiet)
6022 39 : error ("dereferencing a null pointer in %qE", orig_whole);
6023 177 : *non_constant_p = true;
6024 177 : return t;
6025 : }
6026 :
6027 63806906 : if (TREE_CODE (whole) == PTRMEM_CST)
6028 1463 : whole = cplus_expand_constant (whole);
6029 63806906 : if (whole == orig_whole)
6030 : return t;
6031 43145423 : if (lval == vc_discard)
6032 : return t;
6033 43145399 : if (lval)
6034 17362670 : return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
6035 : whole, part, NULL_TREE);
6036 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6037 : CONSTRUCTOR. */
6038 25782729 : if (TREE_CODE (whole) != CONSTRUCTOR)
6039 : {
6040 0 : if (!ctx->quiet)
6041 0 : error ("%qE is not a constant expression", orig_whole);
6042 0 : *non_constant_p = true;
6043 0 : return t;
6044 : }
6045 25781231 : if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole))
6046 25784409 : && DECL_MUTABLE_P (part))
6047 : {
6048 144 : if (!ctx->quiet)
6049 16 : error ("mutable %qD is not usable in a constant expression", part);
6050 144 : *non_constant_p = true;
6051 144 : return t;
6052 : }
6053 :
6054 25782585 : bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole));
6055 36777211 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6056 : {
6057 : /* Use name match for PMF fields, as a variant will have a
6058 : different FIELD_DECL with a different type. */
6059 36665181 : if (pmf ? DECL_NAME (field) == DECL_NAME (part)
6060 : : field == part)
6061 : {
6062 25670555 : if (value == void_node)
6063 3 : goto uninit;
6064 25670552 : if (value)
6065 : {
6066 25670534 : STRIP_ANY_LOCATION_WRAPPER (value);
6067 25670534 : return value;
6068 : }
6069 : else
6070 : /* We're in the middle of initializing it. */
6071 : break;
6072 : }
6073 : }
6074 112048 : if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE)
6075 : {
6076 106 : if (CONSTRUCTOR_NELTS (whole) > 0)
6077 : {
6078 : /* DR 1188 says we don't have to deal with this. */
6079 91 : if (!ctx->quiet)
6080 : {
6081 19 : constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0);
6082 19 : if (cep->value == NULL_TREE)
6083 9 : error ("accessing uninitialized member %qD", part);
6084 : else
6085 10 : error ("accessing %qD member instead of active %qD member "
6086 : "in constant expression", part, cep->index);
6087 : }
6088 91 : *non_constant_p = true;
6089 91 : return t;
6090 : }
6091 15 : else if (!CONSTRUCTOR_NO_CLEARING (whole))
6092 : {
6093 : /* Value-initialized union, check if looking at the first member. */
6094 12 : tree first = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (whole)));
6095 12 : if (first != part)
6096 : {
6097 9 : if (!ctx->quiet)
6098 3 : error ("accessing %qD member instead of initialized %qD "
6099 : "member in constant expression", part, first);
6100 9 : *non_constant_p = true;
6101 9 : return t;
6102 : }
6103 : }
6104 : }
6105 :
6106 : /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
6107 : classes never get represented; throw together a value now. */
6108 111948 : if (is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
6109 103372 : return build_constructor (TREE_TYPE (t), NULL);
6110 :
6111 8576 : gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
6112 :
6113 8576 : if (CONSTRUCTOR_NO_CLEARING (whole))
6114 : {
6115 110 : uninit:
6116 : /* 'whole' is part of the aggregate initializer we're currently
6117 : building; if there's no initializer for this member yet, that's an
6118 : error. */
6119 113 : if (!ctx->quiet)
6120 22 : error ("accessing uninitialized member %qD", part);
6121 113 : *non_constant_p = true;
6122 113 : return t;
6123 : }
6124 :
6125 : /* If there's no explicit init for this field, it's value-initialized. */
6126 :
6127 8466 : if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
6128 : {
6129 : /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR
6130 : and copy the flags. */
6131 7970 : constructor_elt *e = get_or_insert_ctor_field (whole, part);
6132 7970 : e->value = value = build_constructor (TREE_TYPE (part), NULL);
6133 7970 : CONSTRUCTOR_ZERO_PADDING_BITS (value)
6134 7970 : = CONSTRUCTOR_ZERO_PADDING_BITS (whole);
6135 7970 : return value;
6136 : }
6137 :
6138 496 : value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
6139 496 : return cxx_eval_constant_expression (ctx, value,
6140 : lval,
6141 : non_constant_p, overflow_p,
6142 496 : jump_target);
6143 : }
6144 :
6145 : /* Subroutine of cxx_eval_constant_expression.
6146 : Attempt to reduce a field access of a value of class type that is
6147 : expressed as a BIT_FIELD_REF. */
6148 :
6149 : static tree
6150 16029 : cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
6151 : value_cat lval,
6152 : bool *non_constant_p, bool *overflow_p,
6153 : tree *jump_target)
6154 : {
6155 16029 : tree orig_whole = TREE_OPERAND (t, 0);
6156 16029 : tree retval, fldval, utype, mask;
6157 16029 : bool fld_seen = false;
6158 16029 : HOST_WIDE_INT istart, isize;
6159 16029 : tree whole = cxx_eval_constant_expression (ctx, orig_whole,
6160 : lval,
6161 : non_constant_p, overflow_p,
6162 : jump_target);
6163 16029 : tree start, field, value;
6164 16029 : unsigned HOST_WIDE_INT i;
6165 :
6166 16029 : if (*jump_target)
6167 : return NULL_TREE;
6168 16029 : if (whole == orig_whole)
6169 : return t;
6170 : /* Don't VERIFY_CONSTANT here; we only want to check that we got a
6171 : CONSTRUCTOR. */
6172 15818 : if (!*non_constant_p
6173 15818 : && TREE_CODE (whole) != VECTOR_CST
6174 1739 : && TREE_CODE (whole) != CONSTRUCTOR)
6175 : {
6176 0 : if (!ctx->quiet)
6177 0 : error ("%qE is not a constant expression", orig_whole);
6178 0 : *non_constant_p = true;
6179 : }
6180 15818 : if (*non_constant_p)
6181 : return t;
6182 :
6183 15818 : if (TREE_CODE (whole) == VECTOR_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)))
6184 : {
6185 14079 : if (tree r = fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
6186 : TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)))
6187 : return r;
6188 0 : if (!ctx->quiet)
6189 0 : error ("%qE is not a constant expression", orig_whole);
6190 0 : *non_constant_p = true;
6191 0 : return t;
6192 : }
6193 :
6194 1739 : start = TREE_OPERAND (t, 2);
6195 1739 : istart = tree_to_shwi (start);
6196 1739 : isize = tree_to_shwi (TREE_OPERAND (t, 1));
6197 1739 : utype = TREE_TYPE (t);
6198 1739 : if (!TYPE_UNSIGNED (utype))
6199 0 : utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
6200 1739 : retval = build_int_cst (utype, 0);
6201 24346 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
6202 : {
6203 22607 : tree bitpos = bit_position (field);
6204 22607 : STRIP_ANY_LOCATION_WRAPPER (value);
6205 22607 : if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
6206 : return value;
6207 22607 : if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
6208 22607 : && TREE_CODE (value) == INTEGER_CST
6209 22607 : && tree_fits_shwi_p (bitpos)
6210 45214 : && tree_fits_shwi_p (DECL_SIZE (field)))
6211 : {
6212 22607 : HOST_WIDE_INT bit = tree_to_shwi (bitpos);
6213 22607 : HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
6214 22607 : HOST_WIDE_INT shift;
6215 22607 : if (bit >= istart && bit + sz <= istart + isize)
6216 : {
6217 5217 : fldval = fold_convert (utype, value);
6218 5217 : mask = build_int_cst_type (utype, -1);
6219 5217 : mask = fold_build2 (LSHIFT_EXPR, utype, mask,
6220 : size_int (TYPE_PRECISION (utype) - sz));
6221 5217 : mask = fold_build2 (RSHIFT_EXPR, utype, mask,
6222 : size_int (TYPE_PRECISION (utype) - sz));
6223 5217 : fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
6224 5217 : shift = bit - istart;
6225 5217 : if (BYTES_BIG_ENDIAN)
6226 : shift = TYPE_PRECISION (utype) - shift - sz;
6227 5217 : fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
6228 : size_int (shift));
6229 5217 : retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
6230 5217 : fld_seen = true;
6231 : }
6232 : }
6233 : }
6234 1739 : if (fld_seen)
6235 1739 : return fold_convert (TREE_TYPE (t), retval);
6236 0 : gcc_unreachable ();
6237 : return error_mark_node;
6238 : }
6239 :
6240 : /* Helper for cxx_eval_bit_cast.
6241 : Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From
6242 : types and types of all subobjects have is_union_v<T>, is_pointer_v<T>,
6243 : is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static
6244 : data members of reference type. */
6245 :
6246 : static bool
6247 6018 : check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
6248 : tree orig_type)
6249 : {
6250 6563 : if (TREE_CODE (type) == UNION_TYPE)
6251 : {
6252 63 : if (!ctx->quiet)
6253 : {
6254 21 : if (type == orig_type)
6255 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6256 : "a union type", "__builtin_bit_cast", type);
6257 : else
6258 15 : error_at (loc, "%qs is not a constant expression because %qT "
6259 : "contains a union type", "__builtin_bit_cast",
6260 : orig_type);
6261 : }
6262 63 : return true;
6263 : }
6264 : if (TREE_CODE (type) == POINTER_TYPE)
6265 : {
6266 57 : if (!ctx->quiet)
6267 : {
6268 18 : if (type == orig_type)
6269 6 : error_at (loc, "%qs is not a constant expression because %qT is "
6270 : "a pointer type", "__builtin_bit_cast", type);
6271 : else
6272 12 : error_at (loc, "%qs is not a constant expression because %qT "
6273 : "contains a pointer type", "__builtin_bit_cast",
6274 : orig_type);
6275 : }
6276 57 : return true;
6277 : }
6278 : if (TREE_CODE (type) == REFERENCE_TYPE)
6279 : {
6280 0 : if (!ctx->quiet)
6281 : {
6282 0 : if (type == orig_type)
6283 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6284 : "a reference type", "__builtin_bit_cast", type);
6285 : else
6286 0 : error_at (loc, "%qs is not a constant expression because %qT "
6287 : "contains a reference type", "__builtin_bit_cast",
6288 : orig_type);
6289 : }
6290 0 : return true;
6291 : }
6292 2113 : if (TYPE_PTRMEM_P (type))
6293 : {
6294 36 : if (!ctx->quiet)
6295 : {
6296 12 : if (type == orig_type)
6297 12 : error_at (loc, "%qs is not a constant expression because %qT is "
6298 : "a pointer to member type", "__builtin_bit_cast",
6299 : type);
6300 : else
6301 0 : error_at (loc, "%qs is not a constant expression because %qT "
6302 : "contains a pointer to member type",
6303 : "__builtin_bit_cast", orig_type);
6304 : }
6305 36 : return true;
6306 : }
6307 6407 : if (TYPE_VOLATILE (type))
6308 : {
6309 0 : if (!ctx->quiet)
6310 : {
6311 0 : if (type == orig_type)
6312 0 : error_at (loc, "%qs is not a constant expression because %qT is "
6313 : "volatile", "__builtin_bit_cast", type);
6314 : else
6315 0 : error_at (loc, "%qs is not a constant expression because %qT "
6316 : "contains a volatile subobject",
6317 : "__builtin_bit_cast", orig_type);
6318 : }
6319 0 : return true;
6320 : }
6321 6407 : if (TREE_CODE (type) == RECORD_TYPE)
6322 70710 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
6323 68705 : if (TREE_CODE (field) == FIELD_DECL
6324 68705 : && check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
6325 : return true;
6326 6317 : if (TREE_CODE (type) == ARRAY_TYPE)
6327 545 : return check_bit_cast_type (ctx, loc, TREE_TYPE (type), orig_type);
6328 : return false;
6329 : }
6330 :
6331 : /* Helper function for cxx_eval_bit_cast. For unsigned char or
6332 : std::byte members of CONSTRUCTOR (recursively) if they contain
6333 : some indeterminate bits (as set in MASK), remove the ctor elts,
6334 : mark the CONSTRUCTOR as CONSTRUCTOR_NO_CLEARING and clear the
6335 : bits in MASK. */
6336 :
6337 : static void
6338 707 : clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask)
6339 : {
6340 707 : if (TREE_CODE (t) != CONSTRUCTOR)
6341 : return;
6342 :
6343 : unsigned i, j = 0;
6344 : tree index, value;
6345 2284 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)
6346 : {
6347 1577 : tree type = TREE_TYPE (value);
6348 1577 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
6349 2715 : && DECL_BIT_FIELD_TYPE (index) != NULL_TREE)
6350 : {
6351 270 : if (is_byte_access_type_not_plain_char (DECL_BIT_FIELD_TYPE (index)))
6352 : {
6353 135 : HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (index));
6354 135 : gcc_assert (fldsz != 0);
6355 135 : HOST_WIDE_INT pos = int_byte_position (index);
6356 135 : HOST_WIDE_INT bpos
6357 135 : = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (index));
6358 135 : bpos %= BITS_PER_UNIT;
6359 135 : HOST_WIDE_INT end
6360 135 : = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
6361 135 : gcc_assert (end == 1 || end == 2);
6362 135 : unsigned char *p = mask + pos;
6363 135 : unsigned char mask_save[2];
6364 135 : mask_save[0] = mask[pos];
6365 135 : mask_save[1] = end == 2 ? mask[pos + 1] : 0;
6366 135 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
6367 : sorry_at (loc, "PDP11 bit-field handling unsupported"
6368 : " in %qs", "__builtin_bit_cast");
6369 135 : else if (BYTES_BIG_ENDIAN)
6370 : {
6371 : /* Big endian. */
6372 : if (bpos + fldsz <= BITS_PER_UNIT)
6373 : *p &= ~(((1 << fldsz) - 1)
6374 : << (BITS_PER_UNIT - bpos - fldsz));
6375 : else
6376 : {
6377 : gcc_assert (bpos);
6378 : *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
6379 : p++;
6380 : fldsz -= BITS_PER_UNIT - bpos;
6381 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
6382 : *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
6383 : }
6384 : }
6385 : else
6386 : {
6387 : /* Little endian. */
6388 135 : if (bpos + fldsz <= BITS_PER_UNIT)
6389 135 : *p &= ~(((1 << fldsz) - 1) << bpos);
6390 : else
6391 : {
6392 0 : gcc_assert (bpos);
6393 0 : *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
6394 0 : p++;
6395 0 : fldsz -= BITS_PER_UNIT - bpos;
6396 0 : gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
6397 0 : *p &= ~((1 << fldsz) - 1);
6398 : }
6399 : }
6400 135 : if (mask_save[0] != mask[pos]
6401 99 : || (end == 2 && mask_save[1] != mask[pos + 1]))
6402 : {
6403 36 : CONSTRUCTOR_NO_CLEARING (t) = 1;
6404 36 : continue;
6405 : }
6406 : }
6407 : }
6408 1307 : else if (is_byte_access_type_not_plain_char (type))
6409 : {
6410 228 : HOST_WIDE_INT pos;
6411 228 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
6412 132 : pos = tree_to_shwi (index);
6413 : else
6414 96 : pos = int_byte_position (index);
6415 228 : if (mask[pos])
6416 : {
6417 48 : CONSTRUCTOR_NO_CLEARING (t) = 1;
6418 48 : mask[pos] = 0;
6419 48 : continue;
6420 : }
6421 : }
6422 1493 : if (TREE_CODE (value) == CONSTRUCTOR)
6423 : {
6424 368 : HOST_WIDE_INT pos;
6425 368 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
6426 144 : pos = tree_to_shwi (index)
6427 72 : * tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))));
6428 : else
6429 296 : pos = int_byte_position (index);
6430 368 : clear_uchar_or_std_byte_in_mask (loc, value, mask + pos);
6431 : }
6432 1493 : if (i != j)
6433 : {
6434 180 : CONSTRUCTOR_ELT (t, j)->index = index;
6435 180 : CONSTRUCTOR_ELT (t, j)->value = value;
6436 : }
6437 1493 : ++j;
6438 : }
6439 1414 : if (CONSTRUCTOR_NELTS (t) != j)
6440 84 : vec_safe_truncate (CONSTRUCTOR_ELTS (t), j);
6441 : }
6442 :
6443 : /* Subroutine of cxx_eval_constant_expression.
6444 : Attempt to evaluate a BIT_CAST_EXPR. */
6445 :
6446 : static tree
6447 1238 : cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
6448 : bool *overflow_p, tree *jump_target)
6449 : {
6450 1238 : if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
6451 1238 : TREE_TYPE (t))
6452 4004 : || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0),
6453 1157 : EXPR_LOCATION (t)),
6454 1157 : TREE_TYPE (TREE_OPERAND (t, 0)),
6455 1157 : TREE_TYPE (TREE_OPERAND (t, 0))))
6456 : {
6457 156 : *non_constant_p = true;
6458 156 : return t;
6459 : }
6460 :
6461 1082 : tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue,
6462 : non_constant_p, overflow_p,
6463 : jump_target);
6464 1082 : if (*non_constant_p)
6465 : return t;
6466 708 : if (*jump_target)
6467 : return NULL_TREE;
6468 :
6469 708 : location_t loc = EXPR_LOCATION (t);
6470 708 : if (BITS_PER_UNIT != 8 || CHAR_BIT != 8)
6471 : {
6472 : if (!ctx->quiet)
6473 : sorry_at (loc, "%qs cannot be constant evaluated on the target",
6474 : "__builtin_bit_cast");
6475 : *non_constant_p = true;
6476 : return t;
6477 : }
6478 :
6479 708 : if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))))
6480 : {
6481 0 : if (!ctx->quiet)
6482 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
6483 : "type is too large", "__builtin_bit_cast");
6484 0 : *non_constant_p = true;
6485 0 : return t;
6486 : }
6487 :
6488 708 : HOST_WIDE_INT len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t)));
6489 708 : if (len < 0 || (int) len != len)
6490 : {
6491 0 : if (!ctx->quiet)
6492 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
6493 : "type is too large", "__builtin_bit_cast");
6494 0 : *non_constant_p = true;
6495 0 : return t;
6496 : }
6497 :
6498 708 : unsigned char buf[64];
6499 708 : unsigned char *ptr, *mask;
6500 708 : size_t alen = (size_t) len * 2;
6501 708 : if (alen <= sizeof (buf))
6502 : ptr = buf;
6503 : else
6504 3 : ptr = XNEWVEC (unsigned char, alen);
6505 708 : mask = ptr + (size_t) len;
6506 : /* At the beginning consider everything indeterminate. */
6507 708 : memset (mask, ~0, (size_t) len);
6508 :
6509 708 : if (native_encode_initializer (op, ptr, len, 0, mask) != len)
6510 : {
6511 0 : if (!ctx->quiet)
6512 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
6513 : "argument cannot be encoded", "__builtin_bit_cast");
6514 0 : *non_constant_p = true;
6515 0 : if (ptr != buf)
6516 0 : XDELETE (ptr);
6517 0 : return t;
6518 : }
6519 :
6520 708 : tree r = NULL_TREE;
6521 708 : if (can_native_interpret_type_p (TREE_TYPE (t)))
6522 : {
6523 369 : r = native_interpret_expr (TREE_TYPE (t), ptr, len);
6524 369 : if (is_byte_access_type_not_plain_char (TREE_TYPE (t)))
6525 : {
6526 46 : gcc_assert (len == 1);
6527 46 : if (mask[0])
6528 : {
6529 24 : memset (mask, 0, len);
6530 24 : r = build_constructor (TREE_TYPE (r), NULL);
6531 24 : CONSTRUCTOR_NO_CLEARING (r) = 1;
6532 : }
6533 : }
6534 : }
6535 339 : else if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
6536 : {
6537 339 : r = native_interpret_aggregate (TREE_TYPE (t), ptr, 0, len);
6538 339 : if (r != NULL_TREE)
6539 : {
6540 339 : clear_type_padding_in_mask (TREE_TYPE (t), mask);
6541 339 : clear_uchar_or_std_byte_in_mask (loc, r, mask);
6542 339 : if (CHECKING_P)
6543 : {
6544 339 : tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue,
6545 : non_constant_p, overflow_p,
6546 : jump_target);
6547 339 : gcc_checking_assert (e == r && !*jump_target);
6548 : r = e;
6549 : }
6550 : }
6551 : }
6552 :
6553 708 : if (r != NULL_TREE)
6554 : {
6555 5935 : for (int i = 0; i < len; i++)
6556 5317 : if (mask[i])
6557 : {
6558 90 : if (!ctx->quiet)
6559 30 : error_at (loc, "%qs accessing uninitialized byte at offset %d",
6560 : "__builtin_bit_cast", i);
6561 90 : *non_constant_p = true;
6562 90 : r = t;
6563 90 : break;
6564 : }
6565 708 : if (ptr != buf)
6566 3 : XDELETE (ptr);
6567 708 : return r;
6568 : }
6569 :
6570 0 : if (!ctx->quiet)
6571 0 : sorry_at (loc, "%qs cannot be constant evaluated because the "
6572 : "argument cannot be interpreted", "__builtin_bit_cast");
6573 0 : *non_constant_p = true;
6574 0 : if (ptr != buf)
6575 0 : XDELETE (ptr);
6576 : return t;
6577 : }
6578 :
6579 : /* Subroutine of cxx_eval_constant_expression.
6580 : Evaluate a short-circuited logical expression T in the context
6581 : of a given constexpr CALL. BAILOUT_VALUE is the value for
6582 : early return. CONTINUE_VALUE is used here purely for
6583 : sanity check purposes. */
6584 :
6585 : static tree
6586 15893607 : cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
6587 : tree bailout_value, tree continue_value,
6588 : bool *non_constant_p, bool *overflow_p,
6589 : tree *jump_target)
6590 : {
6591 15893607 : tree r;
6592 15893607 : tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
6593 : vc_prvalue, non_constant_p,
6594 : overflow_p, jump_target);
6595 15893606 : if (*jump_target)
6596 : return NULL_TREE;
6597 15893597 : VERIFY_CONSTANT (lhs);
6598 8807501 : if (tree_int_cst_equal (lhs, bailout_value))
6599 : return lhs;
6600 7077036 : gcc_assert (tree_int_cst_equal (lhs, continue_value));
6601 7077036 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
6602 : vc_prvalue, non_constant_p,
6603 : overflow_p, jump_target);
6604 7077036 : if (*jump_target)
6605 : return NULL_TREE;
6606 7077036 : VERIFY_CONSTANT (r);
6607 : return r;
6608 : }
6609 :
6610 : /* REF is a COMPONENT_REF designating a particular field. V is a vector of
6611 : CONSTRUCTOR elements to initialize (part of) an object containing that
6612 : field. Return a pointer to the constructor_elt corresponding to the
6613 : initialization of the field. */
6614 :
6615 : static constructor_elt *
6616 0 : base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
6617 : {
6618 0 : tree aggr = TREE_OPERAND (ref, 0);
6619 0 : tree field = TREE_OPERAND (ref, 1);
6620 0 : HOST_WIDE_INT i;
6621 0 : constructor_elt *ce;
6622 :
6623 0 : gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
6624 :
6625 0 : if (TREE_CODE (aggr) == COMPONENT_REF)
6626 : {
6627 0 : constructor_elt *base_ce
6628 0 : = base_field_constructor_elt (v, aggr);
6629 0 : v = CONSTRUCTOR_ELTS (base_ce->value);
6630 : }
6631 :
6632 0 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
6633 0 : if (ce->index == field)
6634 0 : return ce;
6635 :
6636 0 : gcc_unreachable ();
6637 : return NULL;
6638 : }
6639 :
6640 : /* Some of the expressions fed to the constexpr mechanism are calls to
6641 : constructors, which have type void. In that case, return the type being
6642 : initialized by the constructor. */
6643 :
6644 : static tree
6645 610629108 : initialized_type (tree t)
6646 : {
6647 613086992 : if (TYPE_P (t))
6648 : return t;
6649 613086523 : tree type = TREE_TYPE (t);
6650 613086523 : if (TREE_CODE (t) == CALL_EXPR)
6651 : {
6652 : /* A constructor call has void type, so we need to look deeper. */
6653 87990434 : tree fn = get_function_named_in_call (t);
6654 87988440 : if (fn && TREE_CODE (fn) == FUNCTION_DECL
6655 175812517 : && DECL_CXX_CONSTRUCTOR_P (fn))
6656 5049720 : type = DECL_CONTEXT (fn);
6657 : }
6658 525096089 : else if (TREE_CODE (t) == COMPOUND_EXPR)
6659 2457884 : return initialized_type (TREE_OPERAND (t, 1));
6660 522638205 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
6661 456653 : type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
6662 610628639 : return cv_unqualified (type);
6663 : }
6664 :
6665 : /* We're about to initialize element INDEX of an array or class from VALUE.
6666 : Set up NEW_CTX appropriately by adjusting .object to refer to the
6667 : subobject and creating a new CONSTRUCTOR if the element is itself
6668 : a class or array. */
6669 :
6670 : static void
6671 3289554 : init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
6672 : tree index, tree &value)
6673 : {
6674 3289554 : new_ctx = *ctx;
6675 :
6676 3289554 : if (index && TREE_CODE (index) != INTEGER_CST
6677 2989064 : && TREE_CODE (index) != FIELD_DECL
6678 3 : && TREE_CODE (index) != RANGE_EXPR)
6679 : /* This won't have an element in the new CONSTRUCTOR. */
6680 : return;
6681 :
6682 3289554 : tree type = initialized_type (value);
6683 3289554 : if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
6684 : /* A non-aggregate member doesn't get its own CONSTRUCTOR. */
6685 : return;
6686 703368 : if (VECTOR_TYPE_P (type)
6687 2884 : && VECTOR_TYPE_P (TREE_TYPE (ctx->ctor))
6688 704291 : && index == NULL_TREE)
6689 : /* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
6690 : vector is constructed from smaller vectors, doesn't get its own
6691 : CONSTRUCTOR either. */
6692 : return;
6693 :
6694 : /* The sub-aggregate initializer might contain a placeholder;
6695 : update object to refer to the subobject and ctor to refer to
6696 : the (newly created) sub-initializer. */
6697 702445 : if (ctx->object)
6698 : {
6699 515481 : if (index == NULL_TREE || TREE_CODE (index) == RANGE_EXPR)
6700 : /* There's no well-defined subobject for this index. */
6701 3 : new_ctx.object = NULL_TREE;
6702 : else
6703 515478 : new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
6704 : }
6705 :
6706 702445 : if (is_empty_class (type))
6707 : /* Leave ctor null for an empty subobject, they aren't represented in the
6708 : result of evaluation. */
6709 623834 : new_ctx.ctor = NULL_TREE;
6710 : else
6711 : {
6712 78611 : tree elt = build_constructor (type, NULL);
6713 78611 : CONSTRUCTOR_NO_CLEARING (elt) = true;
6714 78611 : new_ctx.ctor = elt;
6715 : }
6716 :
6717 702445 : if (TREE_CODE (value) == TARGET_EXPR)
6718 : /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR. */
6719 54861 : value = TARGET_EXPR_INITIAL (value);
6720 : }
6721 :
6722 : /* We're about to process an initializer for a class or array TYPE. Make
6723 : sure that CTX is set up appropriately. */
6724 :
6725 : static void
6726 2172429 : verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
6727 : {
6728 : /* We don't bother building a ctor for an empty base subobject. */
6729 2172429 : if (is_empty_class (type))
6730 : return;
6731 :
6732 : /* We're in the middle of an initializer that might involve placeholders;
6733 : our caller should have created a CONSTRUCTOR for us to put the
6734 : initializer into. We will either return that constructor or T. */
6735 1554566 : gcc_assert (ctx->ctor);
6736 1554566 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
6737 : (type, TREE_TYPE (ctx->ctor)));
6738 : /* We used to check that ctx->ctor was empty, but that isn't the case when
6739 : the object is zero-initialized before calling the constructor. */
6740 1554566 : if (ctx->object)
6741 : {
6742 1141633 : tree otype = TREE_TYPE (ctx->object);
6743 1141633 : gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)
6744 : /* Handle flexible array members. */
6745 : || (TREE_CODE (otype) == ARRAY_TYPE
6746 : && TYPE_DOMAIN (otype) == NULL_TREE
6747 : && TREE_CODE (type) == ARRAY_TYPE
6748 : && (same_type_ignoring_top_level_qualifiers_p
6749 : (TREE_TYPE (type), TREE_TYPE (otype)))));
6750 : }
6751 1554566 : gcc_assert (!ctx->object || !DECL_P (ctx->object)
6752 : || ctx->global->get_value (ctx->object) == ctx->ctor);
6753 : }
6754 :
6755 : /* Subroutine of cxx_eval_constant_expression.
6756 : The expression tree T denotes a C-style array or a C-style
6757 : aggregate. Reduce it to a constant expression. */
6758 :
6759 : static tree
6760 2171787 : cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
6761 : value_cat lval,
6762 : bool *non_constant_p, bool *overflow_p,
6763 : tree *jump_target)
6764 : {
6765 2171787 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
6766 2171787 : bool changed = false;
6767 2171787 : gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
6768 2171787 : tree type = TREE_TYPE (t);
6769 :
6770 2171787 : constexpr_ctx new_ctx;
6771 2171787 : if (TYPE_PTRMEMFUNC_P (type) || VECTOR_TYPE_P (type))
6772 : {
6773 : /* We don't really need the ctx->ctor business for a PMF or
6774 : vector, but it's simpler to use the same code. */
6775 32072 : new_ctx = *ctx;
6776 32072 : new_ctx.ctor = build_constructor (type, NULL);
6777 32072 : new_ctx.object = NULL_TREE;
6778 32072 : ctx = &new_ctx;
6779 2171787 : };
6780 2171787 : verify_ctor_sanity (ctx, type);
6781 2171787 : vec<constructor_elt, va_gc> **p = nullptr;
6782 2171787 : if (ctx->ctor)
6783 : {
6784 2171779 : p = &CONSTRUCTOR_ELTS (ctx->ctor);
6785 4339490 : vec_alloc (*p, vec_safe_length (v));
6786 2171779 : if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t))
6787 16053 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1;
6788 : }
6789 :
6790 2171787 : unsigned i;
6791 2171787 : tree index, value;
6792 2171787 : bool constant_p = true;
6793 2171787 : bool side_effects_p = false;
6794 4849202 : FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
6795 : {
6796 3283400 : tree orig_value = value;
6797 3283400 : init_subob_ctx (ctx, new_ctx, index, value);
6798 : /* Like in cxx_eval_store_expression, omit entries for empty fields. */
6799 3283400 : bool no_slot = new_ctx.ctor == NULL_TREE;
6800 3283400 : int pos_hint = -1;
6801 3283400 : if (new_ctx.ctor != ctx->ctor && !no_slot)
6802 : {
6803 : /* If we built a new CONSTRUCTOR, attach it now so that other
6804 : initializers can refer to it. */
6805 72653 : constructor_elt *cep = get_or_insert_ctor_field (ctx->ctor, index);
6806 72653 : cep->value = new_ctx.ctor;
6807 72653 : pos_hint = cep - (*p)->begin();
6808 72653 : }
6809 3210747 : else if (TREE_CODE (type) == UNION_TYPE)
6810 : /* Otherwise if we're constructing a non-aggregate union member, set
6811 : the active union member now so that we can later detect and diagnose
6812 : if its initializer attempts to activate another member. */
6813 1116 : get_or_insert_ctor_field (ctx->ctor, index);
6814 3283400 : tree elt = cxx_eval_constant_expression (&new_ctx, value,
6815 : lval,
6816 : non_constant_p, overflow_p,
6817 : jump_target);
6818 3283400 : if (*jump_target)
6819 : return NULL_TREE;
6820 : /* Don't VERIFY_CONSTANT here. */
6821 3283400 : if (ctx->quiet && *non_constant_p)
6822 : break;
6823 2677415 : if (elt != orig_value)
6824 494681 : changed = true;
6825 :
6826 2677415 : if (!TREE_CONSTANT (elt))
6827 1573979 : constant_p = false;
6828 2677415 : if (TREE_SIDE_EFFECTS (elt))
6829 168 : side_effects_p = true;
6830 2677415 : if (index && TREE_CODE (index) == COMPONENT_REF)
6831 : {
6832 : /* This is an initialization of a vfield inside a base
6833 : subaggregate that we already initialized; push this
6834 : initialization into the previous initialization. */
6835 0 : constructor_elt *inner = base_field_constructor_elt (*p, index);
6836 0 : inner->value = elt;
6837 0 : changed = true;
6838 0 : }
6839 2677415 : else if (no_slot)
6840 : /* This is an initializer for an empty field; now that we've
6841 : checked that it's constant, we can ignore it. */
6842 : changed = true;
6843 2054135 : else if (index
6844 2045919 : && (TREE_CODE (index) == NOP_EXPR
6845 2045919 : || TREE_CODE (index) == POINTER_PLUS_EXPR))
6846 : {
6847 : /* Old representation of empty bases. FIXME remove. */
6848 0 : gcc_checking_assert (false);
6849 : gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index))));
6850 : changed = true;
6851 : }
6852 : else
6853 : {
6854 2054135 : if (TREE_CODE (type) == UNION_TYPE
6855 2054135 : && (*p)->last().index != index)
6856 : /* The initializer erroneously changed the active union member that
6857 : we're initializing. */
6858 7 : gcc_assert (*non_constant_p);
6859 : else
6860 : {
6861 : /* The initializer might have mutated the underlying CONSTRUCTOR,
6862 : so recompute the location of the target constructer_elt. */
6863 2054128 : constructor_elt *cep
6864 2054128 : = get_or_insert_ctor_field (ctx->ctor, index, pos_hint);
6865 2054128 : cep->value = elt;
6866 : }
6867 :
6868 : /* Adding or replacing an element might change the ctor's flags. */
6869 2054135 : TREE_CONSTANT (ctx->ctor) = constant_p;
6870 2054135 : TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
6871 : }
6872 : }
6873 2171787 : if (*non_constant_p)
6874 : return t;
6875 1565754 : if (!changed)
6876 : {
6877 560984 : if (VECTOR_TYPE_P (type))
6878 14351 : t = fold (t);
6879 560984 : return t;
6880 : }
6881 1004770 : t = ctx->ctor;
6882 1004770 : if (!t)
6883 8 : t = build_constructor (type, NULL);
6884 : /* We're done building this CONSTRUCTOR, so now we can interpret an
6885 : element without an explicit initializer as value-initialized. */
6886 1004770 : CONSTRUCTOR_NO_CLEARING (t) = false;
6887 1004770 : TREE_CONSTANT (t) = constant_p;
6888 1004770 : TREE_SIDE_EFFECTS (t) = side_effects_p;
6889 1004770 : if (VECTOR_TYPE_P (type))
6890 4200 : t = fold (t);
6891 : return t;
6892 : }
6893 :
6894 : /* Subroutine of cxx_eval_constant_expression.
6895 : The expression tree T is a VEC_INIT_EXPR which denotes the desired
6896 : initialization of a non-static data member of array type. Reduce it to a
6897 : CONSTRUCTOR.
6898 :
6899 : Note that apart from value-initialization (when VALUE_INIT is true),
6900 : this is only intended to support value-initialization and the
6901 : initializations done by defaulted constructors for classes with
6902 : non-static data members of array type. In this case, VEC_INIT_EXPR_INIT
6903 : will either be NULL_TREE for the default constructor, or a COMPONENT_REF
6904 : for the copy/move constructor. */
6905 :
6906 : static tree
6907 642 : cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
6908 : bool value_init, value_cat lval,
6909 : bool *non_constant_p, bool *overflow_p,
6910 : tree *jump_target)
6911 : {
6912 642 : tree elttype = TREE_TYPE (atype);
6913 642 : verify_ctor_sanity (ctx, atype);
6914 642 : vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
6915 642 : bool pre_init = false;
6916 642 : unsigned HOST_WIDE_INT i;
6917 642 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
6918 :
6919 642 : if (init && TREE_CODE (init) == CONSTRUCTOR)
6920 0 : return cxx_eval_bare_aggregate (ctx, init, lval,
6921 0 : non_constant_p, overflow_p, jump_target);
6922 :
6923 : /* We already checked access when building the VEC_INIT_EXPR. */
6924 642 : deferring_access_check_sentinel acs (dk_deferred);
6925 :
6926 : /* For the default constructor, build up a call to the default
6927 : constructor of the element type. We only need to handle class types
6928 : here, as for a constructor to be constexpr, all members must be
6929 : initialized, which for a defaulted default constructor means they must
6930 : be of a class type with a constexpr default constructor. */
6931 642 : if (TREE_CODE (elttype) == ARRAY_TYPE)
6932 : /* We only do this at the lowest level. */;
6933 593 : else if (value_init)
6934 : {
6935 182 : init = build_value_init (elttype, complain);
6936 182 : pre_init = true;
6937 : }
6938 411 : else if (!init)
6939 : {
6940 268 : releasing_vec argvec;
6941 268 : init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
6942 : &argvec, elttype, LOOKUP_NORMAL,
6943 : complain);
6944 268 : init = build_aggr_init_expr (elttype, init);
6945 268 : pre_init = true;
6946 268 : }
6947 :
6948 642 : bool zeroed_out = false;
6949 642 : if (!CONSTRUCTOR_NO_CLEARING (ctx->ctor))
6950 : {
6951 : /* We're initializing an array object that had been zero-initialized
6952 : earlier. Truncate ctx->ctor, and propagate its zeroed state by
6953 : clearing CONSTRUCTOR_NO_CLEARING on each of the aggregate element
6954 : initializers we append to it. */
6955 156 : gcc_checking_assert (initializer_zerop (ctx->ctor));
6956 156 : zeroed_out = true;
6957 156 : vec_safe_truncate (*p, 0);
6958 : }
6959 :
6960 642 : tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
6961 : overflow_p, jump_target);
6962 642 : if (*jump_target)
6963 : return NULL_TREE;
6964 642 : unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
6965 6365 : for (i = 0; i < max; ++i)
6966 : {
6967 6154 : tree idx = build_int_cst (size_type_node, i);
6968 6154 : tree eltinit;
6969 6154 : bool reuse = false;
6970 6154 : constexpr_ctx new_ctx;
6971 6623 : init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
6972 6154 : bool no_slot = new_ctx.ctor == NULL_TREE;
6973 6154 : if (new_ctx.ctor != ctx->ctor && !no_slot)
6974 : {
6975 5958 : if (zeroed_out)
6976 5445 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = false;
6977 5958 : CONSTRUCTOR_APPEND_ELT (*p, idx, new_ctx.ctor);
6978 : }
6979 6154 : if (TREE_CODE (elttype) == ARRAY_TYPE)
6980 : {
6981 : /* A multidimensional array; recurse. */
6982 181 : if (value_init || init == NULL_TREE)
6983 : {
6984 171 : eltinit = NULL_TREE;
6985 171 : reuse = i == 0;
6986 : }
6987 : else
6988 10 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
6989 181 : eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit,
6990 : value_init, lval, non_constant_p,
6991 : overflow_p, jump_target);
6992 : }
6993 5973 : else if (pre_init)
6994 : {
6995 : /* Initializing an element using value or default initialization
6996 : we just pre-built above. */
6997 5685 : if (init == void_node)
6998 : /* Trivial default-init, don't do anything to the CONSTRUCTOR. */
6999 3 : return ctx->ctor;
7000 5682 : eltinit = init;
7001 5682 : if (CLASS_TYPE_P (elttype) && new_ctx.object)
7002 : /* Clarify what object is being initialized (118285). */
7003 5538 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7004 5682 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7005 : non_constant_p, overflow_p,
7006 : jump_target);
7007 5682 : reuse = i == 0;
7008 : }
7009 : else
7010 : {
7011 : /* Copying an element. */
7012 288 : eltinit = cp_build_array_ref (input_location, init, idx, complain);
7013 288 : if (!lvalue_p (init))
7014 257 : eltinit = move (eltinit);
7015 288 : eltinit = (perform_implicit_conversion_flags
7016 288 : (elttype, eltinit, complain,
7017 : LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
7018 281 : if (CLASS_TYPE_P (elttype)
7019 281 : && new_ctx.object
7020 558 : && !error_operand_p (eltinit))
7021 : /* Clarify what object is being initialized (118285). */
7022 266 : eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
7023 288 : eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
7024 : non_constant_p, overflow_p,
7025 : jump_target);
7026 : }
7027 6151 : if (*jump_target)
7028 : return NULL_TREE;
7029 6151 : if (*non_constant_p)
7030 : break;
7031 5987 : if (no_slot)
7032 : {
7033 : /* This is an initializer for an empty subobject; now that we've
7034 : checked that it's constant, we can ignore it. */
7035 18 : gcc_checking_assert (i == 0);
7036 : break;
7037 : }
7038 5969 : else if (new_ctx.ctor != ctx->ctor)
7039 : {
7040 : /* We appended this element above; update the value. */
7041 5831 : gcc_assert ((*p)->last().index == idx);
7042 5831 : (*p)->last().value = eltinit;
7043 : }
7044 : else
7045 138 : CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
7046 : /* Reuse the result of cxx_eval_constant_expression call
7047 : from the first iteration to all others if it is a constant
7048 : initializer that doesn't require relocations. */
7049 5969 : if (reuse
7050 5969 : && max > 1
7051 5969 : && (eltinit == NULL_TREE
7052 399 : || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
7053 399 : == null_pointer_node)))
7054 : {
7055 246 : if (new_ctx.ctor != ctx->ctor)
7056 114 : eltinit = new_ctx.ctor;
7057 246 : tree range = build2 (RANGE_EXPR, size_type_node,
7058 : build_int_cst (size_type_node, 1),
7059 246 : build_int_cst (size_type_node, max - 1));
7060 246 : CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
7061 246 : break;
7062 : }
7063 5723 : else if (i == 0)
7064 208 : vec_safe_reserve (*p, max);
7065 : }
7066 :
7067 639 : if (!*non_constant_p)
7068 : {
7069 475 : init = ctx->ctor;
7070 475 : CONSTRUCTOR_NO_CLEARING (init) = false;
7071 : }
7072 639 : return init;
7073 : }
7074 :
7075 : static tree
7076 524 : cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
7077 : value_cat lval,
7078 : bool *non_constant_p, bool *overflow_p, tree *jump_target)
7079 : {
7080 524 : tree atype = TREE_TYPE (t);
7081 524 : tree init = VEC_INIT_EXPR_INIT (t);
7082 524 : bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
7083 524 : if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
7084 : ;
7085 74 : else if (CONSTRUCTOR_NELTS (init) == 0
7086 74 : && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
7087 : {
7088 : /* Handle {} as value-init. */
7089 : init = NULL_TREE;
7090 : value_init = true;
7091 : }
7092 : else
7093 : {
7094 : /* This is a more complicated case, like needing to loop over trailing
7095 : elements; call build_vec_init and evaluate the result. */
7096 63 : tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
7097 63 : constexpr_ctx new_ctx = *ctx;
7098 63 : if (!ctx->object)
7099 : {
7100 : /* We want to have an initialization target for an VEC_INIT_EXPR.
7101 : If we don't already have one in CTX, use the VEC_INIT_EXPR_SLOT. */
7102 51 : new_ctx.object = VEC_INIT_EXPR_SLOT (t);
7103 51 : tree ctor = new_ctx.ctor = build_constructor (atype, NULL);
7104 51 : CONSTRUCTOR_NO_CLEARING (ctor) = true;
7105 51 : ctx->global->put_value (new_ctx.object, ctor);
7106 51 : ctx = &new_ctx;
7107 : }
7108 63 : init = expand_vec_init_expr (ctx->object, t, complain);
7109 63 : return cxx_eval_constant_expression (ctx, init, lval, non_constant_p,
7110 : overflow_p, jump_target);
7111 : }
7112 461 : tree r = cxx_eval_vec_init_1 (ctx, atype, init, value_init,
7113 : lval, non_constant_p, overflow_p, jump_target);
7114 461 : if (*non_constant_p)
7115 : return t;
7116 : else
7117 320 : return r;
7118 : }
7119 :
7120 : /* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
7121 : where the desired type is an array of unknown bounds because the variable
7122 : has had its bounds deduced since the wrapping expression was created. */
7123 :
7124 : static bool
7125 351814572 : same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
7126 : {
7127 351814572 : while (TREE_CODE (type1) == ARRAY_TYPE
7128 54425 : && TREE_CODE (type2) == ARRAY_TYPE
7129 351814576 : && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
7130 : {
7131 2 : type1 = TREE_TYPE (type1);
7132 2 : type2 = TREE_TYPE (type2);
7133 : }
7134 351814572 : return same_type_ignoring_top_level_qualifiers_p (type1, type2);
7135 : }
7136 :
7137 : /* Try to determine the currently active union member for an expression
7138 : with UNION_TYPE. If it can be determined, return the FIELD_DECL,
7139 : otherwise return NULL_TREE. */
7140 :
7141 : static tree
7142 109 : cxx_union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target)
7143 : {
7144 109 : constexpr_ctx new_ctx = *ctx;
7145 109 : new_ctx.quiet = true;
7146 109 : bool non_constant_p = false, overflow_p = false;
7147 109 : tree ctor = cxx_eval_constant_expression (&new_ctx, t, vc_prvalue,
7148 : &non_constant_p,
7149 : &overflow_p, jump_target);
7150 109 : if (*jump_target)
7151 : return NULL_TREE;
7152 109 : if (TREE_CODE (ctor) == CONSTRUCTOR
7153 40 : && CONSTRUCTOR_NELTS (ctor) == 1
7154 16 : && CONSTRUCTOR_ELT (ctor, 0)->index
7155 125 : && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL)
7156 : return CONSTRUCTOR_ELT (ctor, 0)->index;
7157 : return NULL_TREE;
7158 : }
7159 :
7160 : /* Helper function for cxx_fold_indirect_ref_1, called recursively. */
7161 :
7162 : static tree
7163 12575799 : cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
7164 : tree op, unsigned HOST_WIDE_INT off, bool *empty_base,
7165 : tree *jump_target)
7166 : {
7167 19174373 : tree optype = TREE_TYPE (op);
7168 19174373 : unsigned HOST_WIDE_INT const_nunits;
7169 19174373 : if (off == 0 && similar_type_p (optype, type))
7170 : return op;
7171 12573065 : else if (cxx_dialect >= cxx26
7172 3730815 : && VAR_P (op)
7173 1541950 : && DECL_VTABLE_OR_VTT_P (op)
7174 12789 : && same_type_ignoring_top_level_qualifiers_p (type,
7175 : ptrdiff_type_node)
7176 12574048 : && POINTER_TYPE_P (strip_array_types (optype)))
7177 : {
7178 : /* We often read some virtual table elements using ptrdiff_t rather
7179 : than pointer type. */
7180 983 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc,
7181 : strip_array_types (optype),
7182 : op, off, empty_base,
7183 : jump_target))
7184 983 : return fold_convert (type, ret);
7185 : }
7186 12572082 : else if (TREE_CODE (optype) == COMPLEX_TYPE
7187 12572082 : && similar_type_p (type, TREE_TYPE (optype)))
7188 : {
7189 : /* *(foo *)&complexfoo => __real__ complexfoo */
7190 0 : if (off == 0)
7191 0 : return build1_loc (loc, REALPART_EXPR, type, op);
7192 : /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
7193 0 : else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
7194 0 : return build1_loc (loc, IMAGPART_EXPR, type, op);
7195 : }
7196 : /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF<vectorfoo,...> */
7197 12572082 : else if (VECTOR_TYPE_P (optype)
7198 0 : && similar_type_p (type, TREE_TYPE (optype))
7199 12572082 : && TYPE_VECTOR_SUBPARTS (optype).is_constant (&const_nunits))
7200 : {
7201 0 : unsigned HOST_WIDE_INT part_width = tree_to_uhwi (TYPE_SIZE_UNIT (type));
7202 0 : unsigned HOST_WIDE_INT max_offset = part_width * const_nunits;
7203 0 : if (off < max_offset && off % part_width == 0)
7204 : {
7205 0 : tree index = bitsize_int (off * BITS_PER_UNIT);
7206 0 : return build3_loc (loc, BIT_FIELD_REF, type, op,
7207 0 : TYPE_SIZE (type), index);
7208 : }
7209 : }
7210 : /* ((foo *)&fooarray)[x] => fooarray[x] */
7211 12572082 : else if (TREE_CODE (optype) == ARRAY_TYPE
7212 6598574 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
7213 19170656 : && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
7214 : {
7215 6598574 : tree type_domain = TYPE_DOMAIN (optype);
7216 6598574 : tree min_val = size_zero_node;
7217 6598574 : if (type_domain && TYPE_MIN_VALUE (type_domain))
7218 6598435 : min_val = TYPE_MIN_VALUE (type_domain);
7219 6598574 : unsigned HOST_WIDE_INT el_sz
7220 6598574 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
7221 6598574 : unsigned HOST_WIDE_INT idx = off / el_sz;
7222 6598574 : unsigned HOST_WIDE_INT rem = off % el_sz;
7223 6598574 : if (tree_fits_uhwi_p (min_val))
7224 : {
7225 6598574 : tree index = size_int (idx + tree_to_uhwi (min_val));
7226 6598574 : op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
7227 : NULL_TREE, NULL_TREE);
7228 6598574 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
7229 6598574 : empty_base, jump_target);
7230 : }
7231 : }
7232 : /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
7233 5973508 : else if (TREE_CODE (optype) == RECORD_TYPE
7234 5973508 : || TREE_CODE (optype) == UNION_TYPE)
7235 : {
7236 5970072 : if (TREE_CODE (optype) == UNION_TYPE)
7237 : /* For unions prefer the currently active member. */
7238 109 : if (tree field = cxx_union_active_member (ctx, op, jump_target))
7239 : {
7240 16 : unsigned HOST_WIDE_INT el_sz
7241 16 : = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7242 16 : if (off < el_sz)
7243 : {
7244 16 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7245 : op, field, NULL_TREE);
7246 16 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7247 : off, empty_base,
7248 : jump_target))
7249 : return ret;
7250 : }
7251 : }
7252 :
7253 : /* Handle conversion to "as base" type. */
7254 5970062 : if (CLASS_TYPE_P (optype)
7255 11939960 : && CLASSTYPE_AS_BASE (optype) == type)
7256 : return op;
7257 :
7258 : /* Handle conversion to an empty base class, which is represented with a
7259 : NOP_EXPR. Do this before spelunking into the non-empty subobjects,
7260 : which is likely to be a waste of time (109678). */
7261 5967202 : if (is_empty_class (type)
7262 5735841 : && CLASS_TYPE_P (optype)
7263 11703037 : && lookup_base (optype, type, ba_any, NULL, tf_none, off))
7264 : {
7265 2860210 : if (empty_base)
7266 2860210 : *empty_base = true;
7267 2860210 : return op;
7268 : }
7269 :
7270 3106992 : for (tree field = TYPE_FIELDS (optype);
7271 33879498 : field; field = DECL_CHAIN (field))
7272 33863963 : if (TREE_CODE (field) == FIELD_DECL
7273 3112780 : && TREE_TYPE (field) != error_mark_node
7274 36976743 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (field))))
7275 : {
7276 3112780 : tree pos = byte_position (field);
7277 3112780 : if (!tree_fits_uhwi_p (pos))
7278 0 : continue;
7279 3112780 : unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos);
7280 3112780 : unsigned HOST_WIDE_INT el_sz;
7281 3112780 : if (DECL_FIELD_IS_BASE (field)
7282 387631 : && CLASS_TYPE_P (optype)
7283 3500411 : && CLASSTYPE_VBASECLASSES (optype))
7284 6188 : el_sz = tree_to_uhwi (DECL_SIZE_UNIT (field));
7285 : else
7286 3106592 : el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
7287 3112780 : if (upos <= off && off < upos + el_sz)
7288 : {
7289 3106872 : tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
7290 : op, field, NULL_TREE);
7291 3106872 : if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
7292 : off - upos,
7293 : empty_base,
7294 : jump_target))
7295 : return ret;
7296 : }
7297 : }
7298 : }
7299 :
7300 : return NULL_TREE;
7301 : }
7302 :
7303 : /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
7304 : match. We want to be less strict for simple *& folding; if we have a
7305 : non-const temporary that we access through a const pointer, that should
7306 : work. We handle this here rather than change fold_indirect_ref_1
7307 : because we're dealing with things like ADDR_EXPR of INTEGER_CST which
7308 : don't really make sense outside of constant expression evaluation. Also
7309 : we want to allow folding to COMPONENT_REF, which could cause trouble
7310 : with TBAA in fold_indirect_ref_1. */
7311 :
7312 : static tree
7313 185399313 : cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
7314 : tree op0, bool *empty_base, tree *jump_target)
7315 : {
7316 185399313 : tree sub = op0;
7317 185399313 : tree subtype;
7318 :
7319 : /* STRIP_NOPS, but stop if REINTERPRET_CAST_P. */
7320 383948019 : while (CONVERT_EXPR_P (sub) || TREE_CODE (sub) == NON_LVALUE_EXPR
7321 519022720 : || TREE_CODE (sub) == VIEW_CONVERT_EXPR)
7322 : {
7323 146198866 : if (TREE_CODE (sub) == NOP_EXPR
7324 146198866 : && REINTERPRET_CAST_P (sub))
7325 : return NULL_TREE;
7326 146198866 : sub = TREE_OPERAND (sub, 0);
7327 : }
7328 :
7329 185399313 : subtype = TREE_TYPE (sub);
7330 185399313 : if (!INDIRECT_TYPE_P (subtype))
7331 : return NULL_TREE;
7332 :
7333 : /* Canonicalizes the given OBJ/OFF pair by iteratively absorbing
7334 : the innermost component into the offset until it would make the
7335 : offset positive, so that cxx_fold_indirect_ref_1 can identify
7336 : more folding opportunities. */
7337 194867189 : auto canonicalize_obj_off = [] (tree& obj, tree& off) {
7338 9467928 : if (cxx_dialect >= cxx26)
7339 : {
7340 : /* For C++26, we need to fold *(B *)(&x.D.1234 + 32) used
7341 : to access virtual base members. */
7342 2644525 : tree nobj = obj;
7343 2644525 : while (TREE_CODE (nobj) == COMPONENT_REF
7344 2663224 : && DECL_FIELD_IS_BASE (TREE_OPERAND (nobj, 1)))
7345 18699 : nobj = TREE_OPERAND (nobj, 0);
7346 2644525 : if (nobj != obj
7347 14621 : && CLASS_TYPE_P (TREE_TYPE (nobj))
7348 2659146 : && CLASSTYPE_VBASECLASSES (TREE_TYPE (nobj)))
7349 2041 : while (obj != nobj)
7350 : {
7351 1175 : tree field = TREE_OPERAND (obj, 1);
7352 1175 : tree pos = byte_position (field);
7353 1175 : off = int_const_binop (PLUS_EXPR, off, pos);
7354 1175 : obj = TREE_OPERAND (obj, 0);
7355 : }
7356 : }
7357 12583158 : while (TREE_CODE (obj) == COMPONENT_REF
7358 : /* We need to preserve union member accesses so that we can
7359 : later properly diagnose accessing the wrong member. */
7360 6106955 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (obj, 0))) == RECORD_TYPE
7361 18400638 : && (tree_int_cst_sign_bit (off) || integer_zerop (off)))
7362 : {
7363 3190006 : tree field = TREE_OPERAND (obj, 1);
7364 3190006 : tree pos = byte_position (field);
7365 3190006 : if (integer_zerop (off) && integer_nonzerop (pos))
7366 : /* If the offset is already 0, keep going as long as the
7367 : component is at position 0. */
7368 : break;
7369 3115230 : off = int_const_binop (PLUS_EXPR, off, pos);
7370 3115230 : obj = TREE_OPERAND (obj, 0);
7371 : }
7372 9467928 : };
7373 :
7374 185399261 : if (TREE_CODE (sub) == ADDR_EXPR)
7375 : {
7376 82696119 : tree op = TREE_OPERAND (sub, 0);
7377 82696119 : tree optype = TREE_TYPE (op);
7378 :
7379 : /* *&CONST_DECL -> to the value of the const decl. */
7380 82696119 : if (TREE_CODE (op) == CONST_DECL)
7381 0 : return DECL_INITIAL (op);
7382 : /* *&p => p; make sure to handle *&"str"[cst] here. */
7383 82696119 : if (similar_type_p (optype, type))
7384 : {
7385 78675460 : tree fop = fold_read_from_constant_string (op);
7386 78675460 : if (fop)
7387 : return fop;
7388 : else
7389 78579185 : return op;
7390 : }
7391 : else
7392 : {
7393 4020659 : tree off = integer_zero_node;
7394 4020659 : canonicalize_obj_off (op, off);
7395 4020659 : return cxx_fold_indirect_ref_1 (ctx, loc, type, op,
7396 : tree_to_uhwi (off), empty_base,
7397 : jump_target);
7398 : }
7399 : }
7400 102703142 : else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
7401 102703142 : && tree_fits_uhwi_p (TREE_OPERAND (sub, 1)))
7402 : {
7403 6029449 : tree op00 = TREE_OPERAND (sub, 0);
7404 6029449 : tree off = TREE_OPERAND (sub, 1);
7405 :
7406 6029449 : STRIP_NOPS (op00);
7407 6029449 : if (TREE_CODE (op00) == ADDR_EXPR)
7408 : {
7409 5447269 : tree obj = TREE_OPERAND (op00, 0);
7410 5447269 : canonicalize_obj_off (obj, off);
7411 5447269 : return cxx_fold_indirect_ref_1 (ctx, loc, type, obj,
7412 : tree_to_uhwi (off), empty_base,
7413 : jump_target);
7414 : }
7415 : }
7416 : /* *(foo *)fooarrptr => (*fooarrptr)[0] */
7417 96673693 : else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
7418 96673693 : && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
7419 : {
7420 0 : tree type_domain;
7421 0 : tree min_val = size_zero_node;
7422 0 : tree newsub
7423 0 : = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL,
7424 : jump_target);
7425 0 : if (*jump_target)
7426 : return NULL_TREE;
7427 0 : if (newsub)
7428 : sub = newsub;
7429 : else
7430 0 : sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
7431 0 : type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
7432 0 : if (type_domain && TYPE_MIN_VALUE (type_domain))
7433 0 : min_val = TYPE_MIN_VALUE (type_domain);
7434 0 : return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
7435 0 : NULL_TREE);
7436 : }
7437 :
7438 : return NULL_TREE;
7439 : }
7440 :
7441 : static tree
7442 101406005 : cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
7443 : value_cat lval,
7444 : bool *non_constant_p, bool *overflow_p,
7445 : tree *jump_target)
7446 : {
7447 101406005 : tree orig_op0 = TREE_OPERAND (t, 0);
7448 101406005 : bool empty_base = false;
7449 :
7450 : /* We can handle a MEM_REF like an INDIRECT_REF, if MEM_REF's second
7451 : operand is an integer-zero. Otherwise reject the MEM_REF for now. */
7452 :
7453 101406005 : if (TREE_CODE (t) == MEM_REF
7454 101406005 : && (!TREE_OPERAND (t, 1) || !integer_zerop (TREE_OPERAND (t, 1))))
7455 : {
7456 9 : gcc_assert (ctx->quiet);
7457 9 : *non_constant_p = true;
7458 9 : return t;
7459 : }
7460 :
7461 : /* First try to simplify it directly. */
7462 101405996 : tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
7463 : orig_op0, &empty_base, jump_target);
7464 101405996 : if (*jump_target)
7465 : return NULL_TREE;
7466 101405996 : if (!r)
7467 : {
7468 : /* If that didn't work, evaluate the operand first. */
7469 96562211 : tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
7470 : vc_prvalue, non_constant_p,
7471 : overflow_p, jump_target);
7472 96562211 : if (*jump_target)
7473 : return NULL_TREE;
7474 : /* Don't VERIFY_CONSTANT here. */
7475 96562200 : if (*non_constant_p)
7476 : return t;
7477 :
7478 69122609 : if (!lval && integer_zerop (op0))
7479 : {
7480 70 : if (!ctx->quiet)
7481 12 : error ("dereferencing a null pointer");
7482 70 : *non_constant_p = true;
7483 70 : return t;
7484 : }
7485 :
7486 69122539 : r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0,
7487 : &empty_base, jump_target);
7488 69122539 : if (*jump_target)
7489 : return NULL_TREE;
7490 69122539 : if (r == NULL_TREE)
7491 : {
7492 : /* We couldn't fold to a constant value. Make sure it's not
7493 : something we should have been able to fold. */
7494 697215 : tree sub = op0;
7495 697215 : STRIP_NOPS (sub);
7496 697215 : if (TREE_CODE (sub) == ADDR_EXPR)
7497 : {
7498 1694 : gcc_assert (!similar_type_p
7499 : (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
7500 : /* DR 1188 says we don't have to deal with this. */
7501 1694 : if (!ctx->quiet)
7502 : {
7503 8 : auto_diagnostic_group d;
7504 13 : error_at (cp_expr_loc_or_input_loc (t),
7505 : "accessing value of %qT object through a %qT "
7506 : "glvalue in a constant expression",
7507 8 : TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t));
7508 8 : tree ob = build_fold_indirect_ref (sub);
7509 8 : if (DECL_P (ob))
7510 : {
7511 8 : if (DECL_ARTIFICIAL (ob))
7512 1 : inform (DECL_SOURCE_LOCATION (ob),
7513 1 : "%qT object created here", TREE_TYPE (ob));
7514 : else
7515 7 : inform (DECL_SOURCE_LOCATION (ob),
7516 : "%q#D declared here", ob);
7517 : }
7518 8 : }
7519 1694 : *non_constant_p = true;
7520 1694 : return t;
7521 : }
7522 :
7523 695521 : if (lval == vc_glvalue && op0 != orig_op0)
7524 71944 : return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
7525 623577 : if (!lval)
7526 519852 : VERIFY_CONSTANT (t);
7527 623577 : return t;
7528 : }
7529 : }
7530 :
7531 73269109 : r = cxx_eval_constant_expression (ctx, r,
7532 : lval, non_constant_p, overflow_p,
7533 : jump_target);
7534 73269108 : if (*jump_target)
7535 : return NULL_TREE;
7536 73269108 : if (*non_constant_p)
7537 : return t;
7538 :
7539 : /* If we're pulling out the value of an empty base, just return an empty
7540 : CONSTRUCTOR. */
7541 54108890 : if (empty_base && !lval)
7542 : {
7543 16112 : r = build_constructor (TREE_TYPE (t), NULL);
7544 16112 : TREE_CONSTANT (r) = true;
7545 : }
7546 :
7547 : return r;
7548 : }
7549 :
7550 : /* Complain about R, a DECL that is accessed outside its lifetime. */
7551 :
7552 : static void
7553 36 : outside_lifetime_error (location_t loc, tree r)
7554 : {
7555 36 : auto_diagnostic_group d;
7556 36 : if (DECL_NAME (r) == heap_deleted_identifier)
7557 : {
7558 : /* Provide a more accurate message for deleted variables. */
7559 6 : error_at (loc, "use of allocated storage after deallocation "
7560 : "in a constant expression");
7561 6 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
7562 : }
7563 : else
7564 : {
7565 30 : error_at (loc, "accessing %qE outside its lifetime", r);
7566 30 : inform (DECL_SOURCE_LOCATION (r), "declared here");
7567 : }
7568 36 : }
7569 :
7570 : /* Complain about R, a VAR_DECL, not being usable in a constant expression.
7571 : FUNDEF_P is true if we're checking a constexpr function body.
7572 : Shared between potential_constant_expression and
7573 : cxx_eval_constant_expression. */
7574 :
7575 : static void
7576 334 : non_const_var_error (location_t loc, tree r, bool fundef_p)
7577 : {
7578 334 : auto_diagnostic_group d;
7579 334 : tree type = TREE_TYPE (r);
7580 334 : if (DECL_NAME (r) == heap_uninit_identifier
7581 334 : || DECL_NAME (r) == heap_identifier
7582 331 : || DECL_NAME (r) == heap_vec_uninit_identifier
7583 665 : || DECL_NAME (r) == heap_vec_identifier)
7584 : {
7585 3 : if (constexpr_error (loc, fundef_p, "the content of uninitialized "
7586 : "storage is not usable in a constant expression"))
7587 3 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
7588 3 : return;
7589 : }
7590 331 : if (DECL_NAME (r) == heap_deleted_identifier)
7591 : {
7592 0 : if (constexpr_error (loc, fundef_p, "use of allocated storage after "
7593 : "deallocation in a constant expression"))
7594 0 : inform (DECL_SOURCE_LOCATION (r), "allocated here");
7595 0 : return;
7596 : }
7597 331 : if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
7598 : "a constant expression", r))
7599 : return;
7600 : /* Avoid error cascade. */
7601 328 : if (DECL_INITIAL (r) == error_mark_node)
7602 : return;
7603 314 : if (DECL_DECLARED_CONSTEXPR_P (r))
7604 3 : inform (DECL_SOURCE_LOCATION (r),
7605 : "%qD used in its own initializer", r);
7606 311 : else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
7607 : {
7608 219 : if (!CP_TYPE_CONST_P (type))
7609 190 : inform (DECL_SOURCE_LOCATION (r),
7610 : "%q#D is not const", r);
7611 29 : else if (CP_TYPE_VOLATILE_P (type))
7612 0 : inform (DECL_SOURCE_LOCATION (r),
7613 : "%q#D is volatile", r);
7614 29 : else if (!DECL_INITIAL (r)
7615 9 : || !TREE_CONSTANT (DECL_INITIAL (r))
7616 37 : || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
7617 29 : inform (DECL_SOURCE_LOCATION (r),
7618 : "%qD was not initialized with a constant "
7619 : "expression", r);
7620 : else
7621 0 : gcc_unreachable ();
7622 : }
7623 92 : else if (TYPE_REF_P (type))
7624 9 : inform (DECL_SOURCE_LOCATION (r),
7625 : "%qD was not initialized with a constant "
7626 : "expression", r);
7627 : else
7628 : {
7629 83 : if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
7630 83 : inform (DECL_SOURCE_LOCATION (r),
7631 : "%qD was not declared %<constexpr%>", r);
7632 : else
7633 0 : inform (DECL_SOURCE_LOCATION (r),
7634 : "%qD does not have integral or enumeration type",
7635 : r);
7636 : }
7637 334 : }
7638 :
7639 : /* Subroutine of cxx_eval_constant_expression.
7640 : Like cxx_eval_unary_expression, except for trinary expressions. */
7641 :
7642 : static tree
7643 15128 : cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
7644 : value_cat lval,
7645 : bool *non_constant_p, bool *overflow_p,
7646 : tree *jump_target)
7647 : {
7648 15128 : int i;
7649 15128 : tree args[3];
7650 15128 : tree val;
7651 :
7652 58319 : for (i = 0; i < 3; i++)
7653 : {
7654 43922 : args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
7655 : lval,
7656 : non_constant_p, overflow_p,
7657 : jump_target);
7658 43922 : if (*jump_target)
7659 : return NULL_TREE;
7660 43922 : VERIFY_CONSTANT (args[i]);
7661 : }
7662 :
7663 14397 : val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
7664 : args[0], args[1], args[2]);
7665 14397 : if (val == NULL_TREE)
7666 : return t;
7667 14397 : VERIFY_CONSTANT (val);
7668 : return val;
7669 : }
7670 :
7671 : /* True if T was declared in a function declared to be constexpr, and
7672 : therefore potentially constant in C++14. */
7673 :
7674 : bool
7675 90983552 : var_in_constexpr_fn (tree t)
7676 : {
7677 90983552 : tree ctx = DECL_CONTEXT (t);
7678 90983552 : return (ctx && TREE_CODE (ctx) == FUNCTION_DECL
7679 173733826 : && DECL_DECLARED_CONSTEXPR_P (ctx));
7680 : }
7681 :
7682 : /* True if a function might be constexpr: either a function that was
7683 : declared constexpr, or a C++17 lambda op(). */
7684 :
7685 : bool
7686 742291354 : maybe_constexpr_fn (tree t)
7687 : {
7688 742291354 : return (DECL_DECLARED_CONSTEXPR_P (t)
7689 210983390 : || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t))
7690 943890081 : || (flag_implicit_constexpr
7691 92 : && DECL_DECLARED_INLINE_P (STRIP_TEMPLATE (t))));
7692 : }
7693 :
7694 : /* True if T was declared in a function that might be constexpr: either a
7695 : function that was declared constexpr, or a C++17 lambda op(). */
7696 :
7697 : bool
7698 73096157 : var_in_maybe_constexpr_fn (tree t)
7699 : {
7700 146191716 : return (DECL_FUNCTION_SCOPE_P (t)
7701 134582072 : && maybe_constexpr_fn (DECL_CONTEXT (t)));
7702 : }
7703 :
7704 : /* We're assigning INIT to TARGET. In do_build_copy_constructor and
7705 : build_over_call we implement trivial copy of a class with tail padding using
7706 : assignment of character arrays, which is valid in normal code, but not in
7707 : constexpr evaluation. We don't need to worry about clobbering tail padding
7708 : in constexpr evaluation, so strip the type punning. */
7709 :
7710 : static void
7711 83452842 : maybe_simplify_trivial_copy (tree &target, tree &init)
7712 : {
7713 83452842 : if (TREE_CODE (target) == MEM_REF
7714 3660 : && TREE_CODE (init) == MEM_REF
7715 3560 : && TREE_TYPE (target) == TREE_TYPE (init)
7716 3560 : && TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
7717 83456402 : && TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
7718 : {
7719 3560 : target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
7720 3560 : init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
7721 : }
7722 83452842 : }
7723 :
7724 : /* Returns true if REF, which is a COMPONENT_REF, has any fields
7725 : of constant type. This does not check for 'mutable', so the
7726 : caller is expected to be mindful of that. */
7727 :
7728 : static bool
7729 447 : cref_has_const_field (tree ref)
7730 : {
7731 516 : while (TREE_CODE (ref) == COMPONENT_REF)
7732 : {
7733 507 : if (CP_TYPE_CONST_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
7734 : return true;
7735 69 : ref = TREE_OPERAND (ref, 0);
7736 : }
7737 : return false;
7738 : }
7739 :
7740 : /* Return true if we are modifying something that is const during constant
7741 : expression evaluation. CODE is the code of the statement, OBJ is the
7742 : object in question, MUTABLE_P is true if one of the subobjects were
7743 : declared mutable. */
7744 :
7745 : static bool
7746 73713230 : modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
7747 : {
7748 : /* If this is initialization, there's no problem. */
7749 73713230 : if (code != MODIFY_EXPR)
7750 : return false;
7751 :
7752 : /* [basic.type.qualifier] "A const object is an object of type
7753 : const T or a non-mutable subobject of a const object." */
7754 20297362 : if (mutable_p)
7755 : return false;
7756 :
7757 20296626 : if (TREE_READONLY (obj))
7758 : return true;
7759 :
7760 20292755 : if (CP_TYPE_CONST_P (TREE_TYPE (obj)))
7761 : {
7762 : /* Although a COMPONENT_REF may have a const type, we should
7763 : only consider it modifying a const object when any of the
7764 : field components is const. This can happen when using
7765 : constructs such as const_cast<const T &>(m), making something
7766 : const even though it wasn't declared const. */
7767 30560 : if (TREE_CODE (obj) == COMPONENT_REF)
7768 447 : return cref_has_const_field (obj);
7769 : else
7770 : return true;
7771 : }
7772 :
7773 : return false;
7774 : }
7775 :
7776 : /* Evaluate an INIT_EXPR or MODIFY_EXPR. */
7777 :
7778 : static tree
7779 83452842 : cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
7780 : value_cat lval,
7781 : bool *non_constant_p, bool *overflow_p,
7782 : tree *jump_target)
7783 : {
7784 83452842 : constexpr_ctx new_ctx = *ctx;
7785 :
7786 83452842 : tree init = TREE_OPERAND (t, 1);
7787 :
7788 : /* First we figure out where we're storing to. */
7789 83452842 : tree target = TREE_OPERAND (t, 0);
7790 :
7791 83452842 : maybe_simplify_trivial_copy (target, init);
7792 :
7793 83452842 : tree type = TREE_TYPE (target);
7794 83452842 : bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) == MODIFY_EXPR;
7795 64905212 : if (preeval && !TREE_CLOBBER_P (init))
7796 : {
7797 : /* Ignore var = .DEFERRED_INIT (); for now, until PR121965 is fixed. */
7798 64390479 : if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
7799 17692617 : && TREE_CODE (init) == CALL_EXPR
7800 2596618 : && CALL_EXPR_FN (init) == NULL_TREE
7801 64390483 : && CALL_EXPR_IFN (init) == IFN_DEFERRED_INIT)
7802 4 : return void_node;
7803 :
7804 : /* Evaluate the value to be stored without knowing what object it will be
7805 : stored in, so that any side-effects happen first. */
7806 64390475 : if (!SCALAR_TYPE_P (type))
7807 73848 : new_ctx.ctor = new_ctx.object = NULL_TREE;
7808 64390475 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
7809 : non_constant_p, overflow_p,
7810 : jump_target);
7811 64390473 : if (*jump_target)
7812 : return NULL_TREE;
7813 64390375 : if (*non_constant_p)
7814 : return t;
7815 : }
7816 :
7817 64098472 : bool evaluated = false;
7818 64098472 : if (lval == vc_glvalue)
7819 : {
7820 : /* If we want to return a reference to the target, we need to evaluate it
7821 : as a whole; otherwise, only evaluate the innermost piece to avoid
7822 : building up unnecessary *_REFs. */
7823 0 : target = cxx_eval_constant_expression (ctx, target, lval,
7824 : non_constant_p, overflow_p,
7825 : jump_target);
7826 0 : evaluated = true;
7827 0 : if (*jump_target)
7828 : return NULL_TREE;
7829 0 : if (*non_constant_p)
7830 : return t;
7831 : }
7832 :
7833 : /* Find the underlying variable. */
7834 64098472 : releasing_vec refs;
7835 64098472 : tree object = NULL_TREE;
7836 : /* If we're modifying a const object, save it. */
7837 64098472 : tree const_object_being_modified = NULL_TREE;
7838 64098472 : bool mutable_p = false;
7839 : /* If we see a union, we can't ignore clobbers. */
7840 64098472 : int seen_union = 0;
7841 221005361 : for (tree probe = target; object == NULL_TREE; )
7842 : {
7843 156907261 : switch (TREE_CODE (probe))
7844 : {
7845 28710634 : case BIT_FIELD_REF:
7846 28710634 : case COMPONENT_REF:
7847 28710634 : case ARRAY_REF:
7848 28710634 : {
7849 28710634 : tree ob = TREE_OPERAND (probe, 0);
7850 28710634 : tree elt = TREE_OPERAND (probe, 1);
7851 28710634 : if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt))
7852 : mutable_p = true;
7853 28710634 : if (TREE_CODE (probe) == ARRAY_REF)
7854 : {
7855 4487627 : elt = eval_and_check_array_index (ctx, probe, false,
7856 : non_constant_p, overflow_p,
7857 : jump_target);
7858 4487627 : if (*jump_target)
7859 66 : return NULL_TREE;
7860 4487627 : if (*non_constant_p)
7861 : return t;
7862 : }
7863 : /* We don't check modifying_const_object_p for ARRAY_REFs. Given
7864 : "int a[10]", an ARRAY_REF "a[2]" can be "const int", even though
7865 : the array isn't const. Instead, check "a" in the next iteration;
7866 : that will detect modifying "const int a[10]". */
7867 24223007 : else if (evaluated
7868 9615130 : && modifying_const_object_p (TREE_CODE (t), probe,
7869 : mutable_p)
7870 24223547 : && const_object_being_modified == NULL_TREE)
7871 : const_object_being_modified = probe;
7872 :
7873 : /* Track named member accesses for unions to validate modifications
7874 : that change active member. */
7875 28710568 : if (!evaluated && TREE_CODE (probe) == COMPONENT_REF)
7876 14607877 : vec_safe_push (refs, probe);
7877 : else
7878 14102691 : vec_safe_push (refs, NULL_TREE);
7879 :
7880 28710568 : vec_safe_push (refs, elt);
7881 28710568 : vec_safe_push (refs, TREE_TYPE (probe));
7882 28710568 : probe = ob;
7883 28710568 : if (TREE_CODE (TREE_TYPE (ob)) == UNION_TYPE)
7884 452022 : ++seen_union;
7885 : }
7886 28710568 : break;
7887 :
7888 16 : case REALPART_EXPR:
7889 16 : gcc_assert (refs->is_empty ());
7890 16 : vec_safe_push (refs, NULL_TREE);
7891 16 : vec_safe_push (refs, probe);
7892 16 : vec_safe_push (refs, TREE_TYPE (probe));
7893 16 : probe = TREE_OPERAND (probe, 0);
7894 16 : break;
7895 :
7896 17 : case IMAGPART_EXPR:
7897 17 : gcc_assert (refs->is_empty ());
7898 17 : vec_safe_push (refs, NULL_TREE);
7899 17 : vec_safe_push (refs, probe);
7900 17 : vec_safe_push (refs, TREE_TYPE (probe));
7901 17 : probe = TREE_OPERAND (probe, 0);
7902 17 : break;
7903 :
7904 128196594 : default:
7905 128196594 : if (evaluated)
7906 : object = probe;
7907 : else
7908 : {
7909 64098494 : tree pvar = tree_strip_any_location_wrapper (probe);
7910 64098494 : if (VAR_P (pvar) && DECL_ANON_UNION_VAR_P (pvar))
7911 : {
7912 : /* Stores to DECL_ANON_UNION_VAR_P var are allowed to change
7913 : active union member. */
7914 55 : probe = DECL_VALUE_EXPR (pvar);
7915 55 : break;
7916 : }
7917 64098439 : probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue,
7918 : non_constant_p, overflow_p,
7919 : jump_target);
7920 64098439 : evaluated = true;
7921 64098439 : if (*jump_target)
7922 : return NULL_TREE;
7923 64098439 : if (*non_constant_p)
7924 : return t;
7925 : }
7926 : break;
7927 : }
7928 : }
7929 :
7930 64098100 : if (modifying_const_object_p (TREE_CODE (t), object, mutable_p)
7931 64098100 : && const_object_being_modified == NULL_TREE)
7932 64098100 : const_object_being_modified = object;
7933 :
7934 64098100 : if (DECL_P (object)
7935 64097213 : && TREE_CLOBBER_P (init)
7936 64620428 : && DECL_NAME (object) == heap_deleted_identifier)
7937 : /* Ignore clobbers of deleted allocations for now; we'll get a better error
7938 : message later when operator delete is called. */
7939 15 : return void_node;
7940 :
7941 : /* And then find/build up our initializer for the path to the subobject
7942 : we're initializing. */
7943 64098085 : tree *valp;
7944 64098085 : if (DECL_P (object))
7945 64097198 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
7946 : else
7947 887 : valp = NULL;
7948 64098085 : if (!valp)
7949 : {
7950 : /* A constant-expression cannot modify objects from outside the
7951 : constant-expression. */
7952 6308 : if (!ctx->quiet)
7953 : {
7954 29 : auto_diagnostic_group d;
7955 29 : if (DECL_P (object) && DECL_NAME (object) == heap_deleted_identifier)
7956 : {
7957 0 : error ("modification of allocated storage after deallocation "
7958 : "is not a constant expression");
7959 0 : inform (DECL_SOURCE_LOCATION (object), "allocated here");
7960 : }
7961 29 : else if (DECL_P (object) && ctx->global->is_outside_lifetime (object))
7962 : {
7963 14 : if (TREE_CLOBBER_P (init))
7964 6 : error ("destroying %qE outside its lifetime", object);
7965 : else
7966 8 : error ("modification of %qE outside its lifetime "
7967 : "is not a constant expression", object);
7968 14 : inform (DECL_SOURCE_LOCATION (object), "declared here");
7969 : }
7970 : else
7971 : {
7972 15 : if (TREE_CLOBBER_P (init))
7973 6 : error ("destroying %qE from outside current evaluation "
7974 : "is not a constant expression", object);
7975 : else
7976 9 : error ("modification of %qE from outside current evaluation "
7977 : "is not a constant expression", object);
7978 : }
7979 29 : }
7980 6308 : *non_constant_p = true;
7981 6308 : return t;
7982 : }
7983 :
7984 : /* Handle explicit end-of-lifetime. */
7985 64091777 : if (TREE_CLOBBER_P (init))
7986 : {
7987 522263 : if (CLOBBER_KIND (init) >= CLOBBER_OBJECT_END
7988 522263 : && refs->is_empty ())
7989 : {
7990 125995 : ctx->global->destroy_value (object);
7991 125995 : return void_node;
7992 : }
7993 :
7994 391628 : if (!seen_union && !*valp
7995 399543 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
7996 3241 : return void_node;
7997 :
7998 : /* Ending the lifetime of a const object is OK. */
7999 : const_object_being_modified = NULL_TREE;
8000 : }
8001 :
8002 63962541 : type = TREE_TYPE (object);
8003 63962541 : bool no_zero_init = true;
8004 63962541 : bool zero_padding_bits = false;
8005 :
8006 127925082 : auto_vec<tree *> ctors;
8007 127925082 : releasing_vec indexes;
8008 127925082 : auto_vec<int> index_pos_hints;
8009 63962541 : bool activated_union_member_p = false;
8010 63962541 : bool empty_base = false;
8011 92426966 : while (!refs->is_empty ())
8012 : {
8013 28696485 : if (*valp == NULL_TREE)
8014 : {
8015 3373387 : *valp = build_constructor (type, NULL);
8016 3373387 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8017 3373387 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8018 : }
8019 25323098 : else if (STRIP_ANY_LOCATION_WRAPPER (*valp),
8020 25323098 : TREE_CODE (*valp) == STRING_CST)
8021 : {
8022 : /* An array was initialized with a string constant, and now
8023 : we're writing into one of its elements. Explode the
8024 : single initialization into a set of element
8025 : initializations. */
8026 10878 : gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
8027 :
8028 10878 : tree string = *valp;
8029 10878 : tree elt_type = TREE_TYPE (type);
8030 10878 : unsigned chars_per_elt = (TYPE_PRECISION (elt_type)
8031 10878 : / TYPE_PRECISION (char_type_node));
8032 10878 : unsigned num_elts = TREE_STRING_LENGTH (string) / chars_per_elt;
8033 10878 : tree ary_ctor = build_constructor (type, NULL);
8034 :
8035 10878 : vec_safe_reserve (CONSTRUCTOR_ELTS (ary_ctor), num_elts);
8036 21910 : for (unsigned ix = 0; ix != num_elts; ix++)
8037 : {
8038 11032 : constructor_elt elt =
8039 : {
8040 11032 : build_int_cst (size_type_node, ix),
8041 11032 : extract_string_elt (string, chars_per_elt, ix)
8042 11032 : };
8043 11032 : CONSTRUCTOR_ELTS (ary_ctor)->quick_push (elt);
8044 : }
8045 :
8046 10878 : *valp = ary_ctor;
8047 : }
8048 :
8049 28696485 : enum tree_code code = TREE_CODE (type);
8050 28696485 : tree reftype = refs->pop();
8051 28696485 : tree index = refs->pop();
8052 28696485 : bool is_access_expr = refs->pop() != NULL_TREE;
8053 :
8054 28696485 : if (code == COMPLEX_TYPE)
8055 : {
8056 33 : if (TREE_CODE (*valp) == COMPLEX_CST)
8057 29 : *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp),
8058 29 : TREE_IMAGPART (*valp));
8059 4 : else if (TREE_CODE (*valp) == CONSTRUCTOR
8060 2 : && CONSTRUCTOR_NELTS (*valp) == 0
8061 6 : && CONSTRUCTOR_NO_CLEARING (*valp))
8062 : {
8063 2 : tree r = build_constructor (reftype, NULL);
8064 2 : CONSTRUCTOR_NO_CLEARING (r) = 1;
8065 2 : *valp = build2 (COMPLEX_EXPR, type, r, r);
8066 : }
8067 33 : gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR);
8068 33 : ctors.safe_push (valp);
8069 33 : vec_safe_push (indexes, index);
8070 33 : valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR);
8071 33 : gcc_checking_assert (refs->is_empty ());
8072 : type = reftype;
8073 231140 : break;
8074 : }
8075 :
8076 : /* If the value of object is already zero-initialized, any new ctors for
8077 : subobjects will also be zero-initialized. Similarly with zeroing of
8078 : padding bits. */
8079 28696452 : no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
8080 28696452 : zero_padding_bits = CONSTRUCTOR_ZERO_PADDING_BITS (*valp);
8081 :
8082 28696452 : if (code == RECORD_TYPE && is_empty_field (index))
8083 : /* Don't build a sub-CONSTRUCTOR for an empty base or field, as they
8084 : have no data and might have an offset lower than previously declared
8085 : fields, which confuses the middle-end. The code below will notice
8086 : that we don't have a CONSTRUCTOR for our inner target and just
8087 : return init. */
8088 : {
8089 : empty_base = true;
8090 : break;
8091 : }
8092 :
8093 : /* If a union is zero-initialized, its first non-static named data member
8094 : is zero-initialized (and therefore active). */
8095 28465345 : if (code == UNION_TYPE
8096 28465345 : && !no_zero_init
8097 28465345 : && CONSTRUCTOR_NELTS (*valp) == 0)
8098 77 : if (tree first = next_aggregate_field (TYPE_FIELDS (type)))
8099 77 : CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (*valp), first, NULL_TREE);
8100 :
8101 : /* Check for implicit change of active member for a union. */
8102 :
8103 : /* LWG3436, CWG2675, c++/121068: The array object model is confused. For
8104 : now allow initializing an array element to activate the array. */
8105 28499830 : auto only_array_refs = [](const releasing_vec &refs)
8106 : {
8107 34489 : for (unsigned i = 1; i < refs->length(); i += 3)
8108 34 : if (TREE_CODE ((*refs)[i]) != INTEGER_CST)
8109 : return false;
8110 : return true;
8111 : };
8112 :
8113 28465345 : if (code == UNION_TYPE
8114 451312 : && (CONSTRUCTOR_NELTS (*valp) == 0
8115 142023 : || CONSTRUCTOR_ELT (*valp, 0)->index != index)
8116 : /* An INIT_EXPR of the last member in an access chain is always OK,
8117 : but still check implicit change of members earlier on; see
8118 : cpp2a/constexpr-union6.C. */
8119 28777200 : && !(TREE_CODE (t) == INIT_EXPR && only_array_refs (refs)))
8120 : {
8121 277400 : bool has_active_member = CONSTRUCTOR_NELTS (*valp) != 0;
8122 277400 : tree inner = strip_array_types (reftype);
8123 :
8124 277400 : if (has_active_member && cxx_dialect < cxx20)
8125 : {
8126 58 : if (!ctx->quiet)
8127 19 : error_at (cp_expr_loc_or_input_loc (t),
8128 : "change of the active member of a union "
8129 : "from %qD to %qD is not a constant expression "
8130 : "before C++20",
8131 19 : CONSTRUCTOR_ELT (*valp, 0)->index,
8132 : index);
8133 58 : *non_constant_p = true;
8134 : }
8135 277342 : else if (!is_access_expr
8136 25521 : || (TREE_CLOBBER_P (init)
8137 0 : && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
8138 302863 : || (TREE_CODE (t) == MODIFY_EXPR
8139 25509 : && CLASS_TYPE_P (inner)
8140 15 : && !type_has_non_deleted_trivial_default_ctor (inner)))
8141 : {
8142 : /* Diagnose changing active union member after initialization
8143 : without a valid member access expression, as described in
8144 : [class.union.general] p5. */
8145 251830 : if (!ctx->quiet)
8146 : {
8147 33 : auto_diagnostic_group d;
8148 33 : if (has_active_member)
8149 24 : error_at (cp_expr_loc_or_input_loc (t),
8150 : "accessing %qD member instead of initialized "
8151 : "%qD member in constant expression",
8152 24 : index, CONSTRUCTOR_ELT (*valp, 0)->index);
8153 : else
8154 9 : error_at (cp_expr_loc_or_input_loc (t),
8155 : "accessing uninitialized member %qD",
8156 : index);
8157 33 : if (is_access_expr)
8158 3 : inform (DECL_SOURCE_LOCATION (index),
8159 : "%qD does not implicitly begin its lifetime "
8160 : "because %qT does not have a non-deleted "
8161 : "trivial default constructor, use "
8162 : "%<std::construct_at%> instead",
8163 : index, inner);
8164 : else
8165 30 : inform (DECL_SOURCE_LOCATION (index),
8166 : "initializing %qD requires a member access "
8167 : "expression as the left operand of the assignment",
8168 : index);
8169 33 : }
8170 251830 : *non_constant_p = true;
8171 : }
8172 25512 : else if (has_active_member && CONSTRUCTOR_NO_CLEARING (*valp))
8173 : {
8174 : /* Diagnose changing the active union member while the union
8175 : is in the process of being initialized. */
8176 18 : if (!ctx->quiet)
8177 6 : error_at (cp_expr_loc_or_input_loc (t),
8178 : "change of the active member of a union "
8179 : "from %qD to %qD during initialization",
8180 6 : CONSTRUCTOR_ELT (*valp, 0)->index,
8181 : index);
8182 18 : *non_constant_p = true;
8183 : }
8184 : no_zero_init = true;
8185 : }
8186 :
8187 28465345 : ctors.safe_push (valp);
8188 28465345 : vec_safe_push (indexes, index);
8189 :
8190 : /* Avoid adding an _elt for a clobber when the whole CONSTRUCTOR is
8191 : uninitialized. */
8192 27224778 : int pos = (!seen_union && TREE_CLOBBER_P (init)
8193 889041 : && CONSTRUCTOR_NO_CLEARING (*valp)
8194 29257836 : && CLOBBER_KIND (init) < CLOBBER_OBJECT_END) ? -2 : -1;
8195 28465345 : constructor_elt *cep
8196 28465345 : = get_or_insert_ctor_field (*valp, index, pos);
8197 28465345 : if (cep == nullptr)
8198 920 : return void_node;
8199 28464425 : index_pos_hints.safe_push (cep - CONSTRUCTOR_ELTS (*valp)->begin());
8200 :
8201 28464425 : if (code == UNION_TYPE)
8202 : {
8203 451312 : activated_union_member_p = true;
8204 451312 : --seen_union;
8205 : }
8206 :
8207 28464425 : valp = &cep->value;
8208 28464425 : type = reftype;
8209 : }
8210 :
8211 : /* Change an "as-base" clobber to the real type;
8212 : we don't need to worry about padding in constexpr. */
8213 63961621 : tree itype = initialized_type (init);
8214 63961621 : if (IS_FAKE_BASE_TYPE (itype))
8215 1967 : itype = TYPE_CONTEXT (itype);
8216 :
8217 : /* For initialization of an empty base, the original target will be
8218 : *(base*)this, evaluation of which resolves to the object
8219 : argument, which has the derived type rather than the base type. */
8220 127692135 : if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p
8221 63730514 : (itype, type)))
8222 : {
8223 12173 : gcc_assert (is_empty_class (TREE_TYPE (target)));
8224 : empty_base = true;
8225 : }
8226 :
8227 : /* Detect modifying a constant object in constexpr evaluation.
8228 : We have found a const object that is being modified. Figure out
8229 : if we need to issue an error. Consider
8230 :
8231 : struct A {
8232 : int n;
8233 : constexpr A() : n(1) { n = 2; } // #1
8234 : };
8235 : struct B {
8236 : const A a;
8237 : constexpr B() { a.n = 3; } // #2
8238 : };
8239 : constexpr B b{};
8240 :
8241 : #1 is OK, since we're modifying an object under construction, but
8242 : #2 is wrong, since "a" is const and has been fully constructed.
8243 : To track it, we use the TREE_READONLY bit in the object's CONSTRUCTOR
8244 : which means that the object is read-only. For the example above, the
8245 : *ctors stack at the point of #2 will look like:
8246 :
8247 : ctors[0] = {.a={.n=2}} TREE_READONLY = 0
8248 : ctors[1] = {.n=2} TREE_READONLY = 1
8249 :
8250 : and we're modifying "b.a", so we search the stack and see if the
8251 : constructor for "b.a" has already run. */
8252 63961621 : if (const_object_being_modified)
8253 : {
8254 33307 : bool fail = false;
8255 33307 : tree const_objtype
8256 33307 : = strip_array_types (TREE_TYPE (const_object_being_modified));
8257 33307 : if (!CLASS_TYPE_P (const_objtype))
8258 : fail = true;
8259 : else
8260 : {
8261 : /* [class.ctor]p5 "A constructor can be invoked for a const,
8262 : volatile, or const volatile object. const and volatile
8263 : semantics are not applied on an object under construction.
8264 : They come into effect when the constructor for the most
8265 : derived object ends." */
8266 100046 : for (tree *elt : ctors)
8267 33642 : if (same_type_ignoring_top_level_qualifiers_p
8268 33642 : (TREE_TYPE (const_object_being_modified), TREE_TYPE (*elt)))
8269 : {
8270 33202 : fail = TREE_READONLY (*elt);
8271 33202 : break;
8272 : }
8273 : }
8274 33202 : if (fail)
8275 : {
8276 198 : if (!ctx->quiet)
8277 63 : modifying_const_object_error (t, const_object_being_modified);
8278 198 : *non_constant_p = true;
8279 198 : return t;
8280 : }
8281 : }
8282 :
8283 63961423 : if (!preeval)
8284 : {
8285 : /* We're handling an INIT_EXPR of class type, so the value of the
8286 : initializer can depend on the object it's initializing. */
8287 :
8288 : /* Create a new CONSTRUCTOR in case evaluation of the initializer
8289 : wants to modify it. */
8290 18539392 : if (*valp == NULL_TREE)
8291 : {
8292 17864259 : *valp = build_constructor (type, NULL);
8293 17864259 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8294 17864259 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8295 : }
8296 18539392 : new_ctx.ctor = empty_base ? NULL_TREE : *valp;
8297 18539392 : new_ctx.object = target;
8298 : /* Avoid temporary materialization when initializing from a TARGET_EXPR.
8299 : We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because
8300 : expansion of those trees uses ctx instead. */
8301 18539392 : if (TREE_CODE (init) == TARGET_EXPR)
8302 3470531 : if (tree tinit = TARGET_EXPR_INITIAL (init))
8303 3470531 : init = tinit;
8304 18539392 : init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
8305 : non_constant_p, overflow_p,
8306 : jump_target);
8307 18539392 : if (*jump_target)
8308 : return NULL_TREE;
8309 : /* The hash table might have moved since the get earlier, and the
8310 : initializer might have mutated the underlying CONSTRUCTORs, so we must
8311 : recompute VALP. */
8312 18539331 : valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
8313 21811706 : for (unsigned i = 0; i < vec_safe_length (indexes); i++)
8314 : {
8315 3272375 : ctors[i] = valp;
8316 3272375 : constructor_elt *cep
8317 3272375 : = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]);
8318 3272375 : valp = &cep->value;
8319 : }
8320 : }
8321 :
8322 63961362 : if (*non_constant_p)
8323 : return t;
8324 :
8325 : /* Don't share a CONSTRUCTOR that might be changed later. */
8326 60149097 : init = unshare_constructor (init);
8327 :
8328 60149097 : gcc_checking_assert (!*valp
8329 : || *valp == void_node
8330 : || (same_type_ignoring_top_level_qualifiers_p
8331 : (TREE_TYPE (*valp), type)));
8332 60149097 : if (empty_base)
8333 : {
8334 : /* Just evaluate the initializer and return, since there's no actual data
8335 : to store, and we didn't build a CONSTRUCTOR. */
8336 235828 : if (!*valp)
8337 : {
8338 : /* But do make sure we have something in *valp. */
8339 0 : *valp = build_constructor (type, nullptr);
8340 0 : CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
8341 0 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8342 : }
8343 : }
8344 59913269 : else if (TREE_CLOBBER_P (init))
8345 : {
8346 392107 : if (AGGREGATE_TYPE_P (type))
8347 : {
8348 262689 : if (*valp && TREE_CODE (*valp) == CONSTRUCTOR)
8349 262666 : CONSTRUCTOR_ELTS (*valp) = nullptr;
8350 : else
8351 23 : *valp = build_constructor (type, nullptr);
8352 262689 : TREE_CONSTANT (*valp) = true;
8353 262689 : TREE_SIDE_EFFECTS (*valp) = false;
8354 262689 : CONSTRUCTOR_NO_CLEARING (*valp) = true;
8355 262689 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
8356 : }
8357 : else
8358 129418 : *valp = void_node;
8359 : }
8360 59521162 : else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
8361 14806358 : && TREE_CODE (init) == CONSTRUCTOR)
8362 : {
8363 : /* An outer ctx->ctor might be pointing to *valp, so replace
8364 : its contents. */
8365 3959544 : CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
8366 3959544 : TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
8367 3959544 : TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
8368 11878632 : CONSTRUCTOR_NO_CLEARING (*valp)
8369 3959544 : = CONSTRUCTOR_NO_CLEARING (init);
8370 11878632 : CONSTRUCTOR_ZERO_PADDING_BITS (*valp)
8371 3959544 : = CONSTRUCTOR_ZERO_PADDING_BITS (init);
8372 : }
8373 : else
8374 55561618 : *valp = init;
8375 :
8376 : /* After initialization, 'const' semantics apply to the value of the
8377 : object. Make a note of this fact by marking the CONSTRUCTOR
8378 : TREE_READONLY. */
8379 60149097 : if (TREE_CODE (t) == INIT_EXPR
8380 45209217 : && !empty_base
8381 44973389 : && TREE_CODE (*valp) == CONSTRUCTOR
8382 64045446 : && TYPE_READONLY (type))
8383 : {
8384 20810 : tree target_type = TREE_TYPE (target);
8385 20810 : if (IS_FAKE_BASE_TYPE (target_type))
8386 0 : target_type = TYPE_CONTEXT (target_type);
8387 20810 : if (INDIRECT_REF_P (target)
8388 35873 : && (is_this_parameter
8389 15063 : (tree_strip_nop_conversions (TREE_OPERAND (target, 0)))))
8390 : /* We've just initialized '*this' (perhaps via the target
8391 : constructor of a delegating constructor). Leave it up to the
8392 : caller that set 'this' to set TREE_READONLY appropriately. */
8393 23 : gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
8394 : (target_type, type) || empty_base);
8395 : else
8396 20787 : TREE_READONLY (*valp) = true;
8397 : }
8398 :
8399 : /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing
8400 : CONSTRUCTORs, if any. */
8401 60149097 : bool c = TREE_CONSTANT (init);
8402 60149097 : bool s = TREE_SIDE_EFFECTS (init);
8403 60149097 : if (!indexes->is_empty ())
8404 : {
8405 16839160 : tree last = indexes->last ();
8406 16839160 : if (TREE_CODE (last) == REALPART_EXPR
8407 16839160 : || TREE_CODE (last) == IMAGPART_EXPR)
8408 : {
8409 : /* And canonicalize COMPLEX_EXPR into COMPLEX_CST if
8410 : possible. */
8411 33 : tree *cexpr = ctors.last ();
8412 33 : if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr),
8413 33 : TREE_OPERAND (*cexpr, 0),
8414 33 : TREE_OPERAND (*cexpr, 1)))
8415 31 : *cexpr = c;
8416 : else
8417 : {
8418 4 : TREE_CONSTANT (*cexpr)
8419 2 : = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0))
8420 2 : & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1)));
8421 4 : TREE_SIDE_EFFECTS (*cexpr)
8422 4 : = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0))
8423 2 : | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1)));
8424 : }
8425 33 : c = TREE_CONSTANT (*cexpr);
8426 33 : s = TREE_SIDE_EFFECTS (*cexpr);
8427 : }
8428 : }
8429 60149097 : if (!c || s || activated_union_member_p)
8430 39443338 : for (tree *elt : ctors)
8431 : {
8432 8333637 : if (TREE_CODE (*elt) != CONSTRUCTOR)
8433 0 : continue;
8434 8333637 : if (!c)
8435 7515332 : TREE_CONSTANT (*elt) = false;
8436 8333637 : if (s)
8437 0 : TREE_SIDE_EFFECTS (*elt) = true;
8438 : /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of
8439 : this union. */
8440 8333637 : if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE)
8441 199186 : CONSTRUCTOR_NO_CLEARING (*elt) = false;
8442 : }
8443 :
8444 60149097 : if (lval)
8445 : return target;
8446 : else
8447 352005 : return init;
8448 64098472 : }
8449 :
8450 : /* Evaluate a ++ or -- expression. */
8451 :
8452 : static tree
8453 5876580 : cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
8454 : value_cat lval,
8455 : bool *non_constant_p, bool *overflow_p,
8456 : tree *jump_target)
8457 : {
8458 5876580 : enum tree_code code = TREE_CODE (t);
8459 5876580 : tree type = TREE_TYPE (t);
8460 5876580 : tree op = TREE_OPERAND (t, 0);
8461 5876580 : tree offset = TREE_OPERAND (t, 1);
8462 5876580 : gcc_assert (TREE_CONSTANT (offset));
8463 :
8464 : /* OFFSET is constant, but perhaps not constant enough. We need to
8465 : e.g. bash FLOAT_EXPRs to REAL_CSTs. */
8466 5876580 : offset = fold_simple (offset);
8467 :
8468 : /* The operand as an lvalue. */
8469 5876580 : op = cxx_eval_constant_expression (ctx, op, vc_glvalue,
8470 : non_constant_p, overflow_p,
8471 : jump_target);
8472 5876580 : if (*jump_target)
8473 : return NULL_TREE;
8474 :
8475 : /* The operand as an rvalue. */
8476 5876580 : tree val
8477 5876580 : = cxx_eval_constant_expression (ctx, op, vc_prvalue,
8478 : non_constant_p, overflow_p,
8479 : jump_target);
8480 5876580 : if (*jump_target)
8481 : return NULL_TREE;
8482 : /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
8483 : a local array in a constexpr function. */
8484 5876580 : bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val));
8485 2725827 : if (!ptr)
8486 2725827 : VERIFY_CONSTANT (val);
8487 :
8488 : /* The modified value. */
8489 5750827 : bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
8490 5750827 : tree mod;
8491 5750827 : if (INDIRECT_TYPE_P (type))
8492 : {
8493 : /* The middle end requires pointers to use POINTER_PLUS_EXPR. */
8494 3150753 : offset = convert_to_ptrofftype (offset);
8495 3150753 : if (!inc)
8496 52348 : offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
8497 3150753 : mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
8498 : }
8499 2600074 : else if (c_promoting_integer_type_p (type)
8500 5085 : && !TYPE_UNSIGNED (type)
8501 2600198 : && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
8502 : {
8503 124 : offset = fold_convert (integer_type_node, offset);
8504 124 : mod = fold_convert (integer_type_node, val);
8505 153 : tree t = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, integer_type_node,
8506 : mod, offset);
8507 124 : mod = fold_convert (type, t);
8508 124 : if (TREE_OVERFLOW_P (mod) && !TREE_OVERFLOW_P (t))
8509 9 : TREE_OVERFLOW (mod) = false;
8510 : }
8511 : else
8512 2906109 : mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
8513 5750827 : if (!ptr)
8514 2600074 : VERIFY_CONSTANT (mod);
8515 :
8516 : /* Storing the modified value. */
8517 8895576 : tree store = build2_loc (cp_expr_loc_or_loc (t, input_location),
8518 : MODIFY_EXPR, type, op, mod);
8519 5750827 : mod = cxx_eval_constant_expression (ctx, store, lval,
8520 : non_constant_p, overflow_p,
8521 : jump_target);
8522 5750827 : ggc_free (store);
8523 5750827 : if (*jump_target)
8524 : return NULL_TREE;
8525 5750827 : if (*non_constant_p)
8526 : return t;
8527 :
8528 : /* And the value of the expression. */
8529 5620793 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
8530 : /* Prefix ops are lvalues, but the caller might want an rvalue;
8531 : lval has already been taken into account in the store above. */
8532 : return mod;
8533 : else
8534 : /* Postfix ops are rvalues. */
8535 351215 : return val;
8536 : }
8537 :
8538 : /* Subroutine of cxx_eval_statement_list. Determine whether the statement
8539 : STMT matches *jump_target. If we're looking for a case label and we see
8540 : the default label, note it in ctx->css_state. */
8541 :
8542 : static bool
8543 336197 : label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
8544 : {
8545 336197 : switch (TREE_CODE (*jump_target))
8546 : {
8547 90 : case LABEL_DECL:
8548 90 : if (TREE_CODE (stmt) == LABEL_EXPR
8549 90 : && LABEL_EXPR_LABEL (stmt) == *jump_target)
8550 : return true;
8551 : break;
8552 :
8553 333998 : case INTEGER_CST:
8554 333998 : if (TREE_CODE (stmt) == CASE_LABEL_EXPR)
8555 : {
8556 333982 : gcc_assert (ctx->css_state != NULL);
8557 333982 : if (!CASE_LOW (stmt))
8558 : {
8559 : /* default: should appear just once in a SWITCH_EXPR
8560 : body (excluding nested SWITCH_EXPR). */
8561 55316 : gcc_assert (*ctx->css_state != css_default_seen);
8562 : /* When evaluating SWITCH_EXPR body for the second time,
8563 : return true for the default: label. */
8564 55316 : if (*ctx->css_state == css_default_processing)
8565 : return true;
8566 27670 : *ctx->css_state = css_default_seen;
8567 : }
8568 278666 : else if (CASE_HIGH (stmt))
8569 : {
8570 20 : if (tree_int_cst_le (CASE_LOW (stmt), *jump_target)
8571 31 : && tree_int_cst_le (*jump_target, CASE_HIGH (stmt)))
8572 : return true;
8573 : }
8574 278646 : else if (tree_int_cst_equal (*jump_target, CASE_LOW (stmt)))
8575 : return true;
8576 : }
8577 : break;
8578 :
8579 : case BREAK_STMT:
8580 : case CONTINUE_STMT:
8581 : /* These two are handled directly in cxx_eval_loop_expr by testing
8582 : breaks (jump_target) or continues (jump_target). */
8583 : break;
8584 :
8585 : case VAR_DECL:
8586 : /* Uncaught exception. This is handled by TRY_BLOCK evaluation
8587 : and other places by testing throws (jump_target). */
8588 : break;
8589 :
8590 0 : default:
8591 0 : gcc_unreachable ();
8592 : }
8593 : return false;
8594 : }
8595 :
8596 : /* Evaluate a STATEMENT_LIST for side-effects. Handles various jump
8597 : semantics, for switch, break, continue, and return. */
8598 :
8599 : static tree
8600 46144302 : cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
8601 : bool *non_constant_p, bool *overflow_p,
8602 : tree *jump_target)
8603 : {
8604 : /* In a statement-expression we want to return the last value.
8605 : For empty statement expression return void_node. */
8606 46144302 : tree r = void_node;
8607 108341912 : for (tree_stmt_iterator i = tsi_start (t); !tsi_end_p (i); ++i)
8608 : {
8609 90422938 : tree stmt = *i;
8610 :
8611 : /* We've found a continue, so skip everything until we reach
8612 : the label its jumping to. */
8613 90422938 : if (continues (jump_target))
8614 : {
8615 2199 : if (label_matches (ctx, jump_target, stmt))
8616 : /* Found it. */
8617 18 : *jump_target = NULL_TREE;
8618 : else
8619 2181 : continue;
8620 : }
8621 90420757 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
8622 11724675 : continue;
8623 :
8624 78696082 : value_cat lval = vc_discard;
8625 : /* The result of a statement-expression is not wrapped in EXPR_STMT. */
8626 111068467 : if (tsi_one_before_end_p (i)
8627 32373590 : && !VOID_TYPE_P (TREE_TYPE (stmt)))
8628 : lval = vc_prvalue;
8629 :
8630 78696082 : r = cxx_eval_constant_expression (ctx, stmt, lval,
8631 : non_constant_p, overflow_p,
8632 : jump_target);
8633 78696080 : if (*non_constant_p)
8634 : break;
8635 61769368 : if (returns (jump_target)
8636 50492610 : || breaks (jump_target)
8637 62197610 : || throws (jump_target))
8638 : break;
8639 : }
8640 46144300 : return r;
8641 : }
8642 :
8643 : /* Evaluate a LOOP_EXPR for side-effects. Handles break and return
8644 : semantics; continue semantics are covered by cxx_eval_statement_list. */
8645 :
8646 : static tree
8647 5617336 : cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
8648 : bool *non_constant_p, bool *overflow_p,
8649 : tree *jump_target)
8650 : {
8651 5617336 : tree body, cond = NULL_TREE, expr = NULL_TREE;
8652 5617336 : tree cond_prep = NULL_TREE, cond_cleanup = NULL_TREE;
8653 5617336 : unsigned cond_cleanup_depth = 0;
8654 5617336 : int count = 0;
8655 5617336 : switch (TREE_CODE (t))
8656 : {
8657 1573 : case LOOP_EXPR:
8658 1573 : body = LOOP_EXPR_BODY (t);
8659 1573 : break;
8660 4901045 : case DO_STMT:
8661 4901045 : body = DO_BODY (t);
8662 4901045 : cond = DO_COND (t);
8663 4901045 : break;
8664 182690 : case WHILE_STMT:
8665 182690 : body = WHILE_BODY (t);
8666 182690 : cond = WHILE_COND (t);
8667 182690 : cond_prep = WHILE_COND_PREP (t);
8668 182690 : cond_cleanup = WHILE_COND_CLEANUP (t);
8669 182690 : count = -1;
8670 182690 : break;
8671 532028 : case FOR_STMT:
8672 532028 : if (FOR_INIT_STMT (t))
8673 0 : cxx_eval_constant_expression (ctx, FOR_INIT_STMT (t), vc_discard,
8674 : non_constant_p, overflow_p, jump_target);
8675 532028 : if (*non_constant_p)
8676 : return NULL_TREE;
8677 532028 : body = FOR_BODY (t);
8678 532028 : cond = FOR_COND (t);
8679 532028 : expr = FOR_EXPR (t);
8680 532028 : cond_prep = FOR_COND_PREP (t);
8681 532028 : cond_cleanup = FOR_COND_CLEANUP (t);
8682 532028 : count = -1;
8683 532028 : break;
8684 0 : default:
8685 0 : gcc_unreachable ();
8686 : }
8687 5617336 : if (cond_prep)
8688 12 : gcc_assert (TREE_CODE (cond_prep) == BIND_EXPR);
8689 25839404 : auto cleanup_cond = [&] {
8690 : /* Clean up the condition variable after each iteration. */
8691 20222068 : if (cond_cleanup_depth && !*non_constant_p)
8692 : {
8693 105 : auto_vec<tree, 4> cleanups (cond_cleanup_depth);
8694 105 : tree s = BIND_EXPR_BODY (cond_prep);
8695 105 : unsigned i;
8696 210 : for (i = cond_cleanup_depth; i; --i)
8697 : {
8698 105 : tree_stmt_iterator iter = tsi_last (s);
8699 105 : s = tsi_stmt (iter);
8700 105 : cleanups.quick_push (CLEANUP_EXPR (s));
8701 105 : s = CLEANUP_BODY (s);
8702 : }
8703 105 : tree c;
8704 420 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, c)
8705 105 : cxx_eval_constant_expression (ctx, c, vc_discard, non_constant_p,
8706 : overflow_p, jump_target);
8707 105 : }
8708 20222068 : if (cond_prep)
8709 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
8710 222 : decl; decl = DECL_CHAIN (decl))
8711 111 : destroy_value_checked (ctx, decl, non_constant_p);
8712 5617336 : };
8713 15321441 : do
8714 : {
8715 15321441 : if (count != -1)
8716 : {
8717 14606723 : if (body)
8718 14606723 : cxx_eval_constant_expression (ctx, body, vc_discard,
8719 : non_constant_p, overflow_p,
8720 : jump_target);
8721 14606723 : if (breaks (jump_target))
8722 : {
8723 1991 : *jump_target = NULL_TREE;
8724 1991 : break;
8725 : }
8726 :
8727 14604732 : if (TREE_CODE (t) != LOOP_EXPR && continues (jump_target))
8728 586 : *jump_target = NULL_TREE;
8729 :
8730 14604732 : if (expr)
8731 4025698 : cxx_eval_constant_expression (ctx, expr, vc_discard,
8732 : non_constant_p, overflow_p,
8733 : jump_target);
8734 14604732 : cleanup_cond ();
8735 : }
8736 :
8737 15319450 : if (cond_prep)
8738 : {
8739 111 : for (tree decl = BIND_EXPR_VARS (cond_prep);
8740 222 : decl; decl = DECL_CHAIN (decl))
8741 111 : ctx->global->clear_value (decl);
8742 111 : if (cond_cleanup)
8743 : {
8744 : /* If COND_CLEANUP is non-NULL, we need to evaluate DEPTH
8745 : nested STATEMENT_LISTs from inside of BIND_EXPR_BODY,
8746 : but defer the evaluation of CLEANUP_EXPRs of CLEANUP_STMT
8747 : at the end of those STATEMENT_LISTs. */
8748 111 : cond_cleanup_depth = 0;
8749 111 : tree s = BIND_EXPR_BODY (cond_prep);
8750 111 : for (unsigned depth = tree_to_uhwi (cond_cleanup);
8751 222 : depth; --depth)
8752 : {
8753 111 : for (tree_stmt_iterator i = tsi_start (s);
8754 321 : !tsi_end_p (i); ++i)
8755 : {
8756 321 : tree stmt = *i;
8757 321 : if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
8758 0 : continue;
8759 321 : if (tsi_one_before_end_p (i))
8760 : {
8761 : /* The last statement in the STATEMENT_LIST
8762 : has to be a CLEANUP_STMT (verified in
8763 : finish_loop_cond_prep). We want to
8764 : evaluate just its CLEANUP_BODY part but not
8765 : CLEANUP_EXPR part just yet. */
8766 105 : gcc_assert (TREE_CODE (stmt) == CLEANUP_STMT);
8767 : /* If the CLEANUP_STMT is not actually to be
8768 : evaluated, don't increment cond_cleanup_depth
8769 : so that we don't evaluate the CLEANUP_EXPR
8770 : for it later either. */
8771 105 : if (*jump_target)
8772 : {
8773 : depth = 1;
8774 : break;
8775 : }
8776 105 : ++cond_cleanup_depth;
8777 : /* If not in the innermost one, next iteration
8778 : will handle CLEANUP_BODY similarly. */
8779 105 : if (depth > 1)
8780 : {
8781 0 : s = CLEANUP_BODY (stmt);
8782 0 : break;
8783 : }
8784 : /* The innermost one can be evaluated normally. */
8785 105 : cxx_eval_constant_expression (ctx,
8786 105 : CLEANUP_BODY (stmt),
8787 : vc_discard,
8788 : non_constant_p,
8789 : overflow_p,
8790 : jump_target);
8791 105 : break;
8792 : }
8793 : /* And so should be evaluated statements which aren't
8794 : last in the STATEMENT_LIST. */
8795 216 : cxx_eval_constant_expression (ctx, stmt, vc_discard,
8796 : non_constant_p, overflow_p,
8797 : jump_target);
8798 216 : if (*non_constant_p
8799 210 : || returns (jump_target)
8800 210 : || breaks (jump_target)
8801 210 : || continues (jump_target)
8802 531 : || throws (jump_target))
8803 : {
8804 : depth = 1;
8805 : break;
8806 : }
8807 : }
8808 : }
8809 : }
8810 : else
8811 0 : cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (cond_prep),
8812 : vc_discard, non_constant_p,
8813 : overflow_p, jump_target);
8814 : }
8815 :
8816 15319450 : if (cond)
8817 : {
8818 15317101 : tree res
8819 15317101 : = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
8820 : non_constant_p, overflow_p,
8821 : jump_target);
8822 15317101 : if (res)
8823 : {
8824 15267698 : if (verify_constant (res, ctx->quiet, non_constant_p,
8825 : overflow_p))
8826 : break;
8827 14516244 : if (integer_zerop (res))
8828 : break;
8829 : }
8830 : else
8831 49403 : gcc_assert (*jump_target);
8832 : }
8833 :
8834 9753756 : if (++count >= constexpr_loop_limit)
8835 : {
8836 27 : if (!ctx->quiet)
8837 9 : error_at (cp_expr_loc_or_input_loc (t),
8838 : "%<constexpr%> loop iteration count exceeds limit of %d "
8839 : "(use %<-fconstexpr-loop-limit=%> to increase the limit)",
8840 : constexpr_loop_limit);
8841 27 : *non_constant_p = true;
8842 27 : break;
8843 : }
8844 : }
8845 29211759 : while (!returns (jump_target)
8846 9704301 : && !breaks (jump_target)
8847 9704301 : && !continues (jump_target)
8848 9704394 : && (!switches (jump_target) || count == 0)
8849 9704271 : && !throws (jump_target)
8850 19507619 : && !*non_constant_p);
8851 :
8852 5617336 : cleanup_cond ();
8853 :
8854 5617336 : return NULL_TREE;
8855 : }
8856 :
8857 : /* Evaluate a SWITCH_EXPR for side-effects. Handles switch and break jump
8858 : semantics. */
8859 :
8860 : static tree
8861 34548 : cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
8862 : bool *non_constant_p, bool *overflow_p,
8863 : tree *jump_target)
8864 : {
8865 34548 : tree cond
8866 34548 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
8867 34548 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
8868 : non_constant_p, overflow_p,
8869 : jump_target);
8870 34548 : if (*jump_target)
8871 : return NULL_TREE;
8872 34548 : VERIFY_CONSTANT (cond);
8873 34305 : if (TREE_CODE (cond) != INTEGER_CST)
8874 : {
8875 : /* If the condition doesn't reduce to an INTEGER_CST it isn't a usable
8876 : switch condition even if it's constant enough for other things
8877 : (c++/113545). */
8878 0 : gcc_checking_assert (ctx->quiet);
8879 0 : *non_constant_p = true;
8880 0 : return t;
8881 : }
8882 :
8883 34305 : *jump_target = cond;
8884 :
8885 34305 : tree body
8886 34305 : = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_BODY (t) : SWITCH_BODY (t);
8887 34305 : constexpr_ctx new_ctx = *ctx;
8888 34305 : constexpr_switch_state css = css_default_not_seen;
8889 34305 : new_ctx.css_state = &css;
8890 34305 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
8891 : non_constant_p, overflow_p, jump_target);
8892 61985 : if (switches (jump_target) && css == css_default_seen)
8893 : {
8894 : /* If the SWITCH_EXPR body has default: label, process it once again,
8895 : this time instructing label_matches to return true for default:
8896 : label on switches (jump_target). */
8897 27646 : css = css_default_processing;
8898 27646 : cxx_eval_constant_expression (&new_ctx, body, vc_discard,
8899 : non_constant_p, overflow_p, jump_target);
8900 : }
8901 34305 : if (breaks (jump_target) || switches (jump_target))
8902 19942 : *jump_target = NULL_TREE;
8903 : return NULL_TREE;
8904 : }
8905 :
8906 : /* Find the object of TYPE under initialization in CTX. */
8907 :
8908 : static tree
8909 16621 : lookup_placeholder (const constexpr_ctx *ctx, value_cat lval, tree type)
8910 : {
8911 16621 : if (!ctx)
8912 : return NULL_TREE;
8913 :
8914 : /* Prefer the outermost matching object, but don't cross
8915 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors. */
8916 16294 : if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
8917 505 : if (tree outer_ob = lookup_placeholder (ctx->parent, lval, type))
8918 : return outer_ob;
8919 :
8920 : /* We could use ctx->object unconditionally, but using ctx->ctor when we
8921 : can is a minor optimization. */
8922 16116 : if (!lval && ctx->ctor && same_type_p (TREE_TYPE (ctx->ctor), type))
8923 300 : return ctx->ctor;
8924 :
8925 15816 : if (!ctx->object)
8926 : return NULL_TREE;
8927 :
8928 : /* Since an object cannot have a field of its own type, we can search outward
8929 : from ctx->object to find the unique containing object of TYPE. */
8930 : tree ob = ctx->object;
8931 15804 : while (ob)
8932 : {
8933 15804 : if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type))
8934 : break;
8935 219 : if (handled_component_p (ob))
8936 217 : ob = TREE_OPERAND (ob, 0);
8937 : else
8938 : ob = NULL_TREE;
8939 : }
8940 :
8941 : return ob;
8942 : }
8943 :
8944 : /* Complain about an attempt to evaluate inline assembly. If FUNDEF_P is
8945 : true, we're checking a constexpr function body. */
8946 :
8947 : static void
8948 34 : inline_asm_in_constexpr_error (location_t loc, bool fundef_p)
8949 : {
8950 34 : auto_diagnostic_group d;
8951 34 : if (constexpr_error (loc, fundef_p, "inline assembly is not a "
8952 : "constant expression"))
8953 34 : inform (loc, "only unevaluated inline assembly is allowed in a "
8954 : "%<constexpr%> function in C++20");
8955 34 : }
8956 :
8957 : /* We're getting the constant value of DECL in a manifestly constant-evaluated
8958 : context; maybe complain about that. */
8959 :
8960 : static void
8961 107841980 : maybe_warn_about_constant_value (location_t loc, tree decl)
8962 : {
8963 107841980 : static bool explained = false;
8964 107841980 : if (cxx_dialect >= cxx17
8965 107683919 : && warn_interference_size
8966 107683919 : && !OPTION_SET_P (param_destruct_interfere_size)
8967 107683919 : && DECL_CONTEXT (decl) == std_node
8968 23708321 : && DECL_NAME (decl)
8969 23708315 : && id_equal (DECL_NAME (decl), "hardware_destructive_interference_size")
8970 12 : && (LOCATION_FILE (input_location) != main_input_filename
8971 6 : || module_exporting_p ())
8972 107841983 : && warning_at (loc, OPT_Winterference_size, "use of %qD", decl)
8973 107841989 : && !explained)
8974 : {
8975 6 : explained = true;
8976 6 : inform (loc, "its value can vary between compiler versions or "
8977 : "with different %<-mtune%> or %<-mcpu%> flags");
8978 6 : inform (loc, "if this use is part of a public ABI, change it to "
8979 : "instead use a constant variable you define");
8980 6 : inform (loc, "the default value for the current CPU tuning "
8981 : "is %d bytes", param_destruct_interfere_size);
8982 6 : inform (loc, "you can stabilize this value with %<--param "
8983 : "hardware_destructive_interference_size=%d%>, or disable "
8984 : "this warning with %<-Wno-interference-size%>",
8985 : param_destruct_interfere_size);
8986 : }
8987 107841980 : }
8988 :
8989 : /* For element type ELT_TYPE, return the appropriate type of the heap object
8990 : containing such element(s). COOKIE_SIZE is NULL or the size of cookie
8991 : in bytes. If COOKIE_SIZE is NULL, return array type
8992 : ELT_TYPE[FULL_SIZE / sizeof(ELT_TYPE)], otherwise return
8993 : struct { size_t[COOKIE_SIZE/sizeof(size_t)]; ELT_TYPE[N]; }
8994 : where N is computed such that the size of the struct fits into FULL_SIZE.
8995 : If ARG_SIZE is non-NULL, it is the first argument to the new operator.
8996 : It should be passed if ELT_TYPE is zero sized type in which case FULL_SIZE
8997 : will be also 0 and so it is not possible to determine the actual array
8998 : size. CTX, NON_CONSTANT_P and OVERFLOW_P are used during constant
8999 : expression evaluation of subexpressions of ARG_SIZE. */
9000 :
9001 : static tree
9002 70763 : build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type,
9003 : tree cookie_size, tree full_size, tree arg_size,
9004 : bool *non_constant_p, bool *overflow_p,
9005 : tree *jump_target)
9006 : {
9007 70763 : gcc_assert (cookie_size == NULL_TREE || tree_fits_uhwi_p (cookie_size));
9008 70763 : gcc_assert (tree_fits_uhwi_p (full_size));
9009 70763 : unsigned HOST_WIDE_INT csz = cookie_size ? tree_to_uhwi (cookie_size) : 0;
9010 70763 : if (arg_size)
9011 : {
9012 9 : STRIP_NOPS (arg_size);
9013 9 : if (cookie_size)
9014 : {
9015 0 : if (TREE_CODE (arg_size) != PLUS_EXPR)
9016 : arg_size = NULL_TREE;
9017 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 0)) == INTEGER_CST
9018 0 : && tree_int_cst_equal (cookie_size,
9019 0 : TREE_OPERAND (arg_size, 0)))
9020 : {
9021 0 : arg_size = TREE_OPERAND (arg_size, 1);
9022 0 : STRIP_NOPS (arg_size);
9023 : }
9024 0 : else if (TREE_CODE (TREE_OPERAND (arg_size, 1)) == INTEGER_CST
9025 0 : && tree_int_cst_equal (cookie_size,
9026 0 : TREE_OPERAND (arg_size, 1)))
9027 : {
9028 0 : arg_size = TREE_OPERAND (arg_size, 0);
9029 0 : STRIP_NOPS (arg_size);
9030 : }
9031 : else
9032 : arg_size = NULL_TREE;
9033 : }
9034 9 : if (arg_size && TREE_CODE (arg_size) == MULT_EXPR)
9035 : {
9036 9 : tree op0 = TREE_OPERAND (arg_size, 0);
9037 9 : tree op1 = TREE_OPERAND (arg_size, 1);
9038 9 : if (integer_zerop (op0))
9039 9 : arg_size
9040 9 : = cxx_eval_constant_expression (ctx, op1, vc_prvalue,
9041 : non_constant_p, overflow_p,
9042 : jump_target);
9043 0 : else if (integer_zerop (op1))
9044 0 : arg_size
9045 0 : = cxx_eval_constant_expression (ctx, op0, vc_prvalue,
9046 : non_constant_p, overflow_p,
9047 : jump_target);
9048 : else
9049 : arg_size = NULL_TREE;
9050 9 : if (*jump_target)
9051 : return NULL_TREE;
9052 : }
9053 : else
9054 : arg_size = NULL_TREE;
9055 : }
9056 :
9057 9 : unsigned HOST_WIDE_INT fsz = tree_to_uhwi (arg_size ? arg_size : full_size);
9058 70763 : if (!arg_size)
9059 : {
9060 70754 : unsigned HOST_WIDE_INT esz = int_size_in_bytes (elt_type);
9061 70754 : gcc_assert (fsz >= csz);
9062 70754 : fsz -= csz;
9063 70754 : if (esz)
9064 70754 : fsz /= esz;
9065 : }
9066 70763 : tree itype2 = build_index_type (size_int (fsz - 1));
9067 70763 : if (!cookie_size)
9068 70754 : return build_cplus_array_type (elt_type, itype2);
9069 9 : return build_new_constexpr_heap_type (elt_type, cookie_size, itype2);
9070 : }
9071 :
9072 : /* Handle the case when a cleanup of some expression throws. JMP_TARGET
9073 : indicates whether the cleanup threw or not, *JUMP_TARGET indicates whether
9074 : the expression which needed the cleanup threw. If both threw, diagnose
9075 : it and return NULL, otherwise return R. If only the cleanup threw, set
9076 : *JUMP_TARGET to the exception object from the cleanup. */
9077 :
9078 : static tree
9079 812660 : merge_jump_target (location_t loc, const constexpr_ctx *ctx, tree r,
9080 : bool *non_constant_p, tree *jump_target, tree jmp_target)
9081 : {
9082 812661 : if (!throws (&jmp_target))
9083 : return r;
9084 7 : if (throws (jump_target))
9085 : {
9086 : /* [except.throw]/9 - If the exception handling mechanism
9087 : handling an uncaught exception directly invokes a function
9088 : that exits via an exception, the function std::terminate is
9089 : invoked. */
9090 6 : if (!ctx->quiet)
9091 : {
9092 2 : auto_diagnostic_group d;
9093 2 : diagnose_std_terminate (loc, ctx, *jump_target);
9094 2 : inform (loc, "destructor exited with an exception");
9095 2 : }
9096 6 : *non_constant_p = true;
9097 6 : *jump_target = NULL_TREE;
9098 6 : return NULL_TREE;
9099 : }
9100 1 : *jump_target = jmp_target;
9101 1 : return r;
9102 : }
9103 :
9104 : /* Attempt to reduce the expression T to a constant value.
9105 : On failure, issue diagnostic and return error_mark_node. */
9106 : /* FIXME unify with c_fully_fold */
9107 : /* FIXME overflow_p is too global */
9108 :
9109 : tree
9110 2697581764 : cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
9111 : value_cat lval,
9112 : bool *non_constant_p, bool *overflow_p,
9113 : tree *jump_target)
9114 : {
9115 2697581764 : if (*jump_target)
9116 : {
9117 : /* If we are jumping, ignore all statements/expressions except those
9118 : that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies. */
9119 1300849 : switch (TREE_CODE (t))
9120 : {
9121 : case BIND_EXPR:
9122 : case STATEMENT_LIST:
9123 : case LOOP_EXPR:
9124 : case COND_EXPR:
9125 : case IF_STMT:
9126 : case DO_STMT:
9127 : case WHILE_STMT:
9128 : case FOR_STMT:
9129 : break;
9130 333998 : case LABEL_EXPR:
9131 333998 : case CASE_LABEL_EXPR:
9132 333998 : if (label_matches (ctx, jump_target, t))
9133 : /* Found it. */
9134 34271 : *jump_target = NULL_TREE;
9135 333998 : return NULL_TREE;
9136 : default:
9137 : return NULL_TREE;
9138 : }
9139 : }
9140 2696498154 : if (error_operand_p (t))
9141 : {
9142 139 : *non_constant_p = true;
9143 139 : return t;
9144 : }
9145 :
9146 : /* Change the input location to the currently processed expression for
9147 : better error messages when a subexpression has no location. */
9148 2696498015 : location_t loc = cp_expr_loc_or_input_loc (t);
9149 5392990617 : iloc_sentinel sentinel (loc);
9150 :
9151 2696498015 : STRIP_ANY_LOCATION_WRAPPER (t);
9152 :
9153 2696498015 : if (CONSTANT_CLASS_P (t))
9154 : {
9155 410194236 : if (TREE_OVERFLOW (t))
9156 : {
9157 62 : if (!ctx->quiet)
9158 15 : permerror (input_location, "overflow in constant expression");
9159 62 : if (!flag_permissive || ctx->quiet)
9160 59 : *overflow_p = true;
9161 : }
9162 :
9163 410194236 : if (TREE_CODE (t) == INTEGER_CST
9164 391271248 : && TYPE_PTR_P (TREE_TYPE (t))
9165 : /* INTEGER_CST with pointer-to-method type is only used
9166 : for a virtual method in a pointer to member function.
9167 : Don't reject those. */
9168 1964654 : && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != METHOD_TYPE
9169 412158620 : && !integer_zerop (t))
9170 : {
9171 5 : if (!ctx->quiet)
9172 0 : error ("value %qE of type %qT is not a constant expression",
9173 0 : t, TREE_TYPE (t));
9174 5 : *non_constant_p = true;
9175 : }
9176 :
9177 410194236 : return t;
9178 : }
9179 :
9180 : /* Avoid excessively long constexpr evaluations. */
9181 2286303779 : if (++ctx->global->constexpr_ops_count >= constexpr_ops_limit)
9182 : {
9183 9 : if (!ctx->quiet)
9184 3 : error_at (loc,
9185 : "%<constexpr%> evaluation operation count exceeds limit of "
9186 : "%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
9187 : constexpr_ops_limit);
9188 9 : ctx->global->constexpr_ops_count = INTTYPE_MINIMUM (HOST_WIDE_INT);
9189 9 : *non_constant_p = true;
9190 9 : return t;
9191 : }
9192 :
9193 2286303770 : constexpr_ctx new_ctx;
9194 2286303770 : tree r = t;
9195 :
9196 2286303770 : tree_code tcode = TREE_CODE (t);
9197 2286303770 : switch (tcode)
9198 : {
9199 36238788 : case RESULT_DECL:
9200 36238788 : if (lval)
9201 : return t;
9202 : /* We ask for an rvalue for the RESULT_DECL when indirecting
9203 : through an invisible reference, or in named return value
9204 : optimization. */
9205 39727 : if (tree v = ctx->global->get_value (t))
9206 : return v;
9207 : else
9208 : {
9209 3 : if (!ctx->quiet)
9210 0 : error ("%qE is not a constant expression", t);
9211 3 : *non_constant_p = true;
9212 : }
9213 3 : break;
9214 :
9215 305806147 : case VAR_DECL:
9216 305806147 : if (DECL_HAS_VALUE_EXPR_P (t))
9217 : {
9218 7826617 : if (is_normal_capture_proxy (t)
9219 7826617 : && current_function_decl == DECL_CONTEXT (t))
9220 : {
9221 : /* Function parms aren't constexpr within the function
9222 : definition, so don't try to look at the closure. But if the
9223 : captured variable is constant, try to evaluate it directly. */
9224 1506979 : r = DECL_CAPTURED_VARIABLE (t);
9225 : }
9226 : else
9227 6319638 : r = DECL_VALUE_EXPR (t);
9228 :
9229 7826617 : tree type = TREE_TYPE (t);
9230 7826617 : if (TYPE_REF_P (type) != TYPE_REF_P (TREE_TYPE (r)))
9231 : {
9232 : /* Adjust r to match the reference-ness of t. */
9233 996149 : if (TYPE_REF_P (type))
9234 993848 : r = build_address (r);
9235 : else
9236 2301 : r = convert_from_reference (r);
9237 : }
9238 7826617 : return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
9239 7826617 : overflow_p, jump_target);
9240 : }
9241 : /* fall through */
9242 309914194 : case CONST_DECL:
9243 : /* We used to not check lval for CONST_DECL, but darwin.cc uses
9244 : CONST_DECL for aggregate constants. */
9245 309914194 : if (lval)
9246 : return t;
9247 221426918 : else if (t == ctx->object)
9248 1321733 : return ctx->ctor;
9249 220105185 : if (VAR_P (t))
9250 : {
9251 208170521 : if (tree v = ctx->global->get_value (t))
9252 : {
9253 : r = v;
9254 : break;
9255 : }
9256 164609826 : if (ctx->global->is_outside_lifetime (t))
9257 : {
9258 103 : if (!ctx->quiet)
9259 30 : outside_lifetime_error (loc, t);
9260 103 : *non_constant_p = true;
9261 103 : break;
9262 : }
9263 : }
9264 176544387 : if (ctx->manifestly_const_eval == mce_true)
9265 107841980 : maybe_warn_about_constant_value (loc, t);
9266 176544387 : if (COMPLETE_TYPE_P (TREE_TYPE (t))
9267 176544387 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9268 : {
9269 : /* If the class is empty, we aren't actually loading anything. */
9270 141459 : r = build_constructor (TREE_TYPE (t), NULL);
9271 141459 : TREE_CONSTANT (r) = true;
9272 : }
9273 176402928 : else if (ctx->strict)
9274 176091395 : r = decl_really_constant_value (t, /*unshare_p=*/false);
9275 : else
9276 311533 : r = decl_constant_value (t, /*unshare_p=*/false);
9277 176541690 : if (TREE_CODE (r) == TARGET_EXPR
9278 176541690 : && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
9279 0 : r = TARGET_EXPR_INITIAL (r);
9280 176541690 : if (DECL_P (r)
9281 : /* P2280 allows references to unknown. */
9282 176902937 : && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
9283 : {
9284 47135513 : if (!ctx->quiet)
9285 171 : non_const_var_error (loc, r, /*fundef_p*/false);
9286 47135513 : *non_constant_p = true;
9287 : }
9288 : break;
9289 :
9290 : case DEBUG_BEGIN_STMT:
9291 : /* ??? It might be nice to retain this information somehow, so
9292 : as to be able to step into a constexpr function call. */
9293 : /* Fall through. */
9294 :
9295 : case FUNCTION_DECL:
9296 : case TEMPLATE_DECL:
9297 : case LABEL_DECL:
9298 : case LABEL_EXPR:
9299 : case CASE_LABEL_EXPR:
9300 : case PREDICT_EXPR:
9301 : case OMP_DECLARE_MAPPER:
9302 : case REFLECT_EXPR:
9303 : return t;
9304 :
9305 251129248 : case PARM_DECL:
9306 251129248 : if (lval && !TYPE_REF_P (TREE_TYPE (t)))
9307 : {
9308 : /* glvalue use. */
9309 14071420 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9310 146689 : if (tree v = ctx->global->get_value (t))
9311 1786261788 : r = v;
9312 : }
9313 237057828 : else if (tree v = ctx->global->get_value (t))
9314 : {
9315 119528308 : r = v;
9316 119528308 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
9317 537 : r = cxx_eval_constant_expression (ctx, r, vc_prvalue,
9318 : non_constant_p, overflow_p,
9319 : jump_target);
9320 119528308 : if (*jump_target)
9321 : return NULL_TREE;
9322 : }
9323 117529520 : else if (lval)
9324 : /* Defer in case this is only used for its type. */;
9325 117529520 : else if (ctx->global->is_outside_lifetime (t))
9326 : {
9327 18 : if (!ctx->quiet)
9328 6 : outside_lifetime_error (loc, t);
9329 18 : *non_constant_p = true;
9330 18 : break;
9331 : }
9332 117529502 : else if (COMPLETE_TYPE_P (TREE_TYPE (t))
9333 117529502 : && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
9334 : {
9335 : /* If the class is empty, we aren't actually loading anything. */
9336 6817 : r = build_constructor (TREE_TYPE (t), NULL);
9337 6817 : TREE_CONSTANT (r) = true;
9338 : }
9339 117522685 : else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t)))
9340 : /* P2280 allows references to unknown... */;
9341 117264807 : else if (p2280_active_p (ctx) && is_this_parameter (t))
9342 : /* ...as well as the this pointer. */;
9343 : else
9344 : {
9345 116799580 : if (!ctx->quiet)
9346 195 : error ("%qE is not a constant expression", t);
9347 116799580 : *non_constant_p = true;
9348 : }
9349 : break;
9350 :
9351 199584393 : case CALL_EXPR:
9352 199584393 : case AGGR_INIT_EXPR:
9353 199584393 : r = cxx_eval_call_expression (ctx, t, lval,
9354 : non_constant_p, overflow_p, jump_target);
9355 199584393 : break;
9356 :
9357 16819553 : case DECL_EXPR:
9358 16819553 : {
9359 16819553 : r = DECL_EXPR_DECL (t);
9360 16819553 : if (TREE_CODE (r) == USING_DECL)
9361 : {
9362 8978 : r = void_node;
9363 8978 : break;
9364 : }
9365 :
9366 16810575 : if (VAR_P (r)
9367 16810575 : && (TREE_STATIC (r)
9368 16687526 : || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
9369 : /* Allow __FUNCTION__ etc. */
9370 123049 : && !DECL_ARTIFICIAL (r)
9371 16810608 : && !decl_constant_var_p (r))
9372 : {
9373 7 : if (!ctx->quiet)
9374 : {
9375 2 : if (CP_DECL_THREAD_LOCAL_P (r))
9376 1 : error_at (loc, "control passes through definition of %qD "
9377 : "with thread storage duration", r);
9378 : else
9379 1 : error_at (loc, "control passes through definition of %qD "
9380 : "with static storage duration", r);
9381 : }
9382 7 : *non_constant_p = true;
9383 7 : break;
9384 : }
9385 :
9386 : /* make_rtl_for_nonlocal_decl could have deferred emission of
9387 : a local static var, but if it appears in a statement expression
9388 : which is constant expression evaluated to e.g. just the address
9389 : of the variable, its DECL_EXPR will never be seen during
9390 : gimple lowering's record_vars_into as the statement expression
9391 : will not be in the IL at all. */
9392 16810568 : if (VAR_P (r)
9393 16810568 : && TREE_STATIC (r)
9394 123042 : && !DECL_REALLY_EXTERN (r)
9395 123031 : && DECL_FUNCTION_SCOPE_P (r)
9396 123031 : && !var_in_maybe_constexpr_fn (r)
9397 16810571 : && decl_constant_var_p (r))
9398 : {
9399 3 : varpool_node *node = varpool_node::get (r);
9400 3 : if (node == NULL || !node->definition)
9401 3 : rest_of_decl_compilation (r, 0, at_eof);
9402 : }
9403 :
9404 33463632 : if (AGGREGATE_TYPE_P (TREE_TYPE (r))
9405 32147952 : || VECTOR_TYPE_P (TREE_TYPE (r)))
9406 : {
9407 1474290 : new_ctx = *ctx;
9408 1474290 : new_ctx.object = r;
9409 1474290 : new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
9410 1474290 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
9411 1474290 : ctx->global->put_value (r, new_ctx.ctor);
9412 1474290 : ctx = &new_ctx;
9413 : }
9414 :
9415 16810568 : if (tree init = DECL_INITIAL (r))
9416 : {
9417 7585463 : init = cxx_eval_constant_expression (ctx, init, vc_prvalue,
9418 : non_constant_p, overflow_p,
9419 : jump_target);
9420 7585463 : if (*jump_target)
9421 : return NULL_TREE;
9422 : /* Don't share a CONSTRUCTOR that might be changed. */
9423 7585463 : init = unshare_constructor (init);
9424 : /* Remember that a constant object's constructor has already
9425 : run. */
9426 15170926 : if (CLASS_TYPE_P (TREE_TYPE (r))
9427 7983948 : && CP_TYPE_CONST_P (TREE_TYPE (r)))
9428 36263 : TREE_READONLY (init) = true;
9429 7585463 : ctx->global->put_value (r, init);
9430 : }
9431 9225105 : else if (ctx == &new_ctx)
9432 : /* We gave it a CONSTRUCTOR above. */;
9433 : else
9434 8183740 : ctx->global->put_value (r, NULL_TREE);
9435 : }
9436 : break;
9437 :
9438 26125475 : case TARGET_EXPR:
9439 26125475 : {
9440 26125475 : tree type = TREE_TYPE (t);
9441 :
9442 26125475 : if (!literal_type_p (type))
9443 : {
9444 6300 : if (!ctx->quiet)
9445 : {
9446 0 : auto_diagnostic_group d;
9447 0 : error ("temporary of non-literal type %qT in a "
9448 : "constant expression", type);
9449 0 : explain_non_literal_class (type);
9450 0 : }
9451 6300 : *non_constant_p = true;
9452 12889973 : break;
9453 : }
9454 26119175 : gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (t));
9455 : /* Avoid evaluating a TARGET_EXPR more than once. */
9456 26119175 : tree slot = TARGET_EXPR_SLOT (t);
9457 26119175 : if (tree v = ctx->global->get_value (slot))
9458 : {
9459 1149 : if (lval)
9460 10609750 : return slot;
9461 : r = v;
9462 : break;
9463 : }
9464 26118026 : if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
9465 : {
9466 : /* We're being expanded without an explicit target, so start
9467 : initializing a new object; expansion with an explicit target
9468 : strips the TARGET_EXPR before we get here. */
9469 20660252 : new_ctx = *ctx;
9470 : /* Link CTX to NEW_CTX so that lookup_placeholder can resolve
9471 : any PLACEHOLDER_EXPR within the initializer that refers to the
9472 : former object under construction. */
9473 20660252 : new_ctx.parent = ctx;
9474 20660252 : new_ctx.ctor = build_constructor (type, NULL);
9475 20660252 : CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
9476 20660252 : new_ctx.object = slot;
9477 20660252 : ctx->global->put_value (new_ctx.object, new_ctx.ctor);
9478 20660252 : ctx = &new_ctx;
9479 : }
9480 :
9481 : /* If the initializer is complex, evaluate it to initialize slot. */
9482 26118026 : bool is_complex = target_expr_needs_replace (t);
9483 26118026 : if (is_complex)
9484 : /* In case no initialization actually happens, clear out any
9485 : void_node from a previous evaluation. */
9486 263 : ctx->global->put_value (slot, NULL_TREE);
9487 :
9488 : /* Pass vc_prvalue because this indicates
9489 : initialization of a temporary. */
9490 26118026 : r = cxx_eval_constant_expression (ctx, TARGET_EXPR_INITIAL (t),
9491 : vc_prvalue, non_constant_p,
9492 : overflow_p, jump_target);
9493 26118026 : if (*non_constant_p)
9494 : break;
9495 13235137 : if (ctx->save_exprs)
9496 6906099 : ctx->save_exprs->safe_push (slot);
9497 13235137 : if (*jump_target)
9498 : return NULL_TREE;
9499 13234899 : if (!is_complex)
9500 : {
9501 13234684 : r = unshare_constructor (r);
9502 : /* Adjust the type of the result to the type of the temporary. */
9503 13234684 : r = adjust_temp_type (type, r);
9504 13234684 : ctx->global->put_value (slot, r);
9505 : }
9506 13234899 : if (TARGET_EXPR_CLEANUP (t)
9507 13234899 : && (!CLEANUP_EH_ONLY (t) || cxx_dialect >= cxx26))
9508 : {
9509 1091976 : ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t));
9510 : /* Mark CLEANUP_EH_ONLY cleanups by pushing NULL_TREE after
9511 : them. */
9512 1091976 : if (CLEANUP_EH_ONLY (t))
9513 952 : ctx->global->cleanups->safe_push (NULL_TREE);
9514 : }
9515 13234899 : if (lval)
9516 : return slot;
9517 2625752 : if (is_complex)
9518 0 : r = ctx->global->get_value (slot);
9519 : }
9520 2625752 : break;
9521 :
9522 83452842 : case INIT_EXPR:
9523 83452842 : case MODIFY_EXPR:
9524 83452842 : gcc_assert (jump_target == NULL || *jump_target == NULL_TREE);
9525 83452842 : r = cxx_eval_store_expression (ctx, t, lval,
9526 : non_constant_p, overflow_p, jump_target);
9527 83452842 : break;
9528 :
9529 0 : case SCOPE_REF:
9530 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
9531 : lval,
9532 : non_constant_p, overflow_p,
9533 : jump_target);
9534 0 : break;
9535 :
9536 53019480 : case RETURN_EXPR:
9537 53019480 : if (TREE_OPERAND (t, 0) != NULL_TREE)
9538 52837270 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
9539 : lval,
9540 : non_constant_p, overflow_p,
9541 : jump_target);
9542 53019478 : if (!throws (jump_target))
9543 53019362 : *jump_target = t;
9544 : break;
9545 20954 : case BREAK_STMT:
9546 20954 : case CONTINUE_STMT:
9547 20954 : *jump_target = t;
9548 20954 : break;
9549 :
9550 590098 : case SAVE_EXPR:
9551 : /* Avoid evaluating a SAVE_EXPR more than once. */
9552 590098 : if (tree v = ctx->global->get_value (t))
9553 : r = v;
9554 : else
9555 : {
9556 579967 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
9557 : vc_prvalue, non_constant_p,
9558 : overflow_p, jump_target);
9559 579967 : if (*non_constant_p || *jump_target)
9560 : break;
9561 7944 : ctx->global->put_value (t, r);
9562 7944 : if (ctx->save_exprs)
9563 5806 : ctx->save_exprs->safe_push (t);
9564 : }
9565 : break;
9566 :
9567 44271139 : case NON_LVALUE_EXPR:
9568 44271139 : case EXPR_STMT:
9569 44271139 : case EH_SPEC_BLOCK:
9570 44271139 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
9571 : lval,
9572 : non_constant_p, overflow_p,
9573 : jump_target);
9574 44271139 : break;
9575 :
9576 2226 : case TRY_BLOCK:
9577 2226 : r = cxx_eval_constant_expression (ctx, TRY_STMTS (t), lval,
9578 : non_constant_p, overflow_p,
9579 : jump_target);
9580 2226 : if (!*non_constant_p && throws (jump_target))
9581 1695 : if (tree h = TRY_HANDLERS (t))
9582 : {
9583 1695 : tree type = strip_array_types (TREE_TYPE (*jump_target));
9584 1695 : if (TREE_CODE (h) == STATEMENT_LIST)
9585 : {
9586 470 : for (tree stmt : tsi_range (h))
9587 453 : if (TREE_CODE (stmt) == HANDLER
9588 453 : && handler_match_for_exception_type (stmt, type))
9589 : {
9590 : h = stmt;
9591 : break;
9592 : }
9593 231 : if (TREE_CODE (h) == STATEMENT_LIST)
9594 : h = NULL_TREE;
9595 : }
9596 1464 : else if (TREE_CODE (h) != HANDLER
9597 1464 : || !handler_match_for_exception_type (h, type))
9598 : h = NULL_TREE;
9599 : if (h)
9600 : {
9601 1678 : gcc_assert (VAR_P (*jump_target));
9602 1678 : ctx->global->caught_exceptions.safe_push (*jump_target);
9603 1678 : ctx->global->caught_exceptions.safe_push (HANDLER_TYPE (h));
9604 1678 : *jump_target = NULL_TREE;
9605 1678 : r = cxx_eval_constant_expression (ctx, HANDLER_BODY (h),
9606 : vc_discard, non_constant_p,
9607 : overflow_p, jump_target);
9608 : }
9609 : }
9610 : break;
9611 :
9612 76428228 : case CLEANUP_POINT_EXPR:
9613 76428228 : {
9614 76428228 : auto_vec<tree, 2> cleanups;
9615 76428228 : vec<tree> *prev_cleanups = ctx->global->cleanups;
9616 76428228 : ctx->global->cleanups = &cleanups;
9617 :
9618 76428228 : auto_vec<tree, 10> save_exprs;
9619 76428228 : constexpr_ctx new_ctx = *ctx;
9620 76428228 : new_ctx.save_exprs = &save_exprs;
9621 :
9622 76428228 : r = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 0),
9623 : lval,
9624 : non_constant_p, overflow_p,
9625 : jump_target);
9626 :
9627 76428227 : ctx->global->cleanups = prev_cleanups;
9628 76428227 : unsigned int i;
9629 76428227 : tree cleanup, jmp_target = NULL_TREE;
9630 76428227 : bool eh = throws (jump_target);
9631 : /* Evaluate the cleanups. */
9632 153825793 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
9633 969339 : if (cleanup == NULL_TREE)
9634 : {
9635 : /* NULL_TREE cleanup is a marker that before it is
9636 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it
9637 : if the body didn't throw. */
9638 929 : if (!eh)
9639 928 : --i;
9640 : }
9641 : else
9642 968410 : cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard,
9643 : non_constant_p, overflow_p,
9644 : &jmp_target);
9645 :
9646 : /* Forget SAVE_EXPRs and TARGET_EXPRs created by this
9647 : full-expression. */
9648 236196586 : for (tree save_expr : save_exprs)
9649 6911905 : destroy_value_checked (ctx, save_expr, non_constant_p);
9650 76428227 : if (throws (&jmp_target))
9651 0 : *jump_target = jmp_target;
9652 76428227 : }
9653 76428227 : break;
9654 :
9655 50071106 : case MUST_NOT_THROW_EXPR:
9656 50071106 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
9657 : lval,
9658 : non_constant_p, overflow_p,
9659 : jump_target);
9660 50071105 : if (throws (jump_target))
9661 : {
9662 : /* [except.handle]/7 - If the search for a handler exits the
9663 : function body of a function with a non-throwing exception
9664 : specification, the function std::terminate is invoked. */
9665 27 : if (!ctx->quiet)
9666 : {
9667 9 : auto_diagnostic_group d;
9668 9 : diagnose_std_terminate (loc, ctx, *jump_target);
9669 9 : if (MUST_NOT_THROW_NOEXCEPT_P (t)
9670 7 : && ctx->call
9671 16 : && ctx->call->fundef)
9672 7 : inform (loc, "uncaught exception exited from %<noexcept%> "
9673 : "function %qD",
9674 : ctx->call->fundef->decl);
9675 2 : else if (MUST_NOT_THROW_THROW_P (t))
9676 1 : inform (loc, "destructor exited with an exception after "
9677 : "initializing the exception object");
9678 1 : else if (MUST_NOT_THROW_CATCH_P (t))
9679 1 : inform (loc, "constructor exited with another exception while "
9680 : "entering handler");
9681 9 : }
9682 27 : *non_constant_p = true;
9683 27 : *jump_target = NULL_TREE;
9684 27 : r = NULL_TREE;
9685 : }
9686 : break;
9687 :
9688 0 : case TRY_CATCH_EXPR:
9689 0 : if (TREE_OPERAND (t, 0) == NULL_TREE)
9690 : {
9691 0 : r = void_node;
9692 0 : break;
9693 : }
9694 0 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
9695 : non_constant_p, overflow_p,
9696 : jump_target);
9697 0 : if (!*non_constant_p && throws (jump_target))
9698 : {
9699 0 : tree jmp_target = NULL_TREE;
9700 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
9701 : non_constant_p, overflow_p,
9702 : &jmp_target);
9703 0 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
9704 : jmp_target);
9705 : }
9706 : break;
9707 :
9708 620 : case TRY_FINALLY_EXPR:
9709 620 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
9710 : non_constant_p, overflow_p,
9711 : jump_target);
9712 620 : if (!*non_constant_p)
9713 : {
9714 605 : tree jmp_target = NULL_TREE;
9715 : /* Also evaluate the cleanup. */
9716 605 : if (TREE_CODE (TREE_OPERAND (t, 1)) == EH_ELSE_EXPR
9717 605 : && throws (jump_target))
9718 0 : cxx_eval_constant_expression (ctx,
9719 0 : TREE_OPERAND (TREE_OPERAND (t, 1),
9720 : 1), vc_discard,
9721 : non_constant_p, overflow_p,
9722 : &jmp_target);
9723 : else
9724 605 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
9725 : non_constant_p, overflow_p,
9726 : &jmp_target);
9727 605 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
9728 : jmp_target);
9729 : }
9730 : break;
9731 :
9732 0 : case EH_ELSE_EXPR:
9733 : /* Evaluate any cleanup that applies to non-EH exits. */
9734 0 : cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_discard,
9735 : non_constant_p, overflow_p,
9736 : jump_target);
9737 :
9738 : /* The EH path is handled in TRY_FINALLY_EXPR handling above. */
9739 0 : break;
9740 :
9741 3444704 : case CLEANUP_STMT:
9742 3444704 : r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
9743 : non_constant_p, overflow_p,
9744 : jump_target);
9745 3444703 : if ((!CLEANUP_EH_ONLY (t) || throws (jump_target)) && !*non_constant_p)
9746 : {
9747 812055 : iloc_sentinel ils (loc);
9748 812055 : tree jmp_target = NULL_TREE;
9749 : /* Also evaluate the cleanup. */
9750 812055 : cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), vc_discard,
9751 : non_constant_p, overflow_p,
9752 : &jmp_target);
9753 812055 : r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
9754 : jmp_target);
9755 812055 : }
9756 : break;
9757 :
9758 : /* These differ from cxx_eval_unary_expression in that this doesn't
9759 : check for a constant operand or result; an address can be
9760 : constant without its operand being, and vice versa. */
9761 101406005 : case MEM_REF:
9762 101406005 : case INDIRECT_REF:
9763 101406005 : r = cxx_eval_indirect_ref (ctx, t, lval,
9764 : non_constant_p, overflow_p,
9765 : jump_target);
9766 101406005 : break;
9767 :
9768 110220471 : case ADDR_EXPR:
9769 110220471 : {
9770 110220471 : tree oldop = TREE_OPERAND (t, 0);
9771 110220471 : tree op = cxx_eval_constant_expression (ctx, oldop, vc_glvalue,
9772 : non_constant_p, overflow_p,
9773 : jump_target);
9774 110220471 : if (*jump_target)
9775 : return NULL_TREE;
9776 : /* Don't VERIFY_CONSTANT here. */
9777 110220467 : if (*non_constant_p)
9778 : return t;
9779 87777448 : gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
9780 : /* This function does more aggressive folding than fold itself. */
9781 87777448 : r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
9782 87777448 : if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
9783 : {
9784 64779818 : ggc_free (r);
9785 64779818 : return t;
9786 : }
9787 : break;
9788 : }
9789 :
9790 466760 : case REALPART_EXPR:
9791 466760 : case IMAGPART_EXPR:
9792 466760 : if (lval)
9793 : {
9794 614 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
9795 : non_constant_p, overflow_p,
9796 : jump_target);
9797 614 : if (*jump_target)
9798 : return NULL_TREE;
9799 614 : if (r == error_mark_node)
9800 : ;
9801 614 : else if (r == TREE_OPERAND (t, 0) || lval == vc_discard)
9802 : r = t;
9803 : else
9804 568 : r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
9805 : break;
9806 : }
9807 : /* FALLTHRU */
9808 24089950 : case CONJ_EXPR:
9809 24089950 : case FIX_TRUNC_EXPR:
9810 24089950 : case FLOAT_EXPR:
9811 24089950 : case NEGATE_EXPR:
9812 24089950 : case ABS_EXPR:
9813 24089950 : case ABSU_EXPR:
9814 24089950 : case BIT_NOT_EXPR:
9815 24089950 : case TRUTH_NOT_EXPR:
9816 24089950 : case FIXED_CONVERT_EXPR:
9817 24089950 : case VEC_DUPLICATE_EXPR:
9818 24089950 : r = cxx_eval_unary_expression (ctx, t, lval,
9819 : non_constant_p, overflow_p,
9820 : jump_target);
9821 24089950 : break;
9822 :
9823 10425168 : case SIZEOF_EXPR:
9824 10425168 : r = fold_sizeof_expr (t);
9825 : /* In a template, fold_sizeof_expr may merely create a new SIZEOF_EXPR,
9826 : which could lead to an infinite recursion. */
9827 10425168 : if (TREE_CODE (r) != SIZEOF_EXPR)
9828 10425168 : r = cxx_eval_constant_expression (ctx, r, lval,
9829 : non_constant_p, overflow_p,
9830 : jump_target);
9831 : else
9832 : {
9833 0 : *non_constant_p = true;
9834 0 : gcc_assert (ctx->quiet);
9835 : }
9836 :
9837 : break;
9838 :
9839 8905837 : case COMPOUND_EXPR:
9840 8905837 : {
9841 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
9842 : COMPOUND_EXPR; don't get confused. Also handle EMPTY_CLASS_EXPR
9843 : introduced by build_call_a. */
9844 8905837 : tree op0 = TREE_OPERAND (t, 0);
9845 8905837 : tree op1 = TREE_OPERAND (t, 1);
9846 8905837 : STRIP_NOPS (op1);
9847 3616296 : if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
9848 10124340 : || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
9849 5606475 : r = cxx_eval_constant_expression (ctx, op0,
9850 : lval, non_constant_p, overflow_p,
9851 : jump_target);
9852 : else
9853 : {
9854 : /* Check that the LHS is constant and then discard it. */
9855 3299362 : cxx_eval_constant_expression (ctx, op0, vc_discard,
9856 : non_constant_p, overflow_p,
9857 : jump_target);
9858 3299362 : if (*jump_target)
9859 : return NULL_TREE;
9860 3295980 : if (*non_constant_p)
9861 : return t;
9862 3049199 : op1 = TREE_OPERAND (t, 1);
9863 3049199 : r = cxx_eval_constant_expression (ctx, op1,
9864 : lval, non_constant_p, overflow_p,
9865 : jump_target);
9866 : }
9867 : }
9868 : break;
9869 :
9870 93791707 : case POINTER_PLUS_EXPR:
9871 93791707 : case POINTER_DIFF_EXPR:
9872 93791707 : case PLUS_EXPR:
9873 93791707 : case MINUS_EXPR:
9874 93791707 : case MULT_EXPR:
9875 93791707 : case TRUNC_DIV_EXPR:
9876 93791707 : case CEIL_DIV_EXPR:
9877 93791707 : case FLOOR_DIV_EXPR:
9878 93791707 : case ROUND_DIV_EXPR:
9879 93791707 : case TRUNC_MOD_EXPR:
9880 93791707 : case CEIL_MOD_EXPR:
9881 93791707 : case ROUND_MOD_EXPR:
9882 93791707 : case RDIV_EXPR:
9883 93791707 : case EXACT_DIV_EXPR:
9884 93791707 : case MIN_EXPR:
9885 93791707 : case MAX_EXPR:
9886 93791707 : case LSHIFT_EXPR:
9887 93791707 : case RSHIFT_EXPR:
9888 93791707 : case LROTATE_EXPR:
9889 93791707 : case RROTATE_EXPR:
9890 93791707 : case BIT_IOR_EXPR:
9891 93791707 : case BIT_XOR_EXPR:
9892 93791707 : case BIT_AND_EXPR:
9893 93791707 : case TRUTH_XOR_EXPR:
9894 93791707 : case LT_EXPR:
9895 93791707 : case LE_EXPR:
9896 93791707 : case GT_EXPR:
9897 93791707 : case GE_EXPR:
9898 93791707 : case EQ_EXPR:
9899 93791707 : case NE_EXPR:
9900 93791707 : case SPACESHIP_EXPR:
9901 93791707 : case UNORDERED_EXPR:
9902 93791707 : case ORDERED_EXPR:
9903 93791707 : case UNLT_EXPR:
9904 93791707 : case UNLE_EXPR:
9905 93791707 : case UNGT_EXPR:
9906 93791707 : case UNGE_EXPR:
9907 93791707 : case UNEQ_EXPR:
9908 93791707 : case LTGT_EXPR:
9909 93791707 : case RANGE_EXPR:
9910 93791707 : case COMPLEX_EXPR:
9911 93791707 : r = cxx_eval_binary_expression (ctx, t, lval,
9912 : non_constant_p, overflow_p,
9913 : jump_target);
9914 93791707 : break;
9915 :
9916 : /* fold can introduce non-IF versions of these; still treat them as
9917 : short-circuiting. */
9918 12498566 : case TRUTH_AND_EXPR:
9919 12498566 : case TRUTH_ANDIF_EXPR:
9920 12498566 : r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
9921 : boolean_true_node,
9922 : non_constant_p, overflow_p,
9923 : jump_target);
9924 12498566 : break;
9925 :
9926 3395041 : case TRUTH_OR_EXPR:
9927 3395041 : case TRUTH_ORIF_EXPR:
9928 3395041 : r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
9929 : boolean_false_node,
9930 : non_constant_p, overflow_p,
9931 : jump_target);
9932 3395041 : break;
9933 :
9934 10827587 : case ARRAY_REF:
9935 10827587 : r = cxx_eval_array_reference (ctx, t, lval,
9936 : non_constant_p, overflow_p,
9937 : jump_target);
9938 10827587 : break;
9939 :
9940 106441807 : case COMPONENT_REF:
9941 106441807 : if (is_overloaded_fn (t))
9942 : {
9943 : /* We can only get here in checking mode via
9944 : build_non_dependent_expr, because any expression that
9945 : calls or takes the address of the function will have
9946 : pulled a FUNCTION_DECL out of the COMPONENT_REF. */
9947 6 : gcc_checking_assert (ctx->quiet || errorcount);
9948 6 : *non_constant_p = true;
9949 6 : return t;
9950 : }
9951 106441801 : r = cxx_eval_component_reference (ctx, t, lval,
9952 : non_constant_p, overflow_p,
9953 : jump_target);
9954 106441801 : break;
9955 :
9956 16029 : case BIT_FIELD_REF:
9957 16029 : r = cxx_eval_bit_field_ref (ctx, t, lval,
9958 : non_constant_p, overflow_p,
9959 : jump_target);
9960 16029 : break;
9961 :
9962 27620387 : case COND_EXPR:
9963 27620387 : case IF_STMT:
9964 27620387 : if (*jump_target)
9965 : {
9966 151144 : tree orig_jump = *jump_target;
9967 151144 : tree arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 1))
9968 302288 : ? TREE_OPERAND (t, 1) : void_node);
9969 : /* When jumping to a label, the label might be either in the
9970 : then or else blocks, so process then block first in skipping
9971 : mode first, and if we are still in the skipping mode at its end,
9972 : process the else block too. */
9973 151144 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
9974 : overflow_p, jump_target);
9975 : /* It's possible that we found the label in the then block. But
9976 : it could have been followed by another jumping statement, e.g.
9977 : say we're looking for case 1:
9978 : if (cond)
9979 : {
9980 : // skipped statements
9981 : case 1:; // clears up *jump_target
9982 : return 1; // and sets it to a RETURN_EXPR
9983 : }
9984 : else { ... }
9985 : in which case we need not go looking to the else block.
9986 : (goto is not allowed in a constexpr function.) */
9987 151144 : if (*jump_target == orig_jump)
9988 : {
9989 151192 : arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 2))
9990 151192 : ? TREE_OPERAND (t, 2) : void_node);
9991 151110 : r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
9992 : overflow_p, jump_target);
9993 : }
9994 : break;
9995 : }
9996 27469243 : r = cxx_eval_conditional_expression (ctx, t, lval,
9997 : non_constant_p, overflow_p,
9998 : jump_target);
9999 27469243 : break;
10000 4788 : case VEC_COND_EXPR:
10001 4788 : r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
10002 : overflow_p, jump_target);
10003 4788 : break;
10004 :
10005 25032860 : case CONSTRUCTOR:
10006 25032860 : if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
10007 : {
10008 : /* Don't re-process a constant CONSTRUCTOR. */
10009 22861412 : verify_constructor_flags (t);
10010 22861412 : if (TREE_CONSTANT (t))
10011 : return t;
10012 : }
10013 2171448 : if (TREE_CLOBBER_P (t))
10014 : {
10015 : /* Assignment from a clobber is handled in cxx_eval_store_expression;
10016 : a clobber by itself isn't a constant-expression. */
10017 0 : gcc_assert (ctx->quiet);
10018 0 : *non_constant_p = true;
10019 0 : break;
10020 : }
10021 2171448 : r = cxx_eval_bare_aggregate (ctx, t, lval,
10022 : non_constant_p, overflow_p, jump_target);
10023 2171448 : break;
10024 :
10025 524 : case VEC_INIT_EXPR:
10026 : /* We can get this in a defaulted constructor for a class with a
10027 : non-static data member of array type. Either the initializer will
10028 : be NULL, meaning default-initialization, or it will be an lvalue
10029 : or xvalue of the same type, meaning direct-initialization from the
10030 : corresponding member. */
10031 524 : r = cxx_eval_vec_init (ctx, t, lval,
10032 : non_constant_p, overflow_p, jump_target);
10033 524 : break;
10034 :
10035 15128 : case VEC_PERM_EXPR:
10036 15128 : r = cxx_eval_trinary_expression (ctx, t, lval,
10037 : non_constant_p, overflow_p,
10038 : jump_target);
10039 15128 : break;
10040 :
10041 4 : case PAREN_EXPR:
10042 4 : gcc_assert (!REF_PARENTHESIZED_P (t));
10043 : /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
10044 : constant expressions since it's unaffected by -fassociative-math. */
10045 4 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10046 : non_constant_p, overflow_p,
10047 : jump_target);
10048 4 : break;
10049 :
10050 422518518 : case NOP_EXPR:
10051 422518518 : if (REINTERPRET_CAST_P (t))
10052 : {
10053 73 : if (!ctx->quiet)
10054 6 : error_at (loc,
10055 : "%<reinterpret_cast%> is not a constant expression");
10056 73 : *non_constant_p = true;
10057 73 : return t;
10058 : }
10059 : /* FALLTHROUGH. */
10060 496921772 : case CONVERT_EXPR:
10061 496921772 : case VIEW_CONVERT_EXPR:
10062 496921772 : case UNARY_PLUS_EXPR:
10063 496921772 : {
10064 496921772 : tree oldop = TREE_OPERAND (t, 0);
10065 :
10066 496921772 : tree op = cxx_eval_constant_expression (ctx, oldop,
10067 496921772 : VOID_TYPE_P (TREE_TYPE (t))
10068 : ? vc_discard
10069 : : tcode == VIEW_CONVERT_EXPR
10070 469363346 : ? lval : vc_prvalue,
10071 : non_constant_p, overflow_p,
10072 : jump_target);
10073 496919074 : if (*jump_target)
10074 : return NULL_TREE;
10075 496917111 : if (*non_constant_p)
10076 : return t;
10077 362039257 : tree type = TREE_TYPE (t);
10078 :
10079 362039257 : if (VOID_TYPE_P (type))
10080 25392180 : return void_node;
10081 :
10082 336647077 : if (TREE_CODE (t) == CONVERT_EXPR
10083 28465591 : && ARITHMETIC_TYPE_P (type)
10084 4717471 : && INDIRECT_TYPE_P (TREE_TYPE (op))
10085 336670535 : && ctx->strict)
10086 : {
10087 23366 : if (!ctx->quiet)
10088 54 : error_at (loc,
10089 : "conversion from pointer type %qT to arithmetic type "
10090 54 : "%qT in a constant expression", TREE_TYPE (op), type);
10091 23366 : *non_constant_p = true;
10092 23366 : return t;
10093 : }
10094 :
10095 : /* [expr.const]: a conversion from type cv void* to a pointer-to-object
10096 : type cannot be part of a core constant expression as a resolution to
10097 : DR 1312. */
10098 118629526 : if (TYPE_PTROB_P (type)
10099 116374728 : && TYPE_PTR_P (TREE_TYPE (op))
10100 91011016 : && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
10101 : /* Inside a call to std::construct_at,
10102 : std::allocator<T>::{,de}allocate, or
10103 : std::source_location::current, we permit casting from void*
10104 : because that is compiler-generated code. */
10105 767144 : && !is_std_construct_at (ctx->call)
10106 89347 : && !is_std_allocator_allocate (ctx->call)
10107 336665327 : && !is_std_source_location_current (ctx->call))
10108 : {
10109 : /* Likewise, don't error when casting from void* when OP is
10110 : &heap uninit and similar. */
10111 41457 : tree sop = tree_strip_nop_conversions (op);
10112 41457 : tree decl = NULL_TREE;
10113 41457 : if (TREE_CODE (sop) == ADDR_EXPR)
10114 31750 : decl = TREE_OPERAND (sop, 0);
10115 31750 : if (decl
10116 31750 : && VAR_P (decl)
10117 31382 : && DECL_ARTIFICIAL (decl)
10118 63093 : && (DECL_NAME (decl) == heap_identifier
10119 24298 : || DECL_NAME (decl) == heap_uninit_identifier
10120 2715 : || DECL_NAME (decl) == heap_vec_identifier
10121 1465 : || DECL_NAME (decl) == heap_vec_uninit_identifier))
10122 : /* OK */;
10123 : /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
10124 : cv void" to a pointer-to-object type T unless P is a null
10125 : pointer value or points to an object whose type is similar to
10126 : T. */
10127 10130 : else if (cxx_dialect > cxx23)
10128 : {
10129 9978 : if (integer_zerop (sop))
10130 28 : return build_int_cst (type, 0);
10131 9950 : r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
10132 : NULL, jump_target);
10133 9950 : if (*jump_target)
10134 : return NULL_TREE;
10135 9950 : if (r)
10136 : {
10137 9915 : r = build1 (ADDR_EXPR, type, r);
10138 9915 : break;
10139 : }
10140 35 : if (!ctx->quiet)
10141 : {
10142 3 : gcc_assert (TREE_CODE (sop) == ADDR_EXPR);
10143 3 : auto_diagnostic_group d;
10144 3 : error_at (loc, "cast from %qT is not allowed in a "
10145 : "constant expression because "
10146 : "pointed-to type %qT is not similar to %qT",
10147 3 : TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)),
10148 3 : TREE_TYPE (type));
10149 3 : tree obj = build_fold_indirect_ref (sop);
10150 3 : if (TREE_CODE (obj) == COMPONENT_REF)
10151 2 : obj = TREE_OPERAND (obj, 1);
10152 3 : if (DECL_P (obj))
10153 3 : inform (DECL_SOURCE_LOCATION (obj),
10154 : "pointed-to object declared here");
10155 3 : }
10156 35 : *non_constant_p = true;
10157 35 : return t;
10158 : }
10159 : else
10160 : {
10161 152 : if (!ctx->quiet)
10162 26 : error_at (loc, "cast from %qT is not allowed in a "
10163 : "constant expression before C++26",
10164 26 : TREE_TYPE (op));
10165 152 : *non_constant_p = true;
10166 152 : return t;
10167 : }
10168 : }
10169 :
10170 336613581 : if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
10171 : {
10172 1013 : op = cplus_expand_constant (op);
10173 1013 : if (TREE_CODE (op) == PTRMEM_CST)
10174 : {
10175 21 : if (!ctx->quiet)
10176 3 : error_at (loc, "%qE is not a constant expression when the "
10177 : "class %qT is still incomplete", op,
10178 3 : PTRMEM_CST_CLASS (op));
10179 21 : *non_constant_p = true;
10180 21 : return t;
10181 : }
10182 : }
10183 :
10184 336613560 : if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
10185 : {
10186 608 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
10187 608 : && !can_convert_qual (type, op))
10188 6 : op = cplus_expand_constant (op);
10189 608 : return cp_fold_convert (type, op);
10190 : }
10191 :
10192 336612952 : if (INDIRECT_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
10193 : {
10194 576158 : if (integer_zerop (op))
10195 : {
10196 521822 : if (TYPE_REF_P (type))
10197 : {
10198 38 : if (!ctx->quiet)
10199 4 : error_at (loc, "dereferencing a null pointer");
10200 38 : *non_constant_p = true;
10201 38 : return t;
10202 : }
10203 : }
10204 54336 : else if (TYPE_PTR_P (type)
10205 54336 : && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
10206 : /* INTEGER_CST with pointer-to-method type is only used
10207 : for a virtual method in a pointer to member function.
10208 : Don't reject those. */
10209 : ;
10210 : else
10211 : {
10212 : /* This detects for example:
10213 : reinterpret_cast<void*>(sizeof 0)
10214 : */
10215 54333 : if (!ctx->quiet)
10216 15 : error_at (loc, "%<reinterpret_cast<%T>(%E)%> is not "
10217 : "a constant expression",
10218 : type, op);
10219 54333 : *non_constant_p = true;
10220 54333 : return t;
10221 : }
10222 : }
10223 :
10224 336558581 : if (INDIRECT_TYPE_P (type)
10225 179151696 : && TREE_CODE (op) == NOP_EXPR
10226 96312699 : && TREE_TYPE (op) == ptr_type_node
10227 287636 : && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR
10228 285299 : && VAR_P (TREE_OPERAND (TREE_OPERAND (op, 0), 0))
10229 336792680 : && (DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10230 234099 : 0)) == heap_uninit_identifier
10231 164785 : || DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
10232 164785 : 0)) == heap_vec_uninit_identifier))
10233 : {
10234 70763 : tree var = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
10235 70763 : tree var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
10236 70763 : tree elt_type = TREE_TYPE (type);
10237 70763 : tree cookie_size = NULL_TREE;
10238 70763 : tree arg_size = NULL_TREE;
10239 70763 : if (TREE_CODE (elt_type) == RECORD_TYPE
10240 70763 : && TYPE_IDENTIFIER (elt_type) == heap_identifier)
10241 : {
10242 9 : tree fld1 = TYPE_FIELDS (elt_type);
10243 9 : tree fld2 = DECL_CHAIN (fld1);
10244 9 : elt_type = TREE_TYPE (TREE_TYPE (fld2));
10245 9 : cookie_size = TYPE_SIZE_UNIT (TREE_TYPE (fld1));
10246 : }
10247 70763 : DECL_NAME (var)
10248 70763 : = (DECL_NAME (var) == heap_uninit_identifier
10249 70763 : ? heap_identifier : heap_vec_identifier);
10250 : /* For zero sized elt_type, try to recover how many outer_nelts
10251 : it should have. */
10252 70763 : if ((cookie_size ? tree_int_cst_equal (var_size, cookie_size)
10253 70754 : : integer_zerop (var_size))
10254 89 : && !int_size_in_bytes (elt_type)
10255 9 : && TREE_CODE (oldop) == CALL_EXPR
10256 70781 : && call_expr_nargs (oldop) >= 1)
10257 9 : if (tree fun = get_function_named_in_call (oldop))
10258 9 : if (cxx_replaceable_global_alloc_fn (fun)
10259 9 : && IDENTIFIER_NEW_OP_P (DECL_NAME (fun)))
10260 9 : arg_size = CALL_EXPR_ARG (oldop, 0);
10261 70763 : tree new_type
10262 70763 : = build_new_constexpr_heap_type (ctx, elt_type, cookie_size,
10263 : var_size, arg_size,
10264 : non_constant_p, overflow_p,
10265 : jump_target);
10266 70763 : if (*jump_target)
10267 : return NULL_TREE;
10268 70763 : TREE_TYPE (var) = new_type;
10269 70763 : TREE_TYPE (TREE_OPERAND (op, 0))
10270 141526 : = build_pointer_type (TREE_TYPE (var));
10271 : }
10272 :
10273 : /* This can happen for std::meta::info(^^int) where the cast has no
10274 : meaning. */
10275 336558581 : if (REFLECTION_TYPE_P (type) && REFLECT_EXPR_P (op))
10276 : {
10277 : r = op;
10278 : break;
10279 : }
10280 :
10281 336510996 : if (op == oldop && tcode != UNARY_PLUS_EXPR)
10282 : /* We didn't fold at the top so we could check for ptr-int
10283 : conversion. */
10284 27240916 : return fold (t);
10285 :
10286 309270080 : tree sop;
10287 :
10288 : /* Handle an array's bounds having been deduced after we built
10289 : the wrapping expression. */
10290 309270080 : if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
10291 : r = op;
10292 99148154 : else if (sop = tree_strip_nop_conversions (op),
10293 141692646 : sop != op && (same_type_ignoring_tlq_and_bounds_p
10294 42544492 : (type, TREE_TYPE (sop))))
10295 : r = sop;
10296 85380297 : else if (tcode == UNARY_PLUS_EXPR)
10297 0 : r = fold_convert (TREE_TYPE (t), op);
10298 : else
10299 85380297 : r = fold_build1 (tcode, type, op);
10300 :
10301 : /* Conversion of an out-of-range value has implementation-defined
10302 : behavior; the language considers it different from arithmetic
10303 : overflow, which is undefined. */
10304 309270080 : if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
10305 11873 : TREE_OVERFLOW (r) = false;
10306 : }
10307 : break;
10308 :
10309 6306 : case EXCESS_PRECISION_EXPR:
10310 6306 : {
10311 6306 : tree oldop = TREE_OPERAND (t, 0);
10312 :
10313 6306 : tree op = cxx_eval_constant_expression (ctx, oldop,
10314 : lval,
10315 : non_constant_p, overflow_p,
10316 : jump_target);
10317 6306 : if (*jump_target)
10318 : return NULL_TREE;
10319 6306 : if (*non_constant_p)
10320 : return t;
10321 6298 : r = fold_convert (TREE_TYPE (t), op);
10322 6298 : break;
10323 : }
10324 :
10325 38462 : case EMPTY_CLASS_EXPR:
10326 : /* Handle EMPTY_CLASS_EXPR produced by build_call_a by lowering
10327 : it to an appropriate CONSTRUCTOR. */
10328 38462 : return build_constructor (TREE_TYPE (t), NULL);
10329 :
10330 46144302 : case STATEMENT_LIST:
10331 46144302 : new_ctx = *ctx;
10332 46144302 : new_ctx.ctor = new_ctx.object = NULL_TREE;
10333 46144302 : return cxx_eval_statement_list (&new_ctx, t,
10334 46144300 : non_constant_p, overflow_p, jump_target);
10335 :
10336 28847984 : case BIND_EXPR:
10337 : /* Pre-emptively clear the vars declared by this BIND_EXPR from the value
10338 : map, so that when checking whether they're already destroyed later we
10339 : don't get confused by remnants of previous calls. */
10340 43252447 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
10341 14404463 : ctx->global->clear_value (decl);
10342 28847984 : r = cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
10343 : lval,
10344 : non_constant_p, overflow_p,
10345 : jump_target);
10346 43252445 : for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
10347 14404462 : destroy_value_checked (ctx, decl, non_constant_p);
10348 : break;
10349 :
10350 5876580 : case PREINCREMENT_EXPR:
10351 5876580 : case POSTINCREMENT_EXPR:
10352 5876580 : case PREDECREMENT_EXPR:
10353 5876580 : case POSTDECREMENT_EXPR:
10354 5876580 : return cxx_eval_increment_expression (ctx, t,
10355 : lval, non_constant_p, overflow_p,
10356 5876580 : jump_target);
10357 :
10358 1120 : case THROW_EXPR:
10359 1120 : if (cxx_dialect >= cxx26)
10360 793 : return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
10361 : non_constant_p, overflow_p,
10362 793 : jump_target);
10363 : /* FALLTHROUGH */
10364 335 : case LAMBDA_EXPR:
10365 335 : case NEW_EXPR:
10366 335 : case VEC_NEW_EXPR:
10367 335 : case DELETE_EXPR:
10368 335 : case VEC_DELETE_EXPR:
10369 335 : case MODOP_EXPR:
10370 : /* GCC internal stuff. */
10371 335 : case VA_ARG_EXPR:
10372 335 : case BASELINK:
10373 335 : case OFFSET_REF:
10374 335 : if (!ctx->quiet)
10375 86 : error_at (loc, "expression %qE is not a constant expression", t);
10376 335 : *non_constant_p = true;
10377 335 : break;
10378 :
10379 466095 : case OBJ_TYPE_REF:
10380 : /* Virtual function lookup. We don't need to do anything fancy. */
10381 466095 : return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t),
10382 : lval, non_constant_p, overflow_p,
10383 466095 : jump_target);
10384 :
10385 16116 : case PLACEHOLDER_EXPR:
10386 : /* Use of the value or address of the current object. */
10387 16116 : if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
10388 : {
10389 15885 : if (TREE_CODE (ctor) == CONSTRUCTOR)
10390 : return ctor;
10391 : else
10392 15585 : return cxx_eval_constant_expression (ctx, ctor, lval,
10393 : non_constant_p, overflow_p,
10394 15585 : jump_target);
10395 : }
10396 : /* A placeholder without a referent. We can get here when
10397 : checking whether NSDMIs are noexcept, or in massage_init_elt;
10398 : just say it's non-constant for now. */
10399 231 : gcc_assert (ctx->quiet);
10400 231 : *non_constant_p = true;
10401 231 : break;
10402 :
10403 3226 : case EXIT_EXPR:
10404 3226 : {
10405 3226 : tree cond = TREE_OPERAND (t, 0);
10406 3226 : cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
10407 : non_constant_p, overflow_p,
10408 : jump_target);
10409 3226 : if (*jump_target)
10410 : return NULL_TREE;
10411 3226 : VERIFY_CONSTANT (cond);
10412 3226 : if (integer_nonzerop (cond))
10413 1555 : *jump_target = t;
10414 : }
10415 : break;
10416 :
10417 39 : case GOTO_EXPR:
10418 39 : if (breaks (&TREE_OPERAND (t, 0))
10419 39 : || continues (&TREE_OPERAND (t, 0)))
10420 18 : *jump_target = TREE_OPERAND (t, 0);
10421 : else
10422 : {
10423 21 : if (!ctx->quiet)
10424 1 : error_at (loc, "%<goto%> is not a constant expression");
10425 21 : *non_constant_p = true;
10426 : }
10427 : break;
10428 :
10429 5617336 : case LOOP_EXPR:
10430 5617336 : case DO_STMT:
10431 5617336 : case WHILE_STMT:
10432 5617336 : case FOR_STMT:
10433 5617336 : cxx_eval_loop_expr (ctx, t,
10434 : non_constant_p, overflow_p, jump_target);
10435 5617336 : break;
10436 :
10437 34548 : case SWITCH_EXPR:
10438 34548 : case SWITCH_STMT:
10439 34548 : cxx_eval_switch_expr (ctx, t,
10440 : non_constant_p, overflow_p, jump_target);
10441 34548 : break;
10442 :
10443 120 : case REQUIRES_EXPR:
10444 : /* It's possible to get a requires-expression in a constant
10445 : expression. For example:
10446 :
10447 : template<typename T> concept bool C() {
10448 : return requires (T t) { t; };
10449 : }
10450 :
10451 : template<typename T> requires !C<T>() void f(T);
10452 :
10453 : Normalization leaves f with the associated constraint
10454 : '!requires (T t) { ... }' which is not transformed into
10455 : a constraint. */
10456 120 : if (!processing_template_decl)
10457 120 : return evaluate_requires_expr (t);
10458 : else
10459 0 : *non_constant_p = true;
10460 0 : return t;
10461 :
10462 16175 : case ANNOTATE_EXPR:
10463 16175 : r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
10464 : lval,
10465 : non_constant_p, overflow_p,
10466 : jump_target);
10467 16175 : break;
10468 :
10469 13705 : case USING_STMT:
10470 13705 : r = void_node;
10471 13705 : break;
10472 :
10473 12 : case ASSERTION_STMT:
10474 12 : case PRECONDITION_STMT:
10475 12 : case POSTCONDITION_STMT:
10476 12 : {
10477 12 : r = void_node;
10478 : /* Only record the first fail, and do not go further is the semantic
10479 : is 'ignore'. */
10480 12 : if (*non_constant_p || ctx->global->contract_statement
10481 24 : || contract_ignored_p (t))
10482 : break;
10483 :
10484 12 : tree cond = CONTRACT_CONDITION (t);
10485 12 : if (!potential_rvalue_constant_expression (cond))
10486 : {
10487 4 : ctx->global->contract_statement = t;
10488 4 : ctx->global->contract_condition_non_const = true;
10489 4 : break;
10490 : }
10491 :
10492 : /* We need to evaluate and stash the result of this here, since whether
10493 : it needs to be reported (and how) depends on whether the containing
10494 : expression is otherwise const. */
10495 8 : bool ctrct_non_const_p = false;
10496 8 : bool ctrct_overflow_p = false;
10497 8 : tree jmp_target = NULL_TREE;
10498 8 : constexpr_ctx new_ctx = *ctx;
10499 8 : new_ctx.quiet = true;
10500 : /* Avoid modification of existing values. */
10501 8 : modifiable_tracker ms (new_ctx.global);
10502 8 : tree eval =
10503 8 : cxx_eval_constant_expression (&new_ctx, cond, vc_prvalue,
10504 : &ctrct_non_const_p,
10505 : &ctrct_overflow_p, &jmp_target);
10506 : /* Not a constant. */
10507 8 : if (ctrct_non_const_p)
10508 : {
10509 0 : ctx->global->contract_statement = t;
10510 0 : ctx->global->contract_condition_non_const = true;
10511 0 : break;
10512 : }
10513 : /* Constant, but check failed. */
10514 8 : if (integer_zerop (eval))
10515 8 : ctx->global->contract_statement = t;
10516 8 : }
10517 8 : break;
10518 :
10519 3582238 : case TEMPLATE_ID_EXPR:
10520 3582238 : {
10521 : /* We can evaluate template-id that refers to a concept only if
10522 : the template arguments are non-dependent. */
10523 3582238 : gcc_assert (concept_check_p (t));
10524 :
10525 3582238 : if (!value_dependent_expression_p (t)
10526 3582238 : && !uid_sensitive_constexpr_evaluation_p ())
10527 3581804 : r = evaluate_concept_check (t);
10528 : else
10529 434 : *non_constant_p = true;
10530 :
10531 : break;
10532 : }
10533 :
10534 51 : case ASM_EXPR:
10535 51 : if (!ctx->quiet)
10536 29 : inline_asm_in_constexpr_error (loc, /*constexpr_fundef_p*/false);
10537 51 : *non_constant_p = true;
10538 51 : return t;
10539 :
10540 1238 : case BIT_CAST_EXPR:
10541 1238 : if (lval)
10542 : {
10543 0 : if (!ctx->quiet)
10544 0 : error_at (EXPR_LOCATION (t),
10545 : "address of a call to %qs is not a constant expression",
10546 : "__builtin_bit_cast");
10547 0 : *non_constant_p = true;
10548 0 : return t;
10549 : }
10550 1238 : r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p, jump_target);
10551 1238 : break;
10552 :
10553 0 : case OMP_PARALLEL:
10554 0 : case OMP_TASK:
10555 0 : case OMP_FOR:
10556 0 : case OMP_SIMD:
10557 0 : case OMP_DISTRIBUTE:
10558 0 : case OMP_TASKLOOP:
10559 0 : case OMP_LOOP:
10560 0 : case OMP_TEAMS:
10561 0 : case OMP_TARGET_DATA:
10562 0 : case OMP_TARGET:
10563 0 : case OMP_SECTIONS:
10564 0 : case OMP_ORDERED:
10565 0 : case OMP_CRITICAL:
10566 0 : case OMP_SINGLE:
10567 0 : case OMP_SCAN:
10568 0 : case OMP_SCOPE:
10569 0 : case OMP_SECTION:
10570 0 : case OMP_STRUCTURED_BLOCK:
10571 0 : case OMP_MASTER:
10572 0 : case OMP_MASKED:
10573 0 : case OMP_TASKGROUP:
10574 0 : case OMP_TARGET_UPDATE:
10575 0 : case OMP_TARGET_ENTER_DATA:
10576 0 : case OMP_TARGET_EXIT_DATA:
10577 0 : case OMP_ATOMIC:
10578 0 : case OMP_ATOMIC_READ:
10579 0 : case OMP_ATOMIC_CAPTURE_OLD:
10580 0 : case OMP_ATOMIC_CAPTURE_NEW:
10581 0 : case OMP_DEPOBJ:
10582 0 : case OACC_PARALLEL:
10583 0 : case OACC_KERNELS:
10584 0 : case OACC_SERIAL:
10585 0 : case OACC_DATA:
10586 0 : case OACC_HOST_DATA:
10587 0 : case OACC_LOOP:
10588 0 : case OACC_CACHE:
10589 0 : case OACC_DECLARE:
10590 0 : case OACC_ENTER_DATA:
10591 0 : case OACC_EXIT_DATA:
10592 0 : case OACC_UPDATE:
10593 0 : if (!ctx->quiet)
10594 0 : error_at (EXPR_LOCATION (t),
10595 : "statement is not a constant expression");
10596 0 : *non_constant_p = true;
10597 0 : break;
10598 :
10599 0 : default:
10600 0 : if (STATEMENT_CODE_P (TREE_CODE (t)))
10601 : {
10602 : /* This function doesn't know how to deal with pre-genericize
10603 : statements; this can only happen with statement-expressions,
10604 : so for now just fail. */
10605 0 : if (!ctx->quiet)
10606 0 : error_at (EXPR_LOCATION (t),
10607 : "statement is not a constant expression");
10608 : }
10609 0 : else if (flag_checking)
10610 0 : internal_error ("unexpected expression %qE of kind %s", t,
10611 : get_tree_code_name (TREE_CODE (t)));
10612 0 : *non_constant_p = true;
10613 0 : break;
10614 : }
10615 :
10616 1786261788 : if (r == error_mark_node)
10617 30237126 : *non_constant_p = true;
10618 :
10619 102015816 : if (r == void_node && lval != vc_discard && !*jump_target
10620 1786265322 : && !VOID_TYPE_P (TREE_TYPE (t)))
10621 : {
10622 : /* For diagnostic quality we should have handled this sooner, where we
10623 : can be more specific about the out-of-lifetime object. But here we
10624 : can still be correct. */
10625 1 : gcc_checking_assert (false);
10626 : if (!ctx->quiet)
10627 : error_at (EXPR_LOCATION (t),
10628 : "%qE accesses an object outside its lifetime", t);
10629 : *non_constant_p = true;
10630 : }
10631 :
10632 1786261787 : if (*non_constant_p)
10633 546709600 : return t;
10634 : else
10635 : return r;
10636 : }
10637 :
10638 : /* P0859: A function is needed for constant evaluation if it is a constexpr
10639 : function that is named by an expression ([basic.def.odr]) that is
10640 : potentially constant evaluated.
10641 :
10642 : So we need to instantiate any constexpr functions mentioned by the
10643 : expression even if the definition isn't needed for evaluating the
10644 : expression. */
10645 :
10646 : static tree
10647 634209939 : instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
10648 : {
10649 634209939 : if (TREE_CODE (*tp) == FUNCTION_DECL
10650 12991465 : && DECL_DECLARED_CONSTEXPR_P (*tp)
10651 12870114 : && !DECL_INITIAL (*tp)
10652 3284955 : && !trivial_fn_p (*tp)
10653 3284935 : && (DECL_TEMPLOID_INSTANTIATION (*tp) || DECL_DEFAULTED_FN (*tp))
10654 634209939 : && !uid_sensitive_constexpr_evaluation_p ())
10655 : {
10656 3271143 : ++function_depth;
10657 3271143 : if (DECL_TEMPLOID_INSTANTIATION (*tp))
10658 3271135 : instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
10659 : else
10660 8 : synthesize_method (*tp);
10661 3271143 : --function_depth;
10662 : }
10663 630938796 : else if (TREE_CODE (*tp) == CALL_EXPR
10664 618078909 : || TREE_CODE (*tp) == AGGR_INIT_EXPR)
10665 : {
10666 13061010 : if (EXPR_HAS_LOCATION (*tp))
10667 13057789 : input_location = EXPR_LOCATION (*tp);
10668 : }
10669 :
10670 634209939 : if (!EXPR_P (*tp))
10671 348011680 : *walk_subtrees = 0;
10672 :
10673 634209939 : return NULL_TREE;
10674 : }
10675 :
10676 : static void
10677 296517445 : instantiate_constexpr_fns (tree t)
10678 : {
10679 296517445 : location_t loc = input_location;
10680 296517445 : cp_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
10681 296517445 : input_location = loc;
10682 296517445 : }
10683 :
10684 : /* Look for heap variables in the expression *TP. */
10685 :
10686 : static tree
10687 609603 : find_heap_var_refs (tree *tp, int *walk_subtrees, void */*data*/)
10688 : {
10689 609603 : if (VAR_P (*tp)
10690 609603 : && (DECL_NAME (*tp) == heap_uninit_identifier
10691 6782 : || DECL_NAME (*tp) == heap_identifier
10692 3504 : || DECL_NAME (*tp) == heap_vec_uninit_identifier
10693 1673 : || DECL_NAME (*tp) == heap_vec_identifier
10694 551 : || DECL_NAME (*tp) == heap_deleted_identifier))
10695 : return *tp;
10696 :
10697 414022 : if (TYPE_P (*tp))
10698 71 : *walk_subtrees = 0;
10699 : return NULL_TREE;
10700 : }
10701 :
10702 : /* Find immediate function decls in *TP if any. */
10703 :
10704 : static tree
10705 644768625 : find_immediate_fndecl (tree *tp, int *walk_subtrees, void */*data*/)
10706 : {
10707 649705324 : if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (*tp))
10708 : return *tp;
10709 644763875 : if (TREE_CODE (*tp) == PTRMEM_CST
10710 55224 : && TREE_CODE (PTRMEM_CST_MEMBER (*tp)) == FUNCTION_DECL
10711 644818334 : && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (*tp)))
10712 : return PTRMEM_CST_MEMBER (*tp);
10713 644763770 : if (REFLECT_EXPR_P (*tp))
10714 48534 : *walk_subtrees = 0;
10715 : return NULL_TREE;
10716 : }
10717 :
10718 : /* T has TREE_CONSTANT set but has been deemed not a valid C++ constant
10719 : expression. Return a version of T that has TREE_CONSTANT cleared. */
10720 :
10721 : static tree
10722 138806 : mark_non_constant (tree t)
10723 : {
10724 138806 : gcc_checking_assert (TREE_CONSTANT (t));
10725 :
10726 : /* This isn't actually constant, so unset TREE_CONSTANT.
10727 : Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
10728 : it to be set if it is invariant address, even when it is not
10729 : a valid C++ constant expression. Wrap it with a NOP_EXPR
10730 : instead. */
10731 138806 : if (EXPR_P (t) && TREE_CODE (t) != ADDR_EXPR)
10732 137205 : t = copy_node (t);
10733 1601 : else if (TREE_CODE (t) == CONSTRUCTOR)
10734 235 : t = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (t), t);
10735 : else
10736 1366 : t = build_nop (TREE_TYPE (t), t);
10737 138806 : TREE_CONSTANT (t) = false;
10738 138806 : return t;
10739 : }
10740 :
10741 : /* If we have a successful constant evaluation, now check whether there is
10742 : a failed or non-constant contract that would invalidate this. */
10743 :
10744 : static bool
10745 601741100 : check_for_failed_contracts (constexpr_ctx *ctx)
10746 : {
10747 601741100 : constexpr_global_ctx *const global_ctx = ctx->global;
10748 601741100 : if (!flag_contracts || !global_ctx->contract_statement)
10749 : return false;
10750 :
10751 12 : location_t loc = EXPR_LOCATION (global_ctx->contract_statement);
10752 12 : enum diagnostics::kind kind;
10753 12 : bool error = false;
10754 : /* [intro.compliance.general]/2.3.4. */
10755 : /* [basic.contract.eval]/8. */
10756 12 : if (ctx->manifestly_const_eval != mce_true)
10757 : {
10758 : /* When !MCE, silently return not constant. */
10759 : return true;
10760 : }
10761 12 : else if (contract_terminating_p (global_ctx->contract_statement))
10762 : {
10763 : kind = diagnostics::kind::error;
10764 : error = true;
10765 : }
10766 : else
10767 4 : kind = diagnostics::kind::warning;
10768 :
10769 : /* [basic.contract.eval]/7.3 */
10770 12 : if (global_ctx->contract_condition_non_const)
10771 : {
10772 4 : emit_diagnostic (kind, loc, 0, "contract condition is not constant");
10773 4 : return error;
10774 : }
10775 :
10776 : /* Otherwise, the evaluation was const, but determined to be false. */
10777 8 : emit_diagnostic (kind, loc, 0,
10778 : "contract predicate is false in constant expression");
10779 8 : return error;
10780 : }
10781 :
10782 : /* ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
10783 : STRICT has the same sense as for constant_value_1: true if we only allow
10784 : conforming C++ constant expressions, or false if we want a constant value
10785 : even if it doesn't conform.
10786 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
10787 : per P0595 even when ALLOW_NON_CONSTANT is true.
10788 : CONSTEXPR_DTOR is true when evaluating the dtor of a constexpr variable.
10789 : OBJECT must be non-NULL in that case. */
10790 :
10791 : static tree
10792 613234046 : cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
10793 : bool strict = true,
10794 : mce_value manifestly_const_eval = mce_unknown,
10795 : bool constexpr_dtor = false,
10796 : tree object = NULL_TREE)
10797 : {
10798 613234046 : auto_timevar time (TV_CONSTEXPR);
10799 :
10800 613234046 : bool non_constant_p = false;
10801 613234046 : bool overflow_p = false;
10802 :
10803 613234046 : if (BRACE_ENCLOSED_INITIALIZER_P (t))
10804 : {
10805 0 : gcc_checking_assert (allow_non_constant);
10806 : return t;
10807 : }
10808 :
10809 613234046 : constexpr_global_ctx global_ctx;
10810 613234046 : constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
10811 : allow_non_constant, strict,
10812 613234046 : !allow_non_constant ? mce_true : manifestly_const_eval };
10813 :
10814 : /* Turn off -frounding-math for manifestly constant evaluation. */
10815 613234046 : warning_sentinel rm (flag_rounding_math,
10816 613234046 : ctx.manifestly_const_eval == mce_true);
10817 613234046 : tree type = (object
10818 613234046 : ? cv_unqualified (TREE_TYPE (object))
10819 543377933 : : initialized_type (t));
10820 613234046 : tree r = t;
10821 613234046 : bool is_consteval = false;
10822 613234046 : if (VOID_TYPE_P (type))
10823 : {
10824 11486593 : if (!constexpr_dtor)
10825 : {
10826 11486593 : if (cxx_dialect < cxx20)
10827 : return t;
10828 : /* We could have a COMPOUND_EXPR here coming from
10829 : keep_unused_object_arg. */
10830 11475622 : tree x = extract_call_expr (t);
10831 11475622 : if (x == NULL_TREE || x == error_mark_node)
10832 : return t;
10833 : /* Calls to immediate functions returning void need to be
10834 : evaluated. */
10835 11475582 : tree fndecl = cp_get_callee_fndecl_nofold (x);
10836 22951164 : if (fndecl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (fndecl))
10837 : return t;
10838 : else
10839 598 : is_consteval = true;
10840 598 : tree lam;
10841 598 : if (manifestly_const_eval == mce_true
10842 828 : && LAMBDA_FUNCTION_P (fndecl)
10843 224 : && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fndecl)))
10844 822 : && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
10845 214 : global_ctx.consteval_block = fndecl;
10846 : }
10847 : }
10848 601747453 : else if (cxx_dialect >= cxx20
10849 593580711 : && (TREE_CODE (t) == CALL_EXPR
10850 501760785 : || TREE_CODE (t) == AGGR_INIT_EXPR
10851 492933517 : || TREE_CODE (t) == TARGET_EXPR))
10852 : {
10853 106446571 : tree x = t;
10854 106446571 : if (TREE_CODE (x) == TARGET_EXPR)
10855 5799377 : x = TARGET_EXPR_INITIAL (x);
10856 106446571 : tree fndecl = cp_get_callee_fndecl_nofold (x);
10857 209894180 : if (fndecl && DECL_IMMEDIATE_FUNCTION_P (fndecl))
10858 : is_consteval = true;
10859 : /* Don't try to evaluate a std::vector constructor taking an integer, it
10860 : will fail in the 'if (heap_var)' block below after doing all the work
10861 : (c++/113835). This will need adjustment if P3554 is accepted. Note
10862 : that evaluation of e.g. the vector default constructor can succeed, so
10863 : we don't shortcut all vector constructors. */
10864 206895218 : if (fndecl && DECL_CONSTRUCTOR_P (fndecl) && allow_non_constant
10865 17253337 : && is_std_class (type, "vector") && call_expr_nargs (x) > 1
10866 106468381 : && TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE)
10867 : return t;
10868 : }
10869 601746640 : if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
10870 : {
10871 : /* In C++14 an NSDMI can participate in aggregate initialization,
10872 : and can refer to the address of the object being initialized, so
10873 : we need to pass in the relevant VAR_DECL if we want to do the
10874 : evaluation in a single pass. The evaluation will dynamically
10875 : update ctx.values for the VAR_DECL. We use the same strategy
10876 : for C++11 constexpr constructors that refer to the object being
10877 : initialized. */
10878 66131697 : if (constexpr_dtor)
10879 : {
10880 155 : gcc_assert (object && VAR_P (object));
10881 155 : gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
10882 155 : gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
10883 155 : if (error_operand_p (DECL_INITIAL (object)))
10884 : return t;
10885 143 : ctx.ctor = unshare_expr (DECL_INITIAL (object));
10886 143 : TREE_READONLY (ctx.ctor) = false;
10887 : /* Temporarily force decl_really_constant_value to return false
10888 : for it, we want to use ctx.ctor for the current value instead. */
10889 143 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = false;
10890 : }
10891 : else
10892 : {
10893 66131542 : ctx.ctor = build_constructor (type, NULL);
10894 66131542 : CONSTRUCTOR_NO_CLEARING (ctx.ctor) = true;
10895 : }
10896 66131685 : if (!object)
10897 : {
10898 23381234 : if (TREE_CODE (t) == CALL_EXPR)
10899 : {
10900 : /* If T is calling a constructor to initialize an object, reframe
10901 : it as an AGGR_INIT_EXPR to avoid trying to modify an object
10902 : from outside the constant evaluation, which will fail even if
10903 : the value is actually constant (is_constant_evaluated3.C). */
10904 11121423 : tree fn = cp_get_callee_fndecl_nofold (t);
10905 22242750 : if (fn && DECL_CONSTRUCTOR_P (fn))
10906 : {
10907 5049030 : object = CALL_EXPR_ARG (t, 0);
10908 5049030 : object = build_fold_indirect_ref (object);
10909 5049030 : r = build_aggr_init_expr (type, r);
10910 : }
10911 : }
10912 12259811 : else if (TREE_CODE (t) == TARGET_EXPR)
10913 5695809 : object = TARGET_EXPR_SLOT (t);
10914 6564002 : else if (TREE_CODE (t) == AGGR_INIT_EXPR)
10915 324095 : object = AGGR_INIT_EXPR_SLOT (t);
10916 : }
10917 66131685 : ctx.object = object;
10918 66131685 : if (object)
10919 53819385 : gcc_assert (same_type_ignoring_top_level_qualifiers_p
10920 : (type, TREE_TYPE (object)));
10921 53819385 : if (object && DECL_P (object))
10922 48437195 : global_ctx.put_value (object, ctx.ctor);
10923 66131685 : if (TREE_CODE (r) == TARGET_EXPR)
10924 : /* Avoid creating another CONSTRUCTOR when we expand the
10925 : TARGET_EXPR. */
10926 5835250 : r = TARGET_EXPR_INITIAL (r);
10927 : }
10928 :
10929 : /* uid_sensitive_constexpr_evaluation_value restricts warning-dependent
10930 : constexpr evaluation to avoid unnecessary template instantiation, and is
10931 : always done with mce_unknown. But due to gaps in the restriction logic
10932 : we may still end up taking an evaluation path that in turn requires
10933 : manifestly constant evaluation, and such evaluation must not be
10934 : restricted since it likely has semantic consequences.
10935 : TODO: Remove/replace the mechanism in GCC 17. */
10936 601746628 : auto uids = make_temp_override (uid_sensitive_constexpr_evaluation_value);
10937 601746628 : if (ctx.manifestly_const_eval == mce_true)
10938 296517445 : uid_sensitive_constexpr_evaluation_value = false;
10939 :
10940 601746628 : auto_vec<tree, 16> cleanups;
10941 601746628 : global_ctx.cleanups = &cleanups;
10942 :
10943 601746628 : if (manifestly_const_eval == mce_true)
10944 296517445 : instantiate_constexpr_fns (r);
10945 601746628 : tree jmp_target = NULL_TREE;
10946 601746628 : r = cxx_eval_constant_expression (&ctx, r, vc_prvalue,
10947 : &non_constant_p, &overflow_p,
10948 : &jmp_target);
10949 601744601 : if (throws (&jmp_target) && !non_constant_p)
10950 : {
10951 671 : if (!ctx.quiet)
10952 188 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
10953 671 : non_constant_p = true;
10954 671 : jmp_target = NULL_TREE;
10955 671 : r = t;
10956 : }
10957 601743259 : else if (!non_constant_p && jmp_target)
10958 : {
10959 24 : non_constant_p = true;
10960 24 : if (!ctx.quiet)
10961 : {
10962 3 : if (breaks (&jmp_target))
10963 3 : error ("%<break%> outside of a loop or %<switch%>");
10964 0 : else if (continues (&jmp_target))
10965 0 : error ("%<continue%> outside of a loop");
10966 0 : else if (returns (&jmp_target))
10967 0 : error ("%<return%> in a statement expression");
10968 : else
10969 0 : gcc_unreachable ();
10970 : }
10971 24 : r = t;
10972 : }
10973 :
10974 : /* If we got a non-simple TARGET_EXPR, the initializer was a sequence
10975 : of statements, and the result ought to be stored in ctx.ctor. */
10976 601743930 : if (r == void_node && !constexpr_dtor && ctx.ctor)
10977 0 : r = ctx.ctor;
10978 :
10979 601743930 : unsigned int i;
10980 601743930 : tree cleanup;
10981 601743930 : jmp_target = NULL_TREE;
10982 : /* Evaluate the cleanups. */
10983 1203610498 : FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
10984 122638 : if (cleanup == NULL_TREE)
10985 : /* NULL_TREE cleanup is a marker that before it is
10986 : CLEANUP_EH_ONLY cleanup. Skip the cleanup before it. */
10987 23 : --i;
10988 : else
10989 122615 : cxx_eval_constant_expression (&ctx, cleanup, vc_discard,
10990 : &non_constant_p, &overflow_p,
10991 : &jmp_target);
10992 601743930 : if (throws (&jmp_target) && !non_constant_p)
10993 : {
10994 0 : if (!ctx.quiet)
10995 0 : diagnose_uncaught_exception (input_location, &ctx, jmp_target);
10996 0 : non_constant_p = true;
10997 0 : r = t;
10998 : }
10999 :
11000 : /* Mutable logic is a bit tricky: we want to allow initialization of
11001 : constexpr variables with mutable members, but we can't copy those
11002 : members to another constexpr variable. */
11003 601743930 : if (!non_constant_p
11004 433617204 : && TREE_CODE (r) == CONSTRUCTOR
11005 623162406 : && CONSTRUCTOR_MUTABLE_POISON (r))
11006 : {
11007 91 : if (!allow_non_constant)
11008 6 : error ("%qE is not a constant expression because it refers to "
11009 : "mutable subobjects of %qT", t, type);
11010 91 : non_constant_p = true;
11011 : }
11012 :
11013 433617113 : if (!non_constant_p && cxx_dialect >= cxx20
11014 1035361043 : && !global_ctx.heap_vars.is_empty ())
11015 : {
11016 200827 : tree heap_var = cp_walk_tree_without_duplicates (&r, find_heap_var_refs,
11017 : NULL);
11018 200827 : unsigned int i;
11019 200827 : if (heap_var)
11020 : {
11021 195581 : if (!allow_non_constant && !non_constant_p)
11022 : {
11023 12 : if (DECL_LANG_SPECIFIC (heap_var))
11024 2 : error ("%qE is not a constant expression because it refers to "
11025 : "exception object allocated with "
11026 : "%<__cxa_allocate_exception%>", t);
11027 : else
11028 10 : error ("%qE is not a constant expression because it refers to "
11029 : "a result of %<operator new%>", t);
11030 12 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11031 : }
11032 195581 : r = t;
11033 195581 : non_constant_p = true;
11034 : }
11035 445397 : FOR_EACH_VEC_ELT (global_ctx.heap_vars, i, heap_var)
11036 : {
11037 244570 : if (DECL_NAME (heap_var) != heap_deleted_identifier)
11038 : {
11039 195668 : if (!allow_non_constant && !non_constant_p)
11040 : {
11041 16 : error ("%qE is not a constant expression because allocated "
11042 : "storage has not been deallocated", t);
11043 16 : inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
11044 : }
11045 195668 : r = t;
11046 195668 : non_constant_p = true;
11047 : }
11048 : }
11049 : }
11050 :
11051 : /* Check that immediate invocation does not return an expression referencing
11052 : any immediate function decls. */
11053 601743930 : if (!non_constant_p && cxx_dialect >= cxx20)
11054 855595626 : if (tree immediate_fndecl
11055 427797813 : = cp_walk_tree_without_duplicates (&r, find_immediate_fndecl,
11056 : NULL))
11057 : {
11058 4855 : if (!allow_non_constant && !non_constant_p)
11059 : {
11060 73 : if (is_consteval)
11061 36 : error_at (cp_expr_loc_or_input_loc (t),
11062 : "immediate evaluation returns address of immediate "
11063 : "function %qD", immediate_fndecl);
11064 : else
11065 56 : error_at (cp_expr_loc_or_input_loc (t),
11066 : "constant evaluation returns address of immediate "
11067 : "function %qD", immediate_fndecl);
11068 : }
11069 4855 : r = t;
11070 4855 : non_constant_p = true;
11071 : }
11072 :
11073 : /* Detect consteval-only smuggling: turning a consteval-only object
11074 : into one that is not. For instance, in
11075 : struct B { };
11076 : struct D : B { info r; };
11077 : constexpr D d{^^::};
11078 : constexpr const B &b = d; // #1
11079 : #1 is wrong because D is a consteval-only type but B is not. */
11080 601743930 : if (flag_reflection
11081 4550749 : && !non_constant_p
11082 3665520 : && object
11083 420985 : && POINTER_TYPE_P (TREE_TYPE (object))
11084 797 : && !consteval_only_p (object)
11085 601744670 : && check_out_of_consteval_use (r, /*complain=*/false))
11086 : {
11087 15 : if (!allow_non_constant)
11088 : {
11089 5 : if (TYPE_REF_P (TREE_TYPE (object)))
11090 6 : error_at (cp_expr_loc_or_input_loc (t),
11091 : "reference into an object of consteval-only type is "
11092 : "not a constant expression unless it also has "
11093 : "consteval-only type");
11094 : else
11095 2 : error_at (cp_expr_loc_or_input_loc (t),
11096 : "pointer into an object of consteval-only type is "
11097 : "not a constant expression unless it also has "
11098 : "consteval-only type");
11099 : }
11100 15 : r = t;
11101 15 : non_constant_p = true;
11102 : }
11103 :
11104 601743930 : if (!non_constant_p && !constexpr_dtor)
11105 433416442 : verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
11106 :
11107 : /* After verify_constant because reduced_constant_expression_p can unset
11108 : CONSTRUCTOR_NO_CLEARING. */
11109 601743930 : if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
11110 : {
11111 338757 : if (!allow_non_constant)
11112 41 : error ("%qE is not a constant expression because it refers to "
11113 : "an incompletely initialized variable", t);
11114 338757 : TREE_CONSTANT (r) = false;
11115 338757 : non_constant_p = true;
11116 : }
11117 :
11118 601743930 : if (non_constant_p)
11119 : /* If we saw something bad, go back to our argument. The wrapping below is
11120 : only for the cases of TREE_CONSTANT argument or overflow. */
11121 173004379 : r = t;
11122 :
11123 601743930 : if (!non_constant_p && overflow_p)
11124 215 : non_constant_p = true;
11125 :
11126 : /* Unshare the result. */
11127 601743930 : bool should_unshare = true;
11128 601743930 : if (r == t || (TREE_CODE (t) == TARGET_EXPR
11129 1545531 : && TARGET_EXPR_INITIAL (t) == r))
11130 : should_unshare = false;
11131 :
11132 601743930 : if (non_constant_p && !allow_non_constant)
11133 2830 : return error_mark_node;
11134 601741100 : else if (check_for_failed_contracts (&ctx))
11135 : {
11136 8 : if (manifestly_const_eval == mce_true)
11137 : /* If MCE, we gave a hard error and return error_mark_node. */
11138 8 : return error_mark_node;
11139 : else
11140 : {
11141 : /* Otherwise treat it as non-constant so the violation is still
11142 : detectable at run-time. */
11143 0 : gcc_checking_assert (allow_non_constant);
11144 : return t;
11145 : }
11146 : }
11147 601741092 : else if (non_constant_p && TREE_CONSTANT (r))
11148 134328 : r = mark_non_constant (r);
11149 601606764 : else if (non_constant_p)
11150 : return t;
11151 :
11152 428873656 : if (constexpr_dtor)
11153 : {
11154 125 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
11155 125 : return r;
11156 : }
11157 :
11158 : /* Check we are not trying to return the wrong type. */
11159 428873531 : if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
11160 : {
11161 : /* If so, this is not a constant expression. */
11162 151 : if (!allow_non_constant)
11163 2 : error ("%qE is not a constant expression because it initializes "
11164 2 : "a %qT rather than %qT", t, TREE_TYPE (t), type);
11165 151 : return t;
11166 : }
11167 :
11168 428873380 : if (should_unshare)
11169 257258944 : r = unshare_expr (r);
11170 :
11171 428873380 : if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
11172 : {
11173 19790959 : r = adjust_temp_type (type, r);
11174 19790959 : if (TREE_CODE (t) == TARGET_EXPR
11175 19790959 : && TARGET_EXPR_INITIAL (t) == r)
11176 : return t;
11177 18820826 : else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR
11178 2732486 : || TREE_CODE (t) == AGGR_INIT_EXPR)
11179 : /* Don't add a TARGET_EXPR if our argument didn't have one. */;
11180 645476 : else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t))
11181 481 : r = get_target_expr (r);
11182 : else
11183 : {
11184 644995 : r = get_target_expr (r, tf_warning_or_error | tf_no_cleanup);
11185 644995 : TREE_CONSTANT (r) = true;
11186 : }
11187 : }
11188 :
11189 427903247 : if (TREE_CODE (t) == TARGET_EXPR
11190 575398 : && TREE_CODE (r) == TARGET_EXPR)
11191 : {
11192 : /* Preserve this flag for potential_constant_expression, and the others
11193 : for good measure. */
11194 575300 : TARGET_EXPR_ELIDING_P (r) = TARGET_EXPR_ELIDING_P (t);
11195 575300 : TARGET_EXPR_IMPLICIT_P (r) = TARGET_EXPR_IMPLICIT_P (t);
11196 575300 : TARGET_EXPR_LIST_INIT_P (r) = TARGET_EXPR_LIST_INIT_P (t);
11197 575300 : TARGET_EXPR_DIRECT_INIT_P (r) = TARGET_EXPR_DIRECT_INIT_P (t);
11198 : }
11199 :
11200 : /* Remember the original location if that wouldn't need a wrapper. */
11201 427903247 : if (location_t loc = EXPR_LOCATION (t))
11202 202187776 : protected_set_expr_location (r, loc);
11203 :
11204 427903247 : return r;
11205 613231348 : }
11206 :
11207 : /* If T represents a constant expression returns its reduced value.
11208 : Otherwise return error_mark_node. */
11209 :
11210 : tree
11211 150199239 : cxx_constant_value (tree t, tree decl /* = NULL_TREE */,
11212 : tsubst_flags_t complain /* = tf_error */)
11213 : {
11214 150199239 : bool sfinae = !(complain & tf_error);
11215 150199239 : tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, mce_true, false, decl);
11216 150199239 : if (sfinae && !TREE_CONSTANT (r))
11217 1645 : r = error_mark_node;
11218 150199239 : return r;
11219 : }
11220 :
11221 : /* Like cxx_constant_value, but used for evaluation of constexpr destructors
11222 : of constexpr variables. The actual initializer of DECL is not modified. */
11223 :
11224 : void
11225 155 : cxx_constant_dtor (tree t, tree decl)
11226 : {
11227 155 : cxx_eval_outermost_constant_expr (t, false, true, mce_true, true, decl);
11228 155 : }
11229 :
11230 : /* Helper routine for fold_simple function. Either return simplified
11231 : expression T, otherwise NULL_TREE.
11232 : In contrast to cp_fully_fold, and to maybe_constant_value, we try to fold
11233 : even if we are within template-declaration. So be careful on call, as in
11234 : such case types can be undefined. */
11235 :
11236 : static tree
11237 184841932 : fold_simple_1 (tree t)
11238 : {
11239 184841932 : tree op1;
11240 184841932 : enum tree_code code = TREE_CODE (t);
11241 :
11242 184841932 : switch (code)
11243 : {
11244 : case INTEGER_CST:
11245 : case REAL_CST:
11246 : case VECTOR_CST:
11247 : case FIXED_CST:
11248 : case COMPLEX_CST:
11249 : return t;
11250 :
11251 1972627 : case SIZEOF_EXPR:
11252 1972627 : return fold_sizeof_expr (t);
11253 :
11254 46368386 : case ABS_EXPR:
11255 46368386 : case ABSU_EXPR:
11256 46368386 : case CONJ_EXPR:
11257 46368386 : case REALPART_EXPR:
11258 46368386 : case IMAGPART_EXPR:
11259 46368386 : case NEGATE_EXPR:
11260 46368386 : case BIT_NOT_EXPR:
11261 46368386 : case TRUTH_NOT_EXPR:
11262 46368386 : case VIEW_CONVERT_EXPR:
11263 46368386 : CASE_CONVERT:
11264 46368386 : case FLOAT_EXPR:
11265 46368386 : case FIX_TRUNC_EXPR:
11266 46368386 : case FIXED_CONVERT_EXPR:
11267 46368386 : case ADDR_SPACE_CONVERT_EXPR:
11268 :
11269 46368386 : op1 = TREE_OPERAND (t, 0);
11270 :
11271 46368386 : t = const_unop (code, TREE_TYPE (t), op1);
11272 46368386 : if (!t)
11273 : return NULL_TREE;
11274 :
11275 4032564 : if (CONVERT_EXPR_CODE_P (code)
11276 4032564 : && TREE_OVERFLOW_P (t) && !TREE_OVERFLOW_P (op1))
11277 0 : TREE_OVERFLOW (t) = false;
11278 : return t;
11279 :
11280 : default:
11281 : return NULL_TREE;
11282 : }
11283 : }
11284 :
11285 : /* If T is a simple constant expression, returns its simplified value.
11286 : Otherwise returns T. In contrast to maybe_constant_value we
11287 : simplify only few operations on constant-expressions, and we don't
11288 : try to simplify constexpressions. */
11289 :
11290 : tree
11291 185502661 : fold_simple (tree t)
11292 : {
11293 185502661 : if (processing_template_decl)
11294 : return t;
11295 :
11296 184841932 : tree r = fold_simple_1 (t);
11297 184841932 : if (r)
11298 : return r;
11299 :
11300 : return t;
11301 : }
11302 :
11303 : /* Try folding the expression T to a simple constant.
11304 : Returns that constant, otherwise returns T. */
11305 :
11306 : tree
11307 1597074 : fold_to_constant (tree t)
11308 : {
11309 1597074 : if (processing_template_decl)
11310 : return t;
11311 :
11312 1505755 : tree r = fold (t);
11313 1505755 : if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
11314 : return r;
11315 : else
11316 : return t;
11317 : }
11318 :
11319 : /* If T is a constant expression, returns its reduced value.
11320 : Otherwise, if T does not have TREE_CONSTANT set, returns T.
11321 : Otherwise, returns a version of T without TREE_CONSTANT.
11322 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
11323 : as per P0595. */
11324 :
11325 : static GTY((deletable)) hash_map<tree, tree> *cv_cache;
11326 :
11327 : tree
11328 934884099 : maybe_constant_value (tree t, tree decl /* = NULL_TREE */,
11329 : mce_value manifestly_const_eval /* = mce_unknown */)
11330 : {
11331 934884099 : tree orig_t = t;
11332 934884099 : tree r;
11333 :
11334 934884099 : if (EXPR_P (t) && manifestly_const_eval == mce_unknown)
11335 : {
11336 : /* Look up each operand in the cv_cache first to see if we've already
11337 : reduced it, and reuse that result to avoid quadratic behavior if
11338 : we're called when building up a large expression. */
11339 275337624 : int n = cp_tree_operand_length (t);
11340 275337624 : tree *ops = XALLOCAVEC (tree, n);
11341 275337624 : bool rebuild = false;
11342 778293464 : for (int i = 0; i < n; ++i)
11343 : {
11344 502955840 : ops[i] = TREE_OPERAND (t, i);
11345 1508296956 : if (tree *cached = hash_map_safe_get (cv_cache, ops[i]))
11346 33434082 : if (*cached != ops[i])
11347 : {
11348 9466850 : ops[i] = *cached;
11349 9466850 : rebuild = true;
11350 : }
11351 : }
11352 275337624 : if (rebuild)
11353 : {
11354 8031328 : t = copy_node (t);
11355 26248990 : for (int i = 0; i < n; ++i)
11356 18217662 : TREE_OPERAND (t, i) = ops[i];
11357 : }
11358 : }
11359 :
11360 934884099 : if (!is_nondependent_constant_expression (t))
11361 : {
11362 0 : if (TREE_OVERFLOW_P (t)
11363 144290685 : || (!processing_template_decl && TREE_CONSTANT (t)))
11364 4478 : t = mark_non_constant (t);
11365 144290685 : return t;
11366 : }
11367 790593414 : else if (CONSTANT_CLASS_P (t))
11368 : /* No caching or evaluation needed. */
11369 : return t;
11370 :
11371 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
11372 : but at least try folding it to a simple constant. */
11373 376454895 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
11374 515353 : return fold_to_constant (t);
11375 :
11376 356814862 : if (manifestly_const_eval != mce_unknown)
11377 : /* TODO: Extend the cache to be mce_value aware. And if we have a
11378 : previously cached mce_unknown result that's TREE_CONSTANT, it means
11379 : the reduced value is independent of mce_value and so we should
11380 : be able to reuse it in the mce_true/false case. */
11381 202105256 : return cxx_eval_outermost_constant_expr (t, true, true,
11382 202102558 : manifestly_const_eval, false, decl);
11383 :
11384 173834286 : if (cv_cache == NULL)
11385 138255 : cv_cache = hash_map<tree, tree>::create_ggc (101);
11386 173834286 : if (tree *cached = cv_cache->get (t))
11387 : {
11388 15579806 : r = *cached;
11389 15579806 : if (r != t)
11390 : {
11391 : /* Clear processing_template_decl for sake of break_out_target_exprs;
11392 : entries in the cv_cache are non-templated. */
11393 4479906 : processing_template_decl_sentinel ptds;
11394 :
11395 4479906 : r = break_out_target_exprs (r, /*clear_loc*/true);
11396 4479906 : protected_set_expr_location (r, EXPR_LOCATION (t));
11397 4479906 : }
11398 15579806 : return r;
11399 : }
11400 :
11401 158254480 : uid_sensitive_constexpr_evaluation_checker c;
11402 158254480 : r = cxx_eval_outermost_constant_expr (t, true, true,
11403 : manifestly_const_eval, false, decl);
11404 158254480 : gcc_checking_assert (r == t
11405 : || CONVERT_EXPR_P (t)
11406 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
11407 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
11408 : || !cp_tree_equal (r, t));
11409 158254480 : if (!c.evaluation_restricted_p ())
11410 157907234 : cv_cache->put (orig_t, r);
11411 : return r;
11412 : }
11413 :
11414 : /* Dispose of the whole CV_CACHE. */
11415 :
11416 : static void
11417 44312941 : clear_cv_cache (void)
11418 : {
11419 44312941 : if (cv_cache != NULL)
11420 44069968 : cv_cache->empty ();
11421 44312941 : }
11422 :
11423 : /* Dispose of the whole CV_CACHE and FOLD_CACHE. */
11424 :
11425 : void
11426 44312941 : clear_cv_and_fold_caches ()
11427 : {
11428 44312941 : clear_cv_cache ();
11429 44312941 : clear_fold_cache ();
11430 44312941 : }
11431 :
11432 : /* Internal function handling expressions in templates for
11433 : fold_non_dependent_expr and fold_non_dependent_init.
11434 :
11435 : If we're in a template, but T isn't value dependent, simplify
11436 : it. We're supposed to treat:
11437 :
11438 : template <typename T> void f(T[1 + 1]);
11439 : template <typename T> void f(T[2]);
11440 :
11441 : as two declarations of the same function, for example. */
11442 :
11443 : static tree
11444 29140284 : fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
11445 : bool manifestly_const_eval,
11446 : tree object)
11447 : {
11448 29140284 : gcc_assert (processing_template_decl);
11449 :
11450 29140284 : if (is_nondependent_constant_expression (t))
11451 : {
11452 15971884 : processing_template_decl_sentinel s;
11453 15971884 : t = instantiate_non_dependent_expr_internal (t, complain);
11454 :
11455 15971884 : if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t))
11456 : {
11457 0 : if (TREE_OVERFLOW_P (t))
11458 : {
11459 0 : t = build_nop (TREE_TYPE (t), t);
11460 0 : TREE_CONSTANT (t) = false;
11461 : }
11462 0 : return t;
11463 : }
11464 15971884 : else if (CONSTANT_CLASS_P (t))
11465 : /* No evaluation needed. */
11466 : return t;
11467 :
11468 : /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
11469 : but at least try folding it to a simple constant. */
11470 4158564 : if (cp_unevaluated_operand && !manifestly_const_eval)
11471 89 : return fold_to_constant (t);
11472 :
11473 4158475 : tree r = cxx_eval_outermost_constant_expr (t, true, true,
11474 : mce_value (manifestly_const_eval),
11475 : false, object);
11476 : /* cp_tree_equal looks through NOPs, so allow them. */
11477 4158475 : gcc_checking_assert (r == t
11478 : || CONVERT_EXPR_P (t)
11479 : || TREE_CODE (t) == VIEW_CONVERT_EXPR
11480 : || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
11481 : || !cp_tree_equal (r, t));
11482 4158475 : return r;
11483 15971884 : }
11484 13168400 : else if (TREE_OVERFLOW_P (t))
11485 : {
11486 0 : t = build_nop (TREE_TYPE (t), t);
11487 0 : TREE_CONSTANT (t) = false;
11488 : }
11489 :
11490 : return t;
11491 : }
11492 :
11493 : /* Like maybe_constant_value but first fully instantiate the argument.
11494 :
11495 : Note: this is equivalent to instantiate_non_dependent_expr (t, complain)
11496 : followed by maybe_constant_value but is more efficient,
11497 : because it calls instantiation_dependent_expression_p and
11498 : potential_constant_expression at most once.
11499 : The manifestly_const_eval argument is passed to maybe_constant_value.
11500 :
11501 : Callers should generally pass their active complain, or if they are in a
11502 : non-template, diagnosing context, they can use the default of
11503 : tf_warning_or_error. Callers that might be within a template context, don't
11504 : have a complain parameter, and aren't going to remember the result for long
11505 : (e.g. null_ptr_cst_p), can pass tf_none and deal with error_mark_node
11506 : appropriately. */
11507 :
11508 : tree
11509 265224953 : fold_non_dependent_expr (tree t,
11510 : tsubst_flags_t complain /* = tf_warning_or_error */,
11511 : bool manifestly_const_eval /* = false */,
11512 : tree object /* = NULL_TREE */)
11513 : {
11514 265224953 : if (t == NULL_TREE)
11515 : return NULL_TREE;
11516 :
11517 264148538 : if (processing_template_decl)
11518 28118851 : return fold_non_dependent_expr_template (t, complain,
11519 28118851 : manifestly_const_eval, object);
11520 :
11521 236029687 : return maybe_constant_value (t, object, mce_value (manifestly_const_eval));
11522 : }
11523 :
11524 : /* Like fold_non_dependent_expr, but if EXPR couldn't be folded to a constant,
11525 : return the original expression. */
11526 :
11527 : tree
11528 2275877 : maybe_fold_non_dependent_expr (tree expr,
11529 : tsubst_flags_t complain/*=tf_warning_or_error*/)
11530 : {
11531 2275877 : tree t = fold_non_dependent_expr (expr, complain);
11532 2275877 : if (t && TREE_CONSTANT (t))
11533 1056350 : return t;
11534 :
11535 : return expr;
11536 : }
11537 :
11538 : /* Like maybe_constant_init but first fully instantiate the argument. */
11539 :
11540 : tree
11541 60684986 : fold_non_dependent_init (tree t,
11542 : tsubst_flags_t complain /*=tf_warning_or_error*/,
11543 : bool manifestly_const_eval /*=false*/,
11544 : tree object /* = NULL_TREE */)
11545 : {
11546 60684986 : if (t == NULL_TREE)
11547 : return NULL_TREE;
11548 :
11549 60684986 : if (processing_template_decl)
11550 : {
11551 1021433 : t = fold_non_dependent_expr_template (t, complain,
11552 : manifestly_const_eval, object);
11553 : /* maybe_constant_init does this stripping, so do it here too. */
11554 1021433 : if (TREE_CODE (t) == TARGET_EXPR)
11555 : {
11556 934 : tree init = TARGET_EXPR_INITIAL (t);
11557 934 : if (TREE_CODE (init) == CONSTRUCTOR)
11558 1021433 : t = init;
11559 : }
11560 1021433 : return t;
11561 : }
11562 :
11563 59663553 : return maybe_constant_init (t, object, manifestly_const_eval);
11564 : }
11565 :
11566 : /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
11567 : than wrapped in a TARGET_EXPR.
11568 : ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
11569 : MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
11570 : per P0595 even when ALLOW_NON_CONSTANT is true. */
11571 :
11572 : static tree
11573 160502220 : maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
11574 : mce_value manifestly_const_eval)
11575 : {
11576 160502220 : if (!t)
11577 : return t;
11578 160502220 : if (TREE_CODE (t) == EXPR_STMT)
11579 24411 : t = TREE_OPERAND (t, 0);
11580 160502220 : if (TREE_CODE (t) == CONVERT_EXPR
11581 160502220 : && VOID_TYPE_P (TREE_TYPE (t)))
11582 79781 : t = TREE_OPERAND (t, 0);
11583 : /* If the types don't match, the INIT_EXPR is initializing a subobject of
11584 : DECL and losing that information would cause mischief later. */
11585 160502220 : if (TREE_CODE (t) == INIT_EXPR
11586 160502220 : && (!decl
11587 55386 : || same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (decl),
11588 55386 : TREE_TYPE (t))))
11589 25653 : t = TREE_OPERAND (t, 1);
11590 160502220 : if (TREE_CODE (t) == TARGET_EXPR)
11591 551537 : t = TARGET_EXPR_INITIAL (t);
11592 160502220 : if (!is_nondependent_static_init_expression (t))
11593 : /* Don't try to evaluate it. */;
11594 137798920 : else if (CONSTANT_CLASS_P (t) && TREE_CODE (t) != PTRMEM_CST)
11595 : /* No evaluation needed. PTRMEM_CST needs the immediate fn check. */;
11596 : else
11597 : {
11598 : /* [basic.start.static] allows constant-initialization of variables with
11599 : static or thread storage duration even if it isn't required, but we
11600 : shouldn't bend the rules the same way for automatic variables.
11601 :
11602 : But still enforce the requirements of constexpr/constinit.
11603 : [dcl.constinit] "If a variable declared with the constinit specifier
11604 : has dynamic initialization, the program is ill-formed, even if the
11605 : implementation would perform that initialization as a static
11606 : initialization." */
11607 44398315 : bool is_static = (decl && DECL_P (decl)
11608 114319588 : && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
11609 3344899 : bool strict = (!is_static
11610 : || (decl && DECL_P (decl)
11611 3344899 : && (DECL_DECLARED_CONSTEXPR_P (decl)
11612 1044520 : || DECL_DECLARED_CONSTINIT_P (decl))));
11613 : if (is_static)
11614 : manifestly_const_eval = mce_true;
11615 :
11616 71011763 : if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
11617 50732 : return fold_to_constant (t);
11618 :
11619 70961031 : t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
11620 : manifestly_const_eval,
11621 : false, decl);
11622 : }
11623 160451488 : if (TREE_CODE (t) == TARGET_EXPR)
11624 : {
11625 69707 : tree init = TARGET_EXPR_INITIAL (t);
11626 69707 : if (TREE_CODE (init) == CONSTRUCTOR)
11627 160502220 : t = init;
11628 : }
11629 : return t;
11630 : }
11631 :
11632 : /* Wrapper for maybe_constant_init_1 which permits non constants. */
11633 :
11634 : tree
11635 102119105 : maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
11636 : {
11637 102119105 : return maybe_constant_init_1 (t, decl, true, mce_value (manifestly_const_eval));
11638 : }
11639 :
11640 : tree
11641 58381606 : maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval)
11642 : {
11643 58381606 : return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
11644 : }
11645 :
11646 : /* Wrapper for maybe_constant_init_1 which does not permit non constants. */
11647 :
11648 : tree
11649 1509 : cxx_constant_init (tree t, tree decl)
11650 : {
11651 1509 : return maybe_constant_init_1 (t, decl, false, mce_true);
11652 : }
11653 :
11654 : /* Return true if CALL_EXPR T might throw during constant evaluation. */
11655 :
11656 : static bool
11657 255848976 : callee_might_throw (tree t)
11658 : {
11659 255848976 : if (cxx_dialect < cxx26 || !flag_exceptions)
11660 : return false;
11661 19542836 : tree callee = cp_get_callee (t);
11662 19542836 : if (callee == NULL_TREE)
11663 : return false;
11664 19508896 : tree callee_fn = cp_get_fndecl_from_callee (callee, false);
11665 19508896 : return (!flag_enforce_eh_specs
11666 19508896 : || type_dependent_expression_p (callee)
11667 17641853 : || !POINTER_TYPE_P (TREE_TYPE (callee))
11668 35900170 : || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee)))
11669 6955444 : && (callee_fn == NULL_TREE || !TREE_NOTHROW (callee_fn))));
11670 : }
11671 :
11672 : #if 0
11673 : /* FIXME see ADDR_EXPR section in potential_constant_expression_1. */
11674 : /* Return true if the object referred to by REF has automatic or thread
11675 : local storage. */
11676 :
11677 : enum { ck_ok, ck_bad, ck_unknown };
11678 : static int
11679 : check_automatic_or_tls (tree ref)
11680 : {
11681 : machine_mode mode;
11682 : poly_int64 bitsize, bitpos;
11683 : tree offset;
11684 : int volatilep = 0, unsignedp = 0;
11685 : tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
11686 : &mode, &unsignedp, &volatilep, false);
11687 : duration_kind dk;
11688 :
11689 : /* If there isn't a decl in the middle, we don't know the linkage here,
11690 : and this isn't a constant expression anyway. */
11691 : if (!DECL_P (decl))
11692 : return ck_unknown;
11693 : dk = decl_storage_duration (decl);
11694 : return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
11695 : }
11696 : #endif
11697 :
11698 : /* Data structure for passing data from potential_constant_expression_1
11699 : to check_for_return_continue via cp_walk_tree. */
11700 : struct check_for_return_continue_data {
11701 : hash_set<tree> *pset;
11702 : tree continue_stmt;
11703 : tree break_stmt;
11704 : bool could_throw;
11705 : };
11706 :
11707 : /* Helper function for potential_constant_expression_1 SWITCH_STMT handling,
11708 : called through cp_walk_tree. Return the first RETURN_EXPR found, or note
11709 : the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found.
11710 : For C++26 also note presence of possibly throwing calls. */
11711 : static tree
11712 69284701 : check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
11713 : {
11714 69284701 : tree t = *tp, s, b;
11715 69284701 : check_for_return_continue_data *d = (check_for_return_continue_data *) data;
11716 69284701 : switch (TREE_CODE (t))
11717 : {
11718 : case RETURN_EXPR:
11719 : return t;
11720 :
11721 28 : case CONTINUE_STMT:
11722 28 : if (d->continue_stmt == NULL_TREE)
11723 28 : d->continue_stmt = t;
11724 : break;
11725 :
11726 19494 : case BREAK_STMT:
11727 19494 : if (d->break_stmt == NULL_TREE)
11728 17779 : d->break_stmt = t;
11729 : break;
11730 :
11731 : #define RECUR(x) \
11732 : if (tree r = cp_walk_tree (&x, check_for_return_continue, data, \
11733 : d->pset)) \
11734 : return r
11735 :
11736 : /* For loops, walk subtrees manually, so that continue stmts found
11737 : inside of the bodies of the loops are ignored. */
11738 38875 : case DO_STMT:
11739 38875 : *walk_subtrees = 0;
11740 38875 : RECUR (DO_COND (t));
11741 38875 : s = d->continue_stmt;
11742 38875 : b = d->break_stmt;
11743 38875 : RECUR (DO_BODY (t));
11744 38875 : d->continue_stmt = s;
11745 38875 : d->break_stmt = b;
11746 38875 : break;
11747 :
11748 117 : case WHILE_STMT:
11749 117 : *walk_subtrees = 0;
11750 117 : RECUR (WHILE_COND_PREP (t));
11751 117 : RECUR (WHILE_COND (t));
11752 117 : s = d->continue_stmt;
11753 117 : b = d->break_stmt;
11754 117 : RECUR (WHILE_BODY (t));
11755 105 : d->continue_stmt = s;
11756 105 : d->break_stmt = b;
11757 105 : break;
11758 :
11759 245 : case FOR_STMT:
11760 245 : *walk_subtrees = 0;
11761 245 : RECUR (FOR_INIT_STMT (t));
11762 245 : RECUR (FOR_COND_PREP (t));
11763 245 : RECUR (FOR_COND (t));
11764 245 : RECUR (FOR_EXPR (t));
11765 245 : s = d->continue_stmt;
11766 245 : b = d->break_stmt;
11767 245 : RECUR (FOR_BODY (t));
11768 215 : d->continue_stmt = s;
11769 215 : d->break_stmt = b;
11770 215 : break;
11771 :
11772 0 : case RANGE_FOR_STMT:
11773 0 : *walk_subtrees = 0;
11774 0 : RECUR (RANGE_FOR_EXPR (t));
11775 0 : s = d->continue_stmt;
11776 0 : b = d->break_stmt;
11777 0 : RECUR (RANGE_FOR_BODY (t));
11778 0 : d->continue_stmt = s;
11779 0 : d->break_stmt = b;
11780 0 : break;
11781 :
11782 207 : case SWITCH_STMT:
11783 207 : *walk_subtrees = 0;
11784 207 : RECUR (SWITCH_STMT_COND (t));
11785 207 : b = d->break_stmt;
11786 207 : RECUR (SWITCH_STMT_BODY (t));
11787 187 : d->break_stmt = b;
11788 187 : break;
11789 : #undef RECUR
11790 :
11791 : case STATEMENT_LIST:
11792 : case CONSTRUCTOR:
11793 : break;
11794 :
11795 3911774 : case AGGR_INIT_EXPR:
11796 3911774 : case CALL_EXPR:
11797 : /* In C++26 a function could throw. */
11798 3911774 : if (callee_might_throw (t))
11799 51372 : d->could_throw = true;
11800 : break;
11801 :
11802 63276959 : default:
11803 63276959 : if (!EXPR_P (t))
11804 17910486 : *walk_subtrees = 0;
11805 : break;
11806 : }
11807 :
11808 : return NULL_TREE;
11809 : }
11810 :
11811 : /* Return true if T denotes a potentially constant expression. Issue
11812 : diagnostic as appropriate under control of FLAGS. If WANT_RVAL is true,
11813 : an lvalue-rvalue conversion is implied. If NOW is true, we want to
11814 : consider the expression in the current context, independent of constexpr
11815 : substitution. If FUNDEF_P is true, we're checking a constexpr function body
11816 : and hard errors should not be reported by constexpr_error.
11817 :
11818 : C++0x [expr.const] used to say
11819 :
11820 : 6 An expression is a potential constant expression if it is
11821 : a constant expression where all occurrences of function
11822 : parameters are replaced by arbitrary constant expressions
11823 : of the appropriate type.
11824 :
11825 : 2 A conditional expression is a constant expression unless it
11826 : involves one of the following as a potentially evaluated
11827 : subexpression (3.2), but subexpressions of logical AND (5.14),
11828 : logical OR (5.15), and conditional (5.16) operations that are
11829 : not evaluated are not considered. */
11830 :
11831 : static bool
11832 5291255398 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
11833 : bool fundef_p, tsubst_flags_t flags,
11834 : tree *jump_target)
11835 : {
11836 : #define RECUR(T,RV) \
11837 : potential_constant_expression_1 ((T), (RV), strict, now, fundef_p, flags, \
11838 : jump_target)
11839 :
11840 5291255398 : enum { any = false, rval = true };
11841 5291255398 : int i;
11842 5291255398 : tree tmp;
11843 :
11844 5291255398 : if (t == error_mark_node)
11845 : return false;
11846 5291244095 : if (t == NULL_TREE)
11847 : return true;
11848 5280250150 : location_t loc = cp_expr_loc_or_input_loc (t);
11849 5280250150 : iloc_sentinel ils = loc;
11850 :
11851 5280250150 : if (*jump_target)
11852 : /* If we are jumping, ignore everything. This is simpler than the
11853 : cxx_eval_constant_expression handling because we only need to be
11854 : conservatively correct, and we don't necessarily have a constant value
11855 : available, so we don't bother with switch tracking. */
11856 : return true;
11857 :
11858 1813459 : if (TREE_THIS_VOLATILE (t) && want_rval
11859 1252870 : && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))
11860 5271037046 : && !NULLPTR_TYPE_P (TREE_TYPE (t)))
11861 : {
11862 78335 : if (TREE_CLOBBER_P (t))
11863 : {
11864 : /* We should have caught any clobbers in INIT/MODIFY_EXPR. */
11865 0 : gcc_checking_assert (false);
11866 : return true;
11867 : }
11868 :
11869 78335 : if (flags & tf_error)
11870 22 : constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of "
11871 : "a volatile lvalue %qE with type %qT", t,
11872 22 : TREE_TYPE (t));
11873 78335 : return false;
11874 : }
11875 5270880350 : if (CONSTANT_CLASS_P (t))
11876 : return true;
11877 3942784493 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
11878 3942784493 : && TREE_TYPE (t) == error_mark_node)
11879 : return false;
11880 :
11881 3942784456 : switch (TREE_CODE (t))
11882 : {
11883 : case FUNCTION_DECL:
11884 : case BASELINK:
11885 : case TEMPLATE_DECL:
11886 : case OVERLOAD:
11887 : case TEMPLATE_ID_EXPR:
11888 : case LABEL_DECL:
11889 : case CASE_LABEL_EXPR:
11890 : case PREDICT_EXPR:
11891 : case CONST_DECL:
11892 : case SIZEOF_EXPR:
11893 : case ALIGNOF_EXPR:
11894 : case OFFSETOF_EXPR:
11895 : case NOEXCEPT_EXPR:
11896 : case TEMPLATE_PARM_INDEX:
11897 : case TRAIT_EXPR:
11898 : case IDENTIFIER_NODE:
11899 : case USERDEF_LITERAL:
11900 : /* We can see a FIELD_DECL in a pointer-to-member expression. */
11901 : case FIELD_DECL:
11902 : case RESULT_DECL:
11903 : case USING_DECL:
11904 : case USING_STMT:
11905 : case PLACEHOLDER_EXPR:
11906 : case REQUIRES_EXPR:
11907 : case STATIC_ASSERT:
11908 : case DEBUG_BEGIN_STMT:
11909 : case REFLECT_EXPR:
11910 : return true;
11911 :
11912 26324701 : case RETURN_EXPR:
11913 26324701 : if (!RECUR (TREE_OPERAND (t, 0), any))
11914 : return false;
11915 : /* FALLTHROUGH */
11916 :
11917 25985968 : case BREAK_STMT:
11918 25985968 : case CONTINUE_STMT:
11919 25985968 : *jump_target = t;
11920 25985968 : return true;
11921 :
11922 403491330 : case PARM_DECL:
11923 403491330 : if (now && want_rval)
11924 : {
11925 95706794 : tree type = TREE_TYPE (t);
11926 95706794 : if (dependent_type_p (type)
11927 68590534 : || !COMPLETE_TYPE_P (processing_template_decl
11928 : ? type : complete_type (type))
11929 164297328 : || is_really_empty_class (type, /*ignore_vptr*/false))
11930 : /* An empty class has no data to read. */
11931 27116776 : return true;
11932 68590018 : if (flags & tf_error)
11933 17 : constexpr_error (input_location, fundef_p,
11934 : "%qE is not a constant expression", t);
11935 68590018 : return false;
11936 : }
11937 : return true;
11938 :
11939 314689469 : case AGGR_INIT_EXPR:
11940 314689469 : case CALL_EXPR:
11941 : /* -- an invocation of a function other than a constexpr function
11942 : or a constexpr constructor. */
11943 314689469 : {
11944 314689469 : tree fun = get_function_named_in_call (t);
11945 314689469 : const int nargs = call_expr_nargs (t);
11946 314689469 : i = 0;
11947 :
11948 314689469 : if (fun == NULL_TREE)
11949 : {
11950 : /* Reset to allow the function to continue past the end
11951 : of the block below. Otherwise return early. */
11952 389239 : bool bail = true;
11953 :
11954 389239 : if (TREE_CODE (t) == CALL_EXPR
11955 389239 : && CALL_EXPR_FN (t) == NULL_TREE)
11956 389239 : switch (CALL_EXPR_IFN (t))
11957 : {
11958 : /* These should be ignored, they are optimized away from
11959 : constexpr functions. */
11960 : case IFN_UBSAN_NULL:
11961 : case IFN_UBSAN_BOUNDS:
11962 : case IFN_UBSAN_VPTR:
11963 : case IFN_FALLTHROUGH:
11964 : case IFN_ASSUME:
11965 : return true;
11966 :
11967 : case IFN_ADD_OVERFLOW:
11968 : case IFN_SUB_OVERFLOW:
11969 : case IFN_MUL_OVERFLOW:
11970 : case IFN_LAUNDER:
11971 : case IFN_VEC_CONVERT:
11972 : bail = false;
11973 : break;
11974 :
11975 : default:
11976 : break;
11977 : }
11978 :
11979 : if (bail)
11980 : {
11981 : /* fold_call_expr can't do anything with IFN calls. */
11982 66 : if (flags & tf_error)
11983 0 : constexpr_error (loc, fundef_p,
11984 : "call to internal function %qE", t);
11985 66 : return false;
11986 : }
11987 : }
11988 :
11989 314300230 : if (fun && is_overloaded_fn (fun))
11990 : {
11991 294921114 : if (!RECUR (fun, true))
11992 : return false;
11993 294504749 : fun = get_fns (fun);
11994 :
11995 294504749 : if (TREE_CODE (fun) == FUNCTION_DECL)
11996 : {
11997 277253842 : if (builtin_valid_in_constant_expr_p (fun))
11998 : return true;
11999 275177246 : if (!maybe_constexpr_fn (fun)
12000 : /* Allow any built-in function; if the expansion
12001 : isn't constant, we'll deal with that then. */
12002 55284349 : && !fndecl_built_in_p (fun)
12003 : /* In C++20, replaceable global allocation functions
12004 : are constant expressions. */
12005 41454713 : && (!cxx_replaceable_global_alloc_fn (fun)
12006 777415 : || TREE_CODE (t) != CALL_EXPR
12007 777415 : || (!CALL_FROM_NEW_OR_DELETE_P (t)
12008 257389 : && (current_function_decl == NULL_TREE
12009 257389 : || !is_std_allocator_allocate
12010 257389 : (current_function_decl))))
12011 : /* Allow placement new in std::construct_at. */
12012 40681308 : && (!cxx_placement_new_fn (fun)
12013 629820 : || TREE_CODE (t) != CALL_EXPR
12014 629820 : || current_function_decl == NULL_TREE
12015 629808 : || !is_std_construct_at (current_function_decl))
12016 40292935 : && !cxx_dynamic_cast_fn_p (fun)
12017 315467377 : && !cxx_cxa_builtin_fn_p (fun))
12018 : {
12019 : /* In C++26 evaluation of the function arguments might
12020 : throw and in that case it is irrelevant whether
12021 : fun is constexpr or not. */
12022 40244224 : if (cxx_dialect >= cxx26)
12023 5722427 : for (; i < nargs; ++i)
12024 : {
12025 3507684 : tree x = get_nth_callarg (t, i);
12026 3507684 : bool rv = processing_template_decl ? any : rval;
12027 3507684 : bool sub_now = false;
12028 3507684 : if (!potential_constant_expression_1 (x, rv, strict,
12029 : sub_now,
12030 : fundef_p,
12031 : flags,
12032 : jump_target))
12033 : return false;
12034 3204037 : if (throws (jump_target))
12035 : return true;
12036 : }
12037 39886777 : if ((flags & tf_error)
12038 39886777 : && constexpr_error (loc, fundef_p,
12039 : "call to non-%<constexpr%> "
12040 : "function %qD", fun))
12041 251 : explain_invalid_constexpr_fn (fun);
12042 39886777 : return false;
12043 : }
12044 : }
12045 :
12046 252183929 : fun = OVL_FIRST (fun);
12047 : /* Skip initial arguments to base constructors. */
12048 252183929 : if (DECL_BASE_CONSTRUCTOR_P (fun))
12049 4028052 : i = num_artificial_parms_for (fun);
12050 : }
12051 19379116 : else if (fun)
12052 : {
12053 19379116 : if (TREE_TYPE (fun)
12054 19379116 : && FUNCTION_POINTER_TYPE_P (TREE_TYPE (fun)))
12055 : want_rval = rval;
12056 : else
12057 : want_rval = any;
12058 19379116 : if (RECUR (fun, want_rval))
12059 : /* Might end up being a constant function pointer. But it
12060 : could also be a function object with constexpr op(), so
12061 : we pass 'any' so that the underlying VAR_DECL is deemed
12062 : as potentially-constant even though it wasn't declared
12063 : constexpr. */;
12064 : else
12065 : return false;
12066 : }
12067 604256202 : for (; i < nargs; ++i)
12068 : {
12069 352284352 : tree x = get_nth_callarg (t, i);
12070 : /* In a template, reference arguments haven't been converted to
12071 : REFERENCE_TYPE and we might not even know if the parameter
12072 : is a reference, so accept lvalue constants too. */
12073 352284352 : bool rv = processing_template_decl ? any : rval;
12074 : /* Don't require an immediately constant value, as constexpr
12075 : substitution might not use the value of the argument. */
12076 352284352 : bool sub_now = false;
12077 352284352 : if (!potential_constant_expression_1 (x, rv, strict,
12078 : sub_now, fundef_p, flags,
12079 : jump_target))
12080 : return false;
12081 3372248879 : if (throws (jump_target))
12082 : return true;
12083 : }
12084 : /* In C++26 a function could throw. */
12085 251971850 : if (*jump_target == NULL_TREE && callee_might_throw (t))
12086 6075254 : *jump_target = void_node;
12087 : return true;
12088 : }
12089 :
12090 207891111 : case NON_LVALUE_EXPR:
12091 : /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
12092 : -- an lvalue of integral type that refers to a non-volatile
12093 : const variable or static data member initialized with
12094 : constant expressions, or
12095 :
12096 : -- an lvalue of literal type that refers to non-volatile
12097 : object defined with constexpr, or that refers to a
12098 : sub-object of such an object; */
12099 207891111 : return RECUR (TREE_OPERAND (t, 0), rval);
12100 :
12101 26404 : case EXCESS_PRECISION_EXPR:
12102 26404 : return RECUR (TREE_OPERAND (t, 0), rval);
12103 :
12104 378387250 : case VAR_DECL:
12105 378387250 : if (DECL_HAS_VALUE_EXPR_P (t))
12106 : {
12107 9903957 : if (now && is_normal_capture_proxy (t))
12108 : {
12109 : /* -- in a lambda-expression, a reference to this or to a
12110 : variable with automatic storage duration defined outside that
12111 : lambda-expression, where the reference would be an
12112 : odr-use. */
12113 :
12114 1448097 : if (want_rval)
12115 : /* Since we're doing an lvalue-rvalue conversion, this might
12116 : not be an odr-use, so evaluate the variable directly. */
12117 1410330 : return RECUR (DECL_CAPTURED_VARIABLE (t), rval);
12118 :
12119 37767 : if (flags & tf_error)
12120 : {
12121 3 : tree cap = DECL_CAPTURED_VARIABLE (t);
12122 3 : auto_diagnostic_group d;
12123 3 : if (constexpr_error (input_location, fundef_p,
12124 : "lambda capture of %qE is not a "
12125 : "constant expression", cap)
12126 3 : && decl_constant_var_p (cap))
12127 3 : inform (input_location, "because it is used as a glvalue");
12128 3 : }
12129 37767 : return false;
12130 : }
12131 8455860 : tree ve = DECL_VALUE_EXPR (t);
12132 : /* Treat __PRETTY_FUNCTION__ inside a template function as
12133 : potentially-constant. */
12134 8455860 : if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
12135 : return true;
12136 8455855 : if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
12137 2736 : return RECUR (TREE_VEC_ELT (ve, 0), rval);
12138 8453119 : return RECUR (ve, rval);
12139 : }
12140 368483293 : if (want_rval
12141 246977403 : && (now || !var_in_maybe_constexpr_fn (t))
12142 224663006 : && !type_dependent_expression_p (t)
12143 194311415 : && !decl_maybe_constant_var_p (t)
12144 63254264 : && !is_local_temp (t)
12145 62660456 : && (strict
12146 3085644 : || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
12147 641576 : || (DECL_INITIAL (t)
12148 636103 : && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)))
12149 62653792 : && COMPLETE_TYPE_P (TREE_TYPE (t))
12150 431136941 : && !is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
12151 : {
12152 62648887 : if (flags & tf_error)
12153 163 : non_const_var_error (loc, t, fundef_p);
12154 62648887 : return false;
12155 : }
12156 : return true;
12157 :
12158 499416058 : case NOP_EXPR:
12159 499416058 : if (REINTERPRET_CAST_P (t))
12160 : {
12161 153783 : if (flags & tf_error)
12162 46 : constexpr_error (loc, fundef_p, "%<reinterpret_cast%> is not a "
12163 : "constant expression");
12164 153783 : return false;
12165 : }
12166 : /* FALLTHRU */
12167 987862366 : case CONVERT_EXPR:
12168 987862366 : case VIEW_CONVERT_EXPR:
12169 : /* -- a reinterpret_cast. FIXME not implemented, and this rule
12170 : may change to something more specific to type-punning (DR 1312). */
12171 987862366 : {
12172 987862366 : tree from = TREE_OPERAND (t, 0);
12173 987862366 : if (location_wrapper_p (t))
12174 394840097 : return (RECUR (from, want_rval));
12175 593022269 : if (INDIRECT_TYPE_P (TREE_TYPE (t)))
12176 : {
12177 345748554 : STRIP_ANY_LOCATION_WRAPPER (from);
12178 345748554 : if (TREE_CODE (from) == INTEGER_CST
12179 345748554 : && !integer_zerop (from))
12180 : {
12181 1522 : if (flags & tf_error)
12182 25 : constexpr_error (loc, fundef_p,
12183 : "%<reinterpret_cast%> from integer to "
12184 : "pointer");
12185 1522 : return false;
12186 : }
12187 : }
12188 593020747 : return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR));
12189 : }
12190 :
12191 11613 : case ADDRESSOF_EXPR:
12192 : /* This is like ADDR_EXPR, except it won't form pointer-to-member. */
12193 11613 : t = TREE_OPERAND (t, 0);
12194 11613 : goto handle_addr_expr;
12195 :
12196 129401695 : case ADDR_EXPR:
12197 : /* -- a unary operator & that is applied to an lvalue that
12198 : designates an object with thread or automatic storage
12199 : duration; */
12200 129401695 : t = TREE_OPERAND (t, 0);
12201 :
12202 129401695 : if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t))
12203 : /* A pointer-to-member constant. */
12204 : return true;
12205 :
12206 129413070 : handle_addr_expr:
12207 : #if 0
12208 : /* FIXME adjust when issue 1197 is fully resolved. For now don't do
12209 : any checking here, as we might dereference the pointer later. If
12210 : we remove this code, also remove check_automatic_or_tls. */
12211 : i = check_automatic_or_tls (t);
12212 : if (i == ck_ok)
12213 : return true;
12214 : if (i == ck_bad)
12215 : {
12216 : if (flags & tf_error)
12217 : error ("address-of an object %qE with thread local or "
12218 : "automatic storage is not a constant expression", t);
12219 : return false;
12220 : }
12221 : #endif
12222 129413070 : return RECUR (t, any);
12223 :
12224 139088011 : case COMPONENT_REF:
12225 139088011 : case ARROW_EXPR:
12226 139088011 : case OFFSET_REF:
12227 : /* -- a class member access unless its postfix-expression is
12228 : of literal type or of pointer to literal type. */
12229 : /* This test would be redundant, as it follows from the
12230 : postfix-expression being a potential constant expression. */
12231 139088011 : if (type_unknown_p (t))
12232 : return true;
12233 130369475 : if (is_overloaded_fn (t))
12234 : /* In a template, a COMPONENT_REF of a function expresses ob.fn(),
12235 : which uses ob as an lvalue. */
12236 131903861 : want_rval = false;
12237 131903861 : gcc_fallthrough ();
12238 :
12239 131903861 : case REALPART_EXPR:
12240 131903861 : case IMAGPART_EXPR:
12241 131903861 : case BIT_FIELD_REF:
12242 131903861 : return RECUR (TREE_OPERAND (t, 0), want_rval);
12243 :
12244 250396 : case EXPR_PACK_EXPANSION:
12245 250396 : return RECUR (PACK_EXPANSION_PATTERN (t), want_rval);
12246 :
12247 : case PACK_INDEX_EXPR:
12248 : return true;
12249 :
12250 138287117 : case INDIRECT_REF:
12251 138287117 : return RECUR (TREE_OPERAND (t, 0), rval);
12252 :
12253 27131616 : case STATEMENT_LIST:
12254 5388015702 : for (tree stmt : tsi_range (t))
12255 82132519 : if (!RECUR (stmt, any))
12256 317741827 : return false;
12257 : return true;
12258 :
12259 5410339 : case MODIFY_EXPR:
12260 5410339 : if (cxx_dialect < cxx14)
12261 1983 : goto fail;
12262 5408356 : if (!RECUR (TREE_OPERAND (t, 0), any))
12263 : return false;
12264 : /* Just ignore clobbers. */
12265 4940138 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
12266 : return true;
12267 4364904 : if (!RECUR (TREE_OPERAND (t, 1), rval))
12268 : return false;
12269 : return true;
12270 :
12271 891782 : case MODOP_EXPR:
12272 891782 : if (cxx_dialect < cxx14)
12273 96 : goto fail;
12274 891686 : if (!RECUR (TREE_OPERAND (t, 0), rval))
12275 : return false;
12276 881841 : if (!RECUR (TREE_OPERAND (t, 2), rval))
12277 : return false;
12278 : return true;
12279 :
12280 630557 : case DO_STMT:
12281 630557 : if (!RECUR (DO_COND (t), rval))
12282 : return false;
12283 630557 : if (!RECUR (DO_BODY (t), any))
12284 : return false;
12285 630265 : if (breaks (jump_target) || continues (jump_target))
12286 2 : *jump_target = NULL_TREE;
12287 : return true;
12288 :
12289 422112 : case FOR_STMT:
12290 422112 : if (!RECUR (FOR_INIT_STMT (t), any))
12291 : return false;
12292 422112 : if (!RECUR (FOR_COND_PREP (t), any))
12293 : return false;
12294 422112 : tmp = FOR_COND (t);
12295 422112 : if (!RECUR (tmp, rval))
12296 : return false;
12297 422044 : if (tmp)
12298 : {
12299 378376 : if (!processing_template_decl)
12300 375253 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
12301 : /* If we couldn't evaluate the condition, it might not ever be
12302 : true. */
12303 378376 : if (!integer_onep (tmp))
12304 : {
12305 : /* Before returning true, check if the for body can contain
12306 : a return. */
12307 378376 : hash_set<tree> pset;
12308 378376 : check_for_return_continue_data data = { &pset, NULL_TREE,
12309 378376 : NULL_TREE, false };
12310 378376 : if (tree ret_expr
12311 378376 : = cp_walk_tree (&FOR_BODY (t), check_for_return_continue,
12312 : &data, &pset))
12313 143291 : *jump_target = ret_expr;
12314 378376 : if (data.could_throw)
12315 8969 : *jump_target = void_node;
12316 378376 : return true;
12317 378376 : }
12318 : }
12319 43668 : if (!RECUR (FOR_EXPR (t), any))
12320 : return false;
12321 43668 : if (!RECUR (FOR_BODY (t), any))
12322 : return false;
12323 43668 : if (!RECUR (FOR_COND_CLEANUP (t), any))
12324 : return false;
12325 43668 : if (breaks (jump_target) || continues (jump_target))
12326 12 : *jump_target = NULL_TREE;
12327 : return true;
12328 :
12329 455 : case RANGE_FOR_STMT:
12330 455 : if (!RECUR (RANGE_FOR_INIT_STMT (t), any))
12331 : return false;
12332 455 : if (!RECUR (RANGE_FOR_EXPR (t), any))
12333 : return false;
12334 455 : if (!RECUR (RANGE_FOR_BODY (t), any))
12335 : return false;
12336 453 : if (breaks (jump_target) || continues (jump_target))
12337 0 : *jump_target = NULL_TREE;
12338 : return true;
12339 :
12340 227629 : case WHILE_STMT:
12341 227629 : if (!RECUR (WHILE_COND_PREP (t), any))
12342 : return false;
12343 227629 : tmp = WHILE_COND (t);
12344 227629 : if (!RECUR (tmp, rval))
12345 : return false;
12346 227565 : if (!processing_template_decl)
12347 227541 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
12348 : /* If we couldn't evaluate the condition, it might not ever be true. */
12349 227565 : if (!integer_onep (tmp))
12350 : {
12351 : /* Before returning true, check if the while body can contain
12352 : a return. */
12353 217930 : hash_set<tree> pset;
12354 217930 : check_for_return_continue_data data = { &pset, NULL_TREE,
12355 217930 : NULL_TREE, false };
12356 217930 : if (tree ret_expr
12357 217930 : = cp_walk_tree (&WHILE_BODY (t), check_for_return_continue,
12358 : &data, &pset))
12359 417 : *jump_target = ret_expr;
12360 217930 : if (data.could_throw)
12361 3104 : *jump_target = void_node;
12362 217930 : return true;
12363 217930 : }
12364 9635 : if (!RECUR (WHILE_BODY (t), any))
12365 : return false;
12366 9624 : if (!RECUR (WHILE_COND_CLEANUP (t), any))
12367 : return false;
12368 9624 : if (breaks (jump_target) || continues (jump_target))
12369 24 : *jump_target = NULL_TREE;
12370 : return true;
12371 :
12372 73820 : case SWITCH_STMT:
12373 73820 : if (!RECUR (SWITCH_STMT_COND (t), rval))
12374 : return false;
12375 : /* FIXME we don't check SWITCH_STMT_BODY currently, because even
12376 : unreachable labels would be checked and it is enough if there is
12377 : a single switch cond value for which it is a valid constant
12378 : expression. We need to check if there are any RETURN_EXPRs
12379 : or CONTINUE_STMTs inside of the body though, as in that case
12380 : we need to set *jump_target. */
12381 : else
12382 : {
12383 73814 : hash_set<tree> pset;
12384 73814 : check_for_return_continue_data data = { &pset, NULL_TREE,
12385 73814 : NULL_TREE, false };
12386 73814 : if (tree ret_expr
12387 73814 : = cp_walk_tree (&SWITCH_STMT_BODY (t), check_for_return_continue,
12388 : &data, &pset))
12389 : /* The switch might return. */
12390 73434 : *jump_target = ret_expr;
12391 380 : else if (data.continue_stmt)
12392 : /* The switch can't return, but might continue. */
12393 3 : *jump_target = data.continue_stmt;
12394 73814 : if (data.could_throw)
12395 25 : *jump_target = void_node;
12396 73814 : }
12397 73814 : return true;
12398 :
12399 50 : case STMT_EXPR:
12400 50 : return RECUR (STMT_EXPR_STMT (t), rval);
12401 :
12402 532247 : case LAMBDA_EXPR:
12403 532247 : if (cxx_dialect >= cxx17)
12404 : /* In C++17 lambdas can be constexpr, don't give up yet. */
12405 : return true;
12406 423 : else if (flags & tf_error)
12407 0 : constexpr_error (loc, fundef_p, "lambda-expression is not a "
12408 : "constant expression before C++17");
12409 : return false;
12410 :
12411 107575 : case NEW_EXPR:
12412 107575 : case VEC_NEW_EXPR:
12413 107575 : case DELETE_EXPR:
12414 107575 : case VEC_DELETE_EXPR:
12415 107575 : if (cxx_dialect >= cxx20)
12416 : /* In C++20, new-expressions are potentially constant. */
12417 : return true;
12418 1044 : else if (flags & tf_error)
12419 0 : constexpr_error (loc, fundef_p, "new-expression is not a "
12420 : "constant expression before C++20");
12421 : return false;
12422 :
12423 78786 : case DYNAMIC_CAST_EXPR:
12424 78786 : case PSEUDO_DTOR_EXPR:
12425 78786 : case OMP_PARALLEL:
12426 78786 : case OMP_TASK:
12427 78786 : case OMP_FOR:
12428 78786 : case OMP_SIMD:
12429 78786 : case OMP_DISTRIBUTE:
12430 78786 : case OMP_TASKLOOP:
12431 78786 : case OMP_LOOP:
12432 78786 : case OMP_TEAMS:
12433 78786 : case OMP_TARGET_DATA:
12434 78786 : case OMP_TARGET:
12435 78786 : case OMP_SECTIONS:
12436 78786 : case OMP_ORDERED:
12437 78786 : case OMP_CRITICAL:
12438 78786 : case OMP_SINGLE:
12439 78786 : case OMP_SCAN:
12440 78786 : case OMP_SCOPE:
12441 78786 : case OMP_SECTION:
12442 78786 : case OMP_MASTER:
12443 78786 : case OMP_MASKED:
12444 78786 : case OMP_TASKGROUP:
12445 78786 : case OMP_TARGET_UPDATE:
12446 78786 : case OMP_TARGET_ENTER_DATA:
12447 78786 : case OMP_TARGET_EXIT_DATA:
12448 78786 : case OMP_ATOMIC:
12449 78786 : case OMP_ATOMIC_READ:
12450 78786 : case OMP_ATOMIC_CAPTURE_OLD:
12451 78786 : case OMP_ATOMIC_CAPTURE_NEW:
12452 78786 : case OMP_DEPOBJ:
12453 78786 : case OACC_PARALLEL:
12454 78786 : case OACC_KERNELS:
12455 78786 : case OACC_SERIAL:
12456 78786 : case OACC_DATA:
12457 78786 : case OACC_HOST_DATA:
12458 78786 : case OACC_LOOP:
12459 78786 : case OACC_CACHE:
12460 78786 : case OACC_DECLARE:
12461 78786 : case OACC_ENTER_DATA:
12462 78786 : case OACC_EXIT_DATA:
12463 78786 : case OACC_UPDATE:
12464 78786 : case OMP_ARRAY_SECTION:
12465 : /* GCC internal stuff. */
12466 78786 : case VA_ARG_EXPR:
12467 78786 : case TRANSACTION_EXPR:
12468 78786 : case AT_ENCODE_EXPR:
12469 78786 : fail:
12470 78786 : if (flags & tf_error)
12471 23 : constexpr_error (loc, fundef_p, "expression %qE is not a constant "
12472 : "expression", t);
12473 : return false;
12474 :
12475 : case OMP_DECLARE_MAPPER:
12476 : /* This can be used to initialize VAR_DECLs: it's treated as a magic
12477 : constant. */
12478 : return true;
12479 :
12480 15203 : case THROW_EXPR:
12481 15203 : if (cxx_dialect < cxx26)
12482 279 : goto fail;
12483 14924 : return RECUR (TREE_OPERAND (t, 0), rval);
12484 :
12485 517 : case ASM_EXPR:
12486 517 : if (flags & tf_error)
12487 5 : inline_asm_in_constexpr_error (loc, fundef_p);
12488 : return false;
12489 :
12490 626394 : case OBJ_TYPE_REF:
12491 626394 : if (cxx_dialect >= cxx20)
12492 : /* In C++20 virtual calls can be constexpr, don't give up yet. */
12493 : return true;
12494 6579 : else if (flags & tf_error)
12495 0 : constexpr_error (loc, fundef_p, "virtual functions cannot be "
12496 : "%<constexpr%> before C++20");
12497 : return false;
12498 :
12499 4388 : case TYPEID_EXPR:
12500 : /* In C++20, a typeid expression whose operand is of polymorphic
12501 : class type can be constexpr. */
12502 4388 : {
12503 4388 : tree e = TREE_OPERAND (t, 0);
12504 4388 : if (cxx_dialect < cxx20
12505 26 : && strict
12506 26 : && !TYPE_P (e)
12507 19 : && !type_dependent_expression_p (e)
12508 7 : && CLASS_TYPE_P (TREE_TYPE (e))
12509 4393 : && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
12510 : {
12511 4 : if (flags & tf_error)
12512 1 : constexpr_error (loc, fundef_p, "%<typeid%> is not a "
12513 : "constant expression because %qE is "
12514 : "of polymorphic type", e);
12515 4 : return false;
12516 : }
12517 : return true;
12518 : }
12519 :
12520 30709580 : case POINTER_DIFF_EXPR:
12521 30709580 : case MINUS_EXPR:
12522 30709580 : want_rval = true;
12523 30709580 : goto binary;
12524 :
12525 94071682 : case LT_EXPR:
12526 94071682 : case LE_EXPR:
12527 94071682 : case GT_EXPR:
12528 94071682 : case GE_EXPR:
12529 94071682 : case EQ_EXPR:
12530 94071682 : case NE_EXPR:
12531 94071682 : case SPACESHIP_EXPR:
12532 94071682 : want_rval = true;
12533 94071682 : goto binary;
12534 :
12535 2533139 : case PREINCREMENT_EXPR:
12536 2533139 : case POSTINCREMENT_EXPR:
12537 2533139 : case PREDECREMENT_EXPR:
12538 2533139 : case POSTDECREMENT_EXPR:
12539 2533139 : if (cxx_dialect < cxx14)
12540 8300 : goto fail;
12541 2524839 : goto unary;
12542 :
12543 1117766 : case BIT_NOT_EXPR:
12544 : /* A destructor. */
12545 1117766 : if (TYPE_P (TREE_OPERAND (t, 0)))
12546 : return true;
12547 : /* fall through. */
12548 :
12549 46840071 : case CONJ_EXPR:
12550 46840071 : case SAVE_EXPR:
12551 46840071 : case FIX_TRUNC_EXPR:
12552 46840071 : case FLOAT_EXPR:
12553 46840071 : case NEGATE_EXPR:
12554 46840071 : case ABS_EXPR:
12555 46840071 : case ABSU_EXPR:
12556 46840071 : case TRUTH_NOT_EXPR:
12557 46840071 : case FIXED_CONVERT_EXPR:
12558 46840071 : case UNARY_PLUS_EXPR:
12559 46840071 : case UNARY_LEFT_FOLD_EXPR:
12560 46840071 : case UNARY_RIGHT_FOLD_EXPR:
12561 46840071 : case VEC_DUPLICATE_EXPR:
12562 1117766 : unary:
12563 46840071 : return RECUR (TREE_OPERAND (t, 0), rval);
12564 :
12565 30538749 : case CAST_EXPR:
12566 30538749 : case CONST_CAST_EXPR:
12567 30538749 : case STATIC_CAST_EXPR:
12568 30538749 : case REINTERPRET_CAST_EXPR:
12569 30538749 : case IMPLICIT_CONV_EXPR:
12570 30538749 : if (!cast_valid_in_integral_constant_expression_p (TREE_TYPE (t)))
12571 : /* In C++98, a conversion to non-integral type can't be part of a
12572 : constant expression. */
12573 : {
12574 297 : if (flags & tf_error)
12575 0 : constexpr_error (loc, fundef_p,
12576 : "cast to non-integral type %qT in a constant "
12577 0 : "expression", TREE_TYPE (t));
12578 297 : return false;
12579 : }
12580 : /* This might be a conversion from a class to a (potentially) literal
12581 : type. Let's consider it potentially constant since the conversion
12582 : might be a constexpr user-defined conversion. */
12583 30538452 : else if (cxx_dialect >= cxx11
12584 30518923 : && (dependent_type_p (TREE_TYPE (t))
12585 10950741 : || !COMPLETE_TYPE_P (TREE_TYPE (t))
12586 10937903 : || literal_type_p (TREE_TYPE (t)))
12587 30482505 : && TREE_OPERAND (t, 0)
12588 60785104 : && (TREE_CODE (t) != CAST_EXPR
12589 23052303 : || !TREE_CHAIN (TREE_OPERAND (t, 0))))
12590 : {
12591 30206632 : tree from = TREE_OPERAND (t, 0);
12592 30206632 : if (TREE_CODE (t) == CAST_EXPR)
12593 23012283 : from = TREE_VALUE (from);
12594 30206632 : tree type = TREE_TYPE (from);
12595 : /* If this is a dependent type, it could end up being a class
12596 : with conversions. */
12597 30206632 : if (type == NULL_TREE || WILDCARD_TYPE_P (type))
12598 : return true;
12599 : /* Or a non-dependent class which has conversions. */
12600 602658 : else if (CLASS_TYPE_P (type)
12601 602658 : && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
12602 266086 : return true;
12603 : }
12604 :
12605 24196499 : return (RECUR (TREE_OPERAND (t, 0),
12606 24196499 : !TYPE_REF_P (TREE_TYPE (t))));
12607 :
12608 18354611 : case BIND_EXPR:
12609 18354611 : return RECUR (BIND_EXPR_BODY (t), want_rval);
12610 :
12611 81785171 : case CLEANUP_POINT_EXPR:
12612 81785171 : case MUST_NOT_THROW_EXPR:
12613 81785171 : case TRY_CATCH_EXPR:
12614 : /* Even for C++26 handle TRY_BLOCK conservatively, if we detect the
12615 : body could throw, even with catch (...) among handlers we'd need
12616 : to analyze them in detail if they couldn't rethrow it. More
12617 : importantly though, throws (jump_target) is just conservative,
12618 : and there could be e.g.
12619 : try
12620 : {
12621 : possibly_throwing_fn (args);
12622 : break;
12623 : }
12624 : catch (...)
12625 : {
12626 : }
12627 : or continue or return instead of break. So, clearing *jump_target
12628 : because we see catch (...) handler might mean we missed break
12629 : etc. */
12630 81785171 : case TRY_BLOCK:
12631 81785171 : case EH_SPEC_BLOCK:
12632 81785171 : case EXPR_STMT:
12633 81785171 : case PAREN_EXPR:
12634 : /* For convenience. */
12635 81785171 : case LOOP_EXPR:
12636 81785171 : case EXIT_EXPR:
12637 81785171 : return RECUR (TREE_OPERAND (t, 0), want_rval);
12638 :
12639 16075790 : case DECL_EXPR:
12640 16075790 : tmp = DECL_EXPR_DECL (t);
12641 11871330 : if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)
12642 23872597 : && (processing_template_decl
12643 7056097 : ? !decl_maybe_constant_var_p (tmp)
12644 6315387 : : !decl_constant_var_p (tmp)))
12645 : {
12646 6450763 : if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
12647 : {
12648 8 : if (flags & tf_error)
12649 3 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
12650 : "%qD defined %<thread_local%> in "
12651 : "%<constexpr%> context", tmp);
12652 8 : return false;
12653 : }
12654 6450755 : else if (TREE_STATIC (tmp))
12655 : {
12656 112 : if (flags & tf_error)
12657 25 : constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
12658 : "%qD defined %<static%> in %<constexpr%> "
12659 : "context", tmp);
12660 112 : return false;
12661 : }
12662 6450643 : else if (!check_for_uninitialized_const_var
12663 6450643 : (tmp, /*constexpr_context_p=*/true, flags))
12664 : return false;
12665 : }
12666 16071935 : if (VAR_P (tmp))
12667 11867475 : return RECUR (DECL_INITIAL (tmp), want_rval);
12668 : return true;
12669 :
12670 28060 : case TRY_FINALLY_EXPR:
12671 28060 : return (RECUR (TREE_OPERAND (t, 0), want_rval)
12672 28060 : && RECUR (TREE_OPERAND (t, 1), any));
12673 :
12674 0 : case EH_ELSE_EXPR:
12675 : /* maybe_apply_function_contracts uses this to check postconditions only
12676 : on normal return. */
12677 0 : return (RECUR (TREE_OPERAND (t, 1), any)
12678 0 : || RECUR (TREE_OPERAND (t, 0), any));
12679 :
12680 24373056 : case SCOPE_REF:
12681 24373056 : return RECUR (TREE_OPERAND (t, 1), want_rval);
12682 :
12683 54678434 : case TARGET_EXPR:
12684 54678434 : if (!TARGET_EXPR_DIRECT_INIT_P (t)
12685 54474562 : && !TARGET_EXPR_ELIDING_P (t)
12686 96422488 : && !literal_type_p (TREE_TYPE (t)))
12687 : {
12688 865381 : if (flags & tf_error)
12689 : {
12690 23 : auto_diagnostic_group d;
12691 23 : if (constexpr_error (loc, fundef_p,
12692 : "temporary of non-literal type %qT in a "
12693 23 : "constant expression", TREE_TYPE (t)))
12694 23 : explain_non_literal_class (TREE_TYPE (t));
12695 23 : }
12696 865381 : return false;
12697 : }
12698 : /* FALLTHRU */
12699 85394172 : case INIT_EXPR:
12700 85394172 : if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
12701 : return true;
12702 85330617 : return RECUR (TREE_OPERAND (t, 1), rval);
12703 :
12704 44660050 : case CONSTRUCTOR:
12705 44660050 : {
12706 44660050 : vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
12707 44660050 : constructor_elt *ce;
12708 5552012222 : for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
12709 228592294 : if (!RECUR (ce->value, want_rval))
12710 : return false;
12711 : return true;
12712 : }
12713 :
12714 20625126 : case TREE_LIST:
12715 20625126 : {
12716 20625126 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
12717 : || DECL_P (TREE_PURPOSE (t)));
12718 20625126 : if (!RECUR (TREE_VALUE (t), want_rval))
12719 : return false;
12720 18331731 : if (TREE_CHAIN (t) == NULL_TREE)
12721 : return true;
12722 67600 : return RECUR (TREE_CHAIN (t), want_rval);
12723 : }
12724 :
12725 14789953 : case TRUNC_DIV_EXPR:
12726 14789953 : case CEIL_DIV_EXPR:
12727 14789953 : case FLOOR_DIV_EXPR:
12728 14789953 : case ROUND_DIV_EXPR:
12729 14789953 : case TRUNC_MOD_EXPR:
12730 14789953 : case CEIL_MOD_EXPR:
12731 14789953 : case ROUND_MOD_EXPR:
12732 14789953 : {
12733 14789953 : tree denom = TREE_OPERAND (t, 1);
12734 14789953 : if (!RECUR (denom, rval))
12735 : return false;
12736 : /* We can't call cxx_eval_outermost_constant_expr on an expression
12737 : that hasn't been through instantiate_non_dependent_expr yet. */
12738 14353210 : if (!processing_template_decl)
12739 7620139 : denom = cxx_eval_outermost_constant_expr (denom, true);
12740 14353210 : if (integer_zerop (denom))
12741 : {
12742 337 : if (flags & tf_error)
12743 35 : constexpr_error (input_location, fundef_p,
12744 : "division by zero is not a constant expression");
12745 337 : return false;
12746 : }
12747 : else
12748 : {
12749 14352873 : want_rval = true;
12750 14352873 : return RECUR (TREE_OPERAND (t, 0), want_rval);
12751 : }
12752 : }
12753 :
12754 7453301 : case COMPOUND_EXPR:
12755 7453301 : {
12756 : /* check_return_expr sometimes wraps a TARGET_EXPR in a
12757 : COMPOUND_EXPR; don't get confused. */
12758 7453301 : tree op0 = TREE_OPERAND (t, 0);
12759 7453301 : tree op1 = TREE_OPERAND (t, 1);
12760 7453301 : STRIP_NOPS (op1);
12761 7453301 : if (TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
12762 1382822 : return RECUR (op0, want_rval);
12763 : else
12764 6070479 : goto binary;
12765 : }
12766 :
12767 : /* If the first operand is the non-short-circuit constant, look at
12768 : the second operand; otherwise we only care about the first one for
12769 : potentiality. */
12770 20137656 : case TRUTH_AND_EXPR:
12771 20137656 : case TRUTH_ANDIF_EXPR:
12772 20137656 : tmp = boolean_true_node;
12773 20137656 : goto truth;
12774 8601450 : case TRUTH_OR_EXPR:
12775 8601450 : case TRUTH_ORIF_EXPR:
12776 8601450 : tmp = boolean_false_node;
12777 28739106 : truth:
12778 28739106 : {
12779 28739106 : tree op0 = TREE_OPERAND (t, 0);
12780 28739106 : tree op1 = TREE_OPERAND (t, 1);
12781 28739106 : if (!RECUR (op0, rval))
12782 : return false;
12783 19914932 : if (!(flags & tf_error) && RECUR (op1, rval))
12784 : /* When quiet, try to avoid expensive trial evaluation by first
12785 : checking potentiality of the second operand. */
12786 : return true;
12787 2274358 : if (!processing_template_decl)
12788 1803262 : op0 = cxx_eval_outermost_constant_expr (op0, true);
12789 2274358 : if (tree_int_cst_equal (op0, tmp))
12790 5133 : return (flags & tf_error) ? RECUR (op1, rval) : false;
12791 : else
12792 : return true;
12793 : }
12794 :
12795 : case PLUS_EXPR:
12796 : case MULT_EXPR:
12797 : case POINTER_PLUS_EXPR:
12798 : case RDIV_EXPR:
12799 : case EXACT_DIV_EXPR:
12800 : case MIN_EXPR:
12801 : case MAX_EXPR:
12802 : case LSHIFT_EXPR:
12803 : case RSHIFT_EXPR:
12804 : case LROTATE_EXPR:
12805 : case RROTATE_EXPR:
12806 : case BIT_IOR_EXPR:
12807 : case BIT_XOR_EXPR:
12808 : case BIT_AND_EXPR:
12809 : case TRUTH_XOR_EXPR:
12810 : case UNORDERED_EXPR:
12811 : case ORDERED_EXPR:
12812 : case UNLT_EXPR:
12813 : case UNLE_EXPR:
12814 : case UNGT_EXPR:
12815 : case UNGE_EXPR:
12816 : case UNEQ_EXPR:
12817 : case LTGT_EXPR:
12818 : case RANGE_EXPR:
12819 : case COMPLEX_EXPR:
12820 251342895 : want_rval = true;
12821 : /* Fall through. */
12822 251342895 : case ARRAY_REF:
12823 251342895 : case ARRAY_RANGE_REF:
12824 251342895 : case MEMBER_REF:
12825 251342895 : case DOTSTAR_EXPR:
12826 251342895 : case MEM_REF:
12827 251342895 : case BINARY_LEFT_FOLD_EXPR:
12828 251342895 : case BINARY_RIGHT_FOLD_EXPR:
12829 251342895 : binary:
12830 551998948 : for (i = 0; i < 2; ++i)
12831 408681854 : if (!RECUR (TREE_OPERAND (t, i), want_rval))
12832 : return false;
12833 : return true;
12834 :
12835 : case VEC_PERM_EXPR:
12836 106540 : for (i = 0; i < 3; ++i)
12837 106098 : if (!RECUR (TREE_OPERAND (t, i), true))
12838 : return false;
12839 : return true;
12840 :
12841 7180049 : case COND_EXPR:
12842 7180049 : if (COND_EXPR_IS_VEC_DELETE (t) && cxx_dialect < cxx20)
12843 : {
12844 8 : if (flags & tf_error)
12845 2 : constexpr_error (loc, fundef_p, "%<delete[]%> is not a "
12846 : "constant expression");
12847 8 : return false;
12848 : }
12849 : /* Fall through. */
12850 21248399 : case IF_STMT:
12851 21248399 : case VEC_COND_EXPR:
12852 : /* If the condition is a known constant, we know which of the legs we
12853 : care about; otherwise we only require that the condition and
12854 : either of the legs be potentially constant. */
12855 21248399 : tmp = TREE_OPERAND (t, 0);
12856 21248399 : if (!RECUR (tmp, rval))
12857 : return false;
12858 19480746 : if (!processing_template_decl)
12859 17529215 : tmp = cxx_eval_outermost_constant_expr (tmp, true);
12860 : /* potential_constant_expression* isn't told if it is called for
12861 : manifestly_const_eval or not, so for consteval if always
12862 : process both branches as if the condition is not a known
12863 : constant. */
12864 19480746 : if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
12865 : {
12866 19448519 : if (integer_zerop (tmp))
12867 4995909 : return RECUR (TREE_OPERAND (t, 2), want_rval);
12868 14452610 : else if (TREE_CODE (tmp) == INTEGER_CST)
12869 4630179 : return RECUR (TREE_OPERAND (t, 1), want_rval);
12870 : }
12871 9854658 : tmp = *jump_target;
12872 11509963 : for (i = 1; i < 3; ++i)
12873 : {
12874 11289986 : tree this_jump_target = tmp;
12875 11289986 : if (potential_constant_expression_1 (TREE_OPERAND (t, i),
12876 : want_rval, strict, now, fundef_p,
12877 : tf_none, &this_jump_target))
12878 : {
12879 9795818 : if (returns (&this_jump_target) || throws (&this_jump_target))
12880 2545039 : *jump_target = this_jump_target;
12881 7089642 : else if (!returns (jump_target) && !throws (jump_target))
12882 : {
12883 7089642 : if (breaks (&this_jump_target)
12884 7089642 : || continues (&this_jump_target))
12885 42 : *jump_target = this_jump_target;
12886 7089642 : if (i == 1)
12887 : {
12888 : /* If the then branch is potentially constant, but
12889 : does not return, check if the else branch
12890 : couldn't return, break or continue. */
12891 5958294 : hash_set<tree> pset;
12892 5958294 : check_for_return_continue_data data = { &pset, NULL_TREE,
12893 : NULL_TREE,
12894 5958294 : false };
12895 11916588 : if (tree ret_expr
12896 5958294 : = cp_walk_tree (&TREE_OPERAND (t, 2),
12897 : check_for_return_continue, &data,
12898 : &pset))
12899 59458 : *jump_target = ret_expr;
12900 5898836 : else if (*jump_target == NULL_TREE)
12901 : {
12902 5898797 : if (data.continue_stmt)
12903 0 : *jump_target = data.continue_stmt;
12904 5898797 : else if (data.break_stmt)
12905 13 : *jump_target = data.break_stmt;
12906 : }
12907 5958294 : if (data.could_throw)
12908 22179 : *jump_target = void_node;
12909 5958294 : }
12910 : }
12911 9634681 : return true;
12912 : }
12913 : }
12914 219977 : if (flags & tf_error)
12915 : {
12916 3 : if (TREE_CODE (t) == IF_STMT)
12917 3 : constexpr_error (loc, fundef_p, "neither branch of %<if%> is a "
12918 : "constant expression");
12919 : else
12920 0 : constexpr_error (loc, fundef_p, "expression %qE is not a "
12921 : "constant expression", t);
12922 : }
12923 : return false;
12924 :
12925 1043 : case VEC_INIT_EXPR:
12926 1043 : if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
12927 : return true;
12928 411 : if (flags & tf_error)
12929 : {
12930 3 : if (constexpr_error (loc, fundef_p, "non-constant array "
12931 : "initialization"))
12932 2 : diagnose_non_constexpr_vec_init (t);
12933 : }
12934 : return false;
12935 :
12936 : case TYPE_DECL:
12937 : case TAG_DEFN:
12938 : /* We can see these in statement-expressions. */
12939 : return true;
12940 :
12941 1617100 : case CLEANUP_STMT:
12942 1617100 : if (!RECUR (CLEANUP_BODY (t), any))
12943 : return false;
12944 1616577 : if (!CLEANUP_EH_ONLY (t) && !RECUR (CLEANUP_EXPR (t), any))
12945 : return false;
12946 : return true;
12947 :
12948 : case EMPTY_CLASS_EXPR:
12949 : return true;
12950 :
12951 36 : case GOTO_EXPR:
12952 36 : {
12953 36 : tree *target = &TREE_OPERAND (t, 0);
12954 : /* Gotos representing break, continue and cdtor return are OK. */
12955 36 : if (breaks (target) || continues (target) || returns (target))
12956 : {
12957 18 : *jump_target = *target;
12958 18 : return true;
12959 : }
12960 18 : if (TREE_CODE (*target) == LABEL_DECL && DECL_ARTIFICIAL (*target))
12961 : /* The user didn't write this goto, this isn't the problem. */
12962 : return true;
12963 16 : if (flags & tf_error)
12964 3 : constexpr_error (loc, fundef_p, "%<goto%> is not a constant "
12965 : "expression");
12966 : return false;
12967 : }
12968 :
12969 : case ASSERTION_STMT:
12970 : case PRECONDITION_STMT:
12971 : case POSTCONDITION_STMT:
12972 : /* Contracts are not supposed to alter this; we have to check that this
12973 : is not violated at a later time. */
12974 : return true;
12975 :
12976 223 : case LABEL_EXPR:
12977 223 : t = LABEL_EXPR_LABEL (t);
12978 223 : if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
12979 : return true;
12980 25 : else if (flags & tf_error)
12981 5 : constexpr_error (loc, fundef_p, "label definition in %<constexpr%> "
12982 : "function only available with %<-std=c++23%> or "
12983 : "%<-std=gnu++23%>");
12984 : return false;
12985 :
12986 9708 : case ANNOTATE_EXPR:
12987 9708 : return RECUR (TREE_OPERAND (t, 0), rval);
12988 :
12989 127834 : case BIT_CAST_EXPR:
12990 127834 : return RECUR (TREE_OPERAND (t, 0), rval);
12991 :
12992 : /* Coroutine await, yield and return expressions are not. */
12993 690 : case CO_AWAIT_EXPR:
12994 690 : case CO_YIELD_EXPR:
12995 690 : case CO_RETURN_EXPR:
12996 690 : case TEMPLATE_FOR_STMT:
12997 690 : if (flags & tf_error)
12998 3 : constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p,
12999 : "%qE is not a constant expression", t);
13000 : return false;
13001 :
13002 : /* Assume a TU-local entity is not constant, we'll error later when
13003 : instantiating. */
13004 : case TU_LOCAL_ENTITY:
13005 : return false;
13006 :
13007 : /* A splice expression is dependent, but will be constant after
13008 : substitution. */
13009 : case SPLICE_EXPR:
13010 : return true;
13011 :
13012 30 : case NONTYPE_ARGUMENT_PACK:
13013 30 : {
13014 30 : tree args = ARGUMENT_PACK_ARGS (t);
13015 30 : int len = TREE_VEC_LENGTH (args);
13016 90 : for (int i = 0; i < len; ++i)
13017 60 : if (!RECUR (TREE_VEC_ELT (args, i), any))
13018 : return false;
13019 : return true;
13020 : }
13021 :
13022 0 : default:
13023 0 : if (objc_non_constant_expr_p (t))
13024 : return false;
13025 :
13026 0 : sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
13027 0 : gcc_unreachable ();
13028 : return false;
13029 : }
13030 : #undef RECUR
13031 5280250150 : }
13032 :
13033 : bool
13034 1831870551 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
13035 : bool fundef_p, tsubst_flags_t flags)
13036 : {
13037 1831870551 : if (flags & tf_error)
13038 : {
13039 : /* Check potentiality quietly first, as that could be performed more
13040 : efficiently in some cases (currently only for TRUTH_*_EXPR). If
13041 : that fails, replay the check noisily to give errors. */
13042 14551985 : flags &= ~tf_error;
13043 14551985 : if (potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13044 : flags))
13045 : return true;
13046 973 : flags |= tf_error;
13047 : }
13048 :
13049 1817319539 : tree target = NULL_TREE;
13050 1817319539 : return potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
13051 1817319539 : flags, &target);
13052 : }
13053 :
13054 : /* The main entry point to the above. */
13055 :
13056 : bool
13057 459822811 : potential_constant_expression (tree t)
13058 : {
13059 459822811 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13060 : /*now*/false, /*fundef_p*/false,
13061 459822811 : tf_none);
13062 : }
13063 :
13064 : /* As above, but require a constant rvalue. */
13065 :
13066 : bool
13067 37407057 : potential_rvalue_constant_expression (tree t)
13068 : {
13069 37407057 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13070 : /*now*/false, /*fundef_p*/false,
13071 37407057 : tf_none);
13072 : }
13073 :
13074 : /* Like above, but complain about non-constant expressions. */
13075 :
13076 : bool
13077 72 : require_potential_constant_expression (tree t)
13078 : {
13079 72 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13080 : /*now*/false, /*fundef_p*/false,
13081 72 : tf_warning_or_error);
13082 : }
13083 :
13084 : /* Cross product of the above. */
13085 :
13086 : bool
13087 125678 : require_potential_rvalue_constant_expression (tree t)
13088 : {
13089 125678 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13090 : /*now*/false, /*fundef_p*/false,
13091 125678 : tf_warning_or_error);
13092 : }
13093 :
13094 : /* Like require_potential_rvalue_constant_expression, but fundef_p is true. */
13095 :
13096 : bool
13097 254 : require_potential_rvalue_constant_expression_fncheck (tree t)
13098 : {
13099 254 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13100 : /*now*/false, /*fundef_p*/true,
13101 254 : tf_warning_or_error);
13102 : }
13103 :
13104 : /* Like above, but don't consider PARM_DECL a potential_constant_expression. */
13105 :
13106 : bool
13107 738 : require_rvalue_constant_expression (tree t)
13108 : {
13109 738 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13110 : /*now*/true, /*fundef_p*/false,
13111 738 : tf_warning_or_error);
13112 : }
13113 :
13114 : /* Like potential_constant_expression, but don't consider possible constexpr
13115 : substitution of the current function. That is, PARM_DECL qualifies under
13116 : potential_constant_expression, but not here.
13117 :
13118 : This is basically what you can check when any actual constant values might
13119 : be value-dependent. */
13120 :
13121 : bool
13122 998461577 : is_constant_expression (tree t)
13123 : {
13124 998461577 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13125 : /*now*/true, /*fundef_p*/false,
13126 998461577 : tf_none);
13127 : }
13128 :
13129 : /* As above, but expect an rvalue. */
13130 :
13131 : bool
13132 146572916 : is_rvalue_constant_expression (tree t)
13133 : {
13134 146572916 : return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
13135 : /*now*/true, /*fundef_p*/false,
13136 146572916 : tf_none);
13137 : }
13138 :
13139 : /* Like above, but complain about non-constant expressions. */
13140 :
13141 : bool
13142 14425243 : require_constant_expression (tree t)
13143 : {
13144 14425243 : return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
13145 : /*now*/true, /*fundef_p*/false,
13146 14425243 : tf_warning_or_error);
13147 : }
13148 :
13149 : /* Like is_constant_expression, but allow const variables that are not allowed
13150 : under constexpr rules. */
13151 :
13152 : bool
13153 160502220 : is_static_init_expression (tree t)
13154 : {
13155 160502220 : return potential_constant_expression_1 (t, /*want_rval*/false,
13156 : /*strict*/false, /*now*/true,
13157 160502220 : /*fundef_p*/false, tf_none);
13158 : }
13159 :
13160 : /* Returns true if T is a potential constant expression that is not
13161 : instantiation-dependent, and therefore a candidate for constant folding even
13162 : in a template. */
13163 :
13164 : bool
13165 964516705 : is_nondependent_constant_expression (tree t)
13166 : {
13167 964516705 : return (!type_unknown_p (t)
13168 964516656 : && is_constant_expression (t)
13169 1800387499 : && !instantiation_dependent_expression_p (t));
13170 : }
13171 :
13172 : /* Returns true if T is a potential static initializer expression that is not
13173 : instantiation-dependent. */
13174 :
13175 : bool
13176 160502220 : is_nondependent_static_init_expression (tree t)
13177 : {
13178 160502220 : return (!type_unknown_p (t)
13179 160502220 : && is_static_init_expression (t)
13180 298338019 : && !instantiation_dependent_expression_p (t));
13181 : }
13182 :
13183 : /* True iff FN is an implicitly constexpr function. */
13184 :
13185 : bool
13186 194845 : decl_implicit_constexpr_p (tree fn)
13187 : {
13188 194845 : if (!(flag_implicit_constexpr
13189 2 : && TREE_CODE (fn) == FUNCTION_DECL
13190 2 : && DECL_DECLARED_CONSTEXPR_P (fn)))
13191 : return false;
13192 :
13193 2 : if (DECL_CLONED_FUNCTION_P (fn))
13194 0 : fn = DECL_CLONED_FUNCTION (fn);
13195 :
13196 2 : return (DECL_LANG_SPECIFIC (fn)
13197 2 : && DECL_LANG_SPECIFIC (fn)->u.fn.implicit_constexpr);
13198 : }
13199 :
13200 : /* Finalize constexpr processing after parsing. */
13201 :
13202 : void
13203 96437 : fini_constexpr (void)
13204 : {
13205 : /* The contexpr call and fundef copies tables are no longer needed. */
13206 96437 : constexpr_call_table = NULL;
13207 96437 : fundef_copies_table = NULL;
13208 96437 : }
13209 :
13210 : #include "gt-cp-constexpr.h"
|