Line data Source code
1 : /* C++-specific tree lowering bits; see also c-gimplify.cc and gimple.cc.
2 :
3 : Copyright (C) 2002-2026 Free Software Foundation, Inc.
4 : Contributed by Jason Merrill <jason@redhat.com>
5 :
6 : This file is part of GCC.
7 :
8 : GCC is free software; you can redistribute it and/or modify it under
9 : the terms of the GNU General Public License as published by the Free
10 : Software Foundation; either version 3, or (at your option) any later
11 : version.
12 :
13 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 : for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with GCC; see the file COPYING3. If not see
20 : <http://www.gnu.org/licenses/>. */
21 :
22 : #include "config.h"
23 : #include "system.h"
24 : #include "coretypes.h"
25 : #include "target.h"
26 : #include "basic-block.h"
27 : #include "cp-tree.h"
28 : #include "gimple.h"
29 : #include "predict.h"
30 : #include "stor-layout.h"
31 : #include "tree-iterator.h"
32 : #include "gimplify.h"
33 : #include "c-family/c-ubsan.h"
34 : #include "stringpool.h"
35 : #include "attribs.h"
36 : #include "asan.h"
37 : #include "gcc-rich-location.h"
38 : #include "memmodel.h"
39 : #include "tm_p.h"
40 : #include "output.h"
41 : #include "file-prefix-map.h"
42 : #include "cgraph.h"
43 : #include "omp-general.h"
44 : #include "opts.h"
45 : #include "gcc-urlifier.h"
46 : #include "contracts.h" // build_contract_check ()
47 : #include "builtins.h"
48 :
49 : /* Keep track of forward references to immediate-escalating functions in
50 : case they become consteval. This vector contains ADDR_EXPRs and
51 : PTRMEM_CSTs; it also stores FUNCTION_DECLs that had an escalating
52 : function call in them, to check that they can be evaluated to a constant,
53 : and immediate-escalating functions that may become consteval. */
54 : static GTY(()) hash_set<tree> *deferred_escalating_exprs;
55 :
56 : static void
57 26702301 : remember_escalating_expr (tree t)
58 : {
59 26702301 : if (uses_template_parms (t))
60 : /* Templates don't escalate, and cp_fold_immediate can get confused by
61 : other template trees in the function body (c++/115986). */
62 : return;
63 26702301 : if (!deferred_escalating_exprs)
64 20030 : deferred_escalating_exprs = hash_set<tree>::create_ggc (37);
65 26702301 : deferred_escalating_exprs->add (t);
66 : }
67 :
68 : /* Flags for cp_fold and cp_fold_r. */
69 :
70 : enum fold_flags {
71 : ff_none = 0,
72 : /* Whether we're being called from cp_fold_function. */
73 : ff_genericize = 1 << 0,
74 : /* Whether we're folding a point where we know we're
75 : definitely not in a manifestly constant-evaluated
76 : context. */
77 : ff_mce_false = 1 << 1,
78 : /* Whether we're only folding non-ODR usages of constants.
79 : This happens before saving the constexpr funcdef, so
80 : we should do as little other folding as possible.
81 : Mutually exclusive with ff_mce_false. */
82 : ff_only_non_odr = 1 << 2,
83 : };
84 :
85 : using fold_flags_t = int;
86 :
87 85571910 : struct cp_fold_data
88 : {
89 : hash_set<tree> pset;
90 : fold_flags_t flags;
91 201653194 : cp_fold_data (fold_flags_t flags): flags (flags)
92 : {
93 201653194 : gcc_checking_assert (!(flags & ff_mce_false)
94 : || !(flags & ff_only_non_odr));
95 201653194 : }
96 79789513 : mce_value mce ()
97 : {
98 79789513 : return flags & ff_mce_false ? mce_false : mce_unknown;
99 : }
100 : };
101 :
102 : /* Forward declarations. */
103 :
104 : static tree cp_genericize_r (tree *, int *, void *);
105 : static tree cp_fold_r (tree *, int *, void *);
106 : static void cp_genericize_tree (tree*, bool);
107 : static tree cp_fold (tree, fold_flags_t);
108 : static tree cp_fold_immediate_r (tree *, int *, void *);
109 :
110 : /* Genericize a TRY_BLOCK. */
111 :
112 : static void
113 19247 : genericize_try_block (tree *stmt_p)
114 : {
115 19247 : tree body = TRY_STMTS (*stmt_p);
116 19247 : tree cleanup = TRY_HANDLERS (*stmt_p);
117 :
118 19247 : *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
119 19247 : }
120 :
121 : /* Genericize a HANDLER by converting to a CATCH_EXPR. */
122 :
123 : static void
124 22423 : genericize_catch_block (tree *stmt_p)
125 : {
126 22423 : tree type = HANDLER_TYPE (*stmt_p);
127 22423 : tree body = HANDLER_BODY (*stmt_p);
128 :
129 : /* FIXME should the caught type go in TREE_TYPE? */
130 22423 : *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
131 22423 : }
132 :
133 : /* A terser interface for building a representation of an exception
134 : specification. */
135 :
136 : static tree
137 5841 : build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
138 : {
139 5841 : tree t;
140 :
141 : /* FIXME should the allowed types go in TREE_TYPE? */
142 5841 : t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
143 5841 : append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
144 :
145 5841 : t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
146 5841 : append_to_statement_list (body, &TREE_OPERAND (t, 0));
147 :
148 5841 : return t;
149 : }
150 :
151 : /* Genericize an EH_SPEC_BLOCK by converting it to a
152 : TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
153 :
154 : static void
155 5841 : genericize_eh_spec_block (tree *stmt_p)
156 : {
157 5841 : tree body = EH_SPEC_STMTS (*stmt_p);
158 5841 : tree allowed = EH_SPEC_RAISES (*stmt_p);
159 5841 : tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
160 :
161 5841 : *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
162 5841 : suppress_warning (*stmt_p);
163 5841 : suppress_warning (TREE_OPERAND (*stmt_p, 1));
164 5841 : }
165 :
166 : /* Return the first non-compound statement in STMT. */
167 :
168 : tree
169 15188768 : first_stmt (tree stmt)
170 : {
171 23001768 : switch (TREE_CODE (stmt))
172 : {
173 6079618 : case STATEMENT_LIST:
174 6079618 : if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt))
175 4113248 : return first_stmt (p->stmt);
176 1966370 : return void_node;
177 :
178 3699752 : case BIND_EXPR:
179 3699752 : return first_stmt (BIND_EXPR_BODY (stmt));
180 :
181 : default:
182 : return stmt;
183 : }
184 : }
185 :
186 : /* Genericize an IF_STMT by turning it into a COND_EXPR. */
187 :
188 : static void
189 22401141 : genericize_if_stmt (tree *stmt_p)
190 : {
191 22401141 : tree stmt, cond, then_, else_;
192 22401141 : location_t locus = EXPR_LOCATION (*stmt_p);
193 :
194 22401141 : stmt = *stmt_p;
195 22401141 : cond = IF_COND (stmt);
196 22401141 : then_ = THEN_CLAUSE (stmt);
197 22401141 : else_ = ELSE_CLAUSE (stmt);
198 :
199 22401141 : if (then_ && else_)
200 : {
201 7594384 : tree ft = first_stmt (then_);
202 7594384 : tree fe = first_stmt (else_);
203 7594384 : br_predictor pr;
204 7594384 : if (TREE_CODE (ft) == PREDICT_EXPR
205 43698 : && TREE_CODE (fe) == PREDICT_EXPR
206 48 : && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe)
207 7594423 : && (pr == PRED_HOT_LABEL || pr == PRED_COLD_LABEL))
208 : {
209 3 : gcc_rich_location richloc (EXPR_LOC_OR_LOC (ft, locus));
210 3 : richloc.add_range (EXPR_LOC_OR_LOC (fe, locus));
211 3 : warning_at (&richloc, OPT_Wattributes,
212 : "both branches of %<if%> statement marked as %qs",
213 : pr == PRED_HOT_LABEL ? "likely" : "unlikely");
214 3 : }
215 : }
216 :
217 22401141 : if (IF_STMT_VACUOUS_INIT_P (stmt))
218 : {
219 56 : gcc_checking_assert (integer_zerop (cond));
220 56 : gcc_checking_assert (!else_ || !TREE_SIDE_EFFECTS (else_));
221 56 : tree lab = create_artificial_label (UNKNOWN_LOCATION);
222 56 : VACUOUS_INIT_LABEL_P (lab) = 1;
223 56 : tree goto_expr = build_stmt (UNKNOWN_LOCATION, GOTO_EXPR, lab);
224 56 : tree label_expr = build_stmt (UNKNOWN_LOCATION, LABEL_EXPR, lab);
225 56 : if (TREE_CODE (then_) == STATEMENT_LIST)
226 : {
227 56 : tree_stmt_iterator i = tsi_start (then_);
228 56 : tsi_link_before (&i, goto_expr, TSI_CONTINUE_LINKING);
229 56 : i = tsi_last (then_);
230 56 : tsi_link_after (&i, label_expr, TSI_CONTINUE_LINKING);
231 56 : stmt = then_;
232 : }
233 : else
234 : {
235 0 : stmt = NULL_TREE;
236 0 : append_to_statement_list (goto_expr, &stmt);
237 0 : append_to_statement_list (then_, &stmt);
238 0 : append_to_statement_list (label_expr, &stmt);
239 : }
240 56 : *stmt_p = stmt;
241 56 : return;
242 : }
243 :
244 22401085 : if (!then_)
245 2010 : then_ = build_empty_stmt (locus);
246 22401085 : if (!else_)
247 14804798 : else_ = build_empty_stmt (locus);
248 :
249 : /* consteval if has been verified not to have the then_/else_ blocks
250 : entered by gotos/case labels from elsewhere, and as then_ block
251 : can contain unfolded immediate function calls, we have to discard
252 : the then_ block regardless of whether else_ has side-effects or not. */
253 22401085 : if (IF_STMT_CONSTEVAL_P (stmt))
254 : {
255 78875 : if (block_may_fallthru (then_))
256 25455 : stmt = build3 (COND_EXPR, void_type_node, boolean_false_node,
257 : void_node, else_);
258 : else
259 53420 : stmt = else_;
260 : }
261 22322210 : else if (IF_STMT_CONSTEXPR_P (stmt))
262 7046619 : stmt = integer_nonzerop (cond) ? then_ : else_;
263 : /* ??? This optimization doesn't seem to belong here, but removing it
264 : causes -Wreturn-type regressions (e.g. 107310). */
265 17540045 : else if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
266 100512 : stmt = then_;
267 17439533 : else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
268 35461 : stmt = else_;
269 : else
270 17404072 : stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
271 22401085 : protected_set_expr_location_if_unset (stmt, locus);
272 22401085 : *stmt_p = stmt;
273 : }
274 :
275 : /* Hook into the middle of gimplifying an OMP_FOR node. */
276 :
277 : static enum gimplify_status
278 45617 : cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
279 : {
280 45617 : tree for_stmt = *expr_p;
281 45617 : gimple_seq seq = NULL;
282 :
283 : /* Protect ourselves from recursion. */
284 45617 : if (OMP_FOR_GIMPLIFYING_P (for_stmt))
285 : return GS_UNHANDLED;
286 21202 : OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
287 :
288 21202 : gimplify_and_add (for_stmt, &seq);
289 21202 : gimple_seq_add_seq (pre_p, seq);
290 :
291 21202 : OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
292 :
293 21202 : return GS_ALL_DONE;
294 : }
295 :
296 : /* Gimplify an EXPR_STMT node. */
297 :
298 : static void
299 4161097 : gimplify_expr_stmt (tree *stmt_p)
300 : {
301 4161097 : tree stmt = EXPR_STMT_EXPR (*stmt_p);
302 :
303 4161097 : if (stmt == error_mark_node)
304 : stmt = NULL;
305 :
306 : /* Gimplification of a statement expression will nullify the
307 : statement if all its side effects are moved to *PRE_P and *POST_P.
308 :
309 : In this case we will not want to emit the gimplified statement.
310 : However, we may still want to emit a warning, so we do that before
311 : gimplification. */
312 4157098 : if (stmt && warn_unused_value)
313 : {
314 308376 : if (!TREE_SIDE_EFFECTS (stmt))
315 : {
316 0 : if (!IS_EMPTY_STMT (stmt)
317 6846 : && !VOID_TYPE_P (TREE_TYPE (stmt))
318 6846 : && !warning_suppressed_p (stmt, OPT_Wunused_value))
319 0 : warning (OPT_Wunused_value, "statement with no effect");
320 : }
321 : else
322 301530 : warn_if_unused_value (stmt, input_location);
323 : }
324 :
325 4161097 : if (stmt == NULL_TREE)
326 3999 : stmt = alloc_stmt_list ();
327 :
328 4161097 : *stmt_p = stmt;
329 4161097 : }
330 :
331 : /* Gimplify initialization from an AGGR_INIT_EXPR. */
332 :
333 : static void
334 12149514 : cp_gimplify_init_expr (tree *expr_p)
335 : {
336 12149514 : tree from = TREE_OPERAND (*expr_p, 1);
337 12149514 : tree to = TREE_OPERAND (*expr_p, 0);
338 12149514 : tree t;
339 :
340 12149514 : if (TREE_CODE (from) == TARGET_EXPR)
341 214429 : if (tree init = TARGET_EXPR_INITIAL (from))
342 : {
343 : /* Make sure that we expected to elide this temporary. But also allow
344 : gimplify_modify_expr_rhs to elide temporaries of trivial type. */
345 214429 : gcc_checking_assert (TARGET_EXPR_ELIDING_P (from)
346 : || !TREE_ADDRESSABLE (TREE_TYPE (from)));
347 214429 : if (target_expr_needs_replace (from))
348 : {
349 : /* If this was changed by cp_genericize_target_expr, we need to
350 : walk into it to replace uses of the slot. */
351 96 : replace_decl (&init, TARGET_EXPR_SLOT (from), to);
352 96 : *expr_p = init;
353 96 : return;
354 : }
355 : else
356 : from = init;
357 : }
358 :
359 : /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
360 : inside the TARGET_EXPR. */
361 12238804 : for (t = from; t; )
362 : {
363 12238804 : tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
364 :
365 : /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
366 : replace the slot operand with our target.
367 :
368 : Should we add a target parm to gimplify_expr instead? No, as in this
369 : case we want to replace the INIT_EXPR. */
370 12238804 : if (TREE_CODE (sub) == AGGR_INIT_EXPR
371 12238804 : || TREE_CODE (sub) == VEC_INIT_EXPR)
372 : {
373 116955 : if (TREE_CODE (sub) == AGGR_INIT_EXPR)
374 116955 : AGGR_INIT_EXPR_SLOT (sub) = to;
375 : else
376 0 : VEC_INIT_EXPR_SLOT (sub) = to;
377 116955 : *expr_p = from;
378 :
379 : /* The initialization is now a side-effect, so the container can
380 : become void. */
381 116955 : if (from != sub)
382 73 : TREE_TYPE (from) = void_type_node;
383 : }
384 :
385 : /* Handle aggregate NSDMI. */
386 12238804 : replace_placeholders (sub, to);
387 :
388 12238804 : if (t == sub)
389 : break;
390 : else
391 89386 : t = TREE_OPERAND (t, 1);
392 : }
393 :
394 : }
395 :
396 : /* Gimplify a MUST_NOT_THROW_EXPR. */
397 :
398 : static enum gimplify_status
399 590747 : gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
400 : {
401 590747 : tree stmt = *expr_p;
402 590747 : tree temp = voidify_wrapper_expr (stmt, NULL);
403 590747 : tree body = TREE_OPERAND (stmt, 0);
404 590747 : gimple_seq try_ = NULL;
405 590747 : gimple_seq catch_ = NULL;
406 590747 : gimple *mnt;
407 :
408 590747 : gimplify_and_add (body, &try_);
409 590747 : mnt = gimple_build_eh_must_not_throw (call_terminate_fn);
410 590747 : gimple_seq_add_stmt_without_update (&catch_, mnt);
411 590747 : mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
412 :
413 590747 : gimple_seq_add_stmt_without_update (pre_p, mnt);
414 590747 : if (temp)
415 : {
416 33 : *expr_p = temp;
417 33 : return GS_OK;
418 : }
419 :
420 : *expr_p = NULL;
421 : return GS_ALL_DONE;
422 : }
423 :
424 : /* Return TRUE if an operand (OP) of a given TYPE being copied is
425 : really just an empty class copy.
426 :
427 : Check that the operand has a simple form so that TARGET_EXPRs and
428 : non-empty CONSTRUCTORs get reduced properly, and we leave the
429 : return slot optimization alone because it isn't a copy. */
430 :
431 : bool
432 20339217 : simple_empty_class_p (tree type, tree op, tree_code code)
433 : {
434 23790817 : if (TREE_CODE (op) == COMPOUND_EXPR)
435 188775 : return simple_empty_class_p (type, TREE_OPERAND (op, 1), code);
436 4357163 : if (SIMPLE_TARGET_EXPR_P (op)
437 26866416 : && TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
438 : /* The TARGET_EXPR is itself a simple copy, look through it. */
439 3262825 : return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
440 :
441 20339217 : if (TREE_CODE (op) == PARM_DECL
442 20339217 : && TREE_ADDRESSABLE (TREE_TYPE (op)))
443 : {
444 9 : tree fn = DECL_CONTEXT (op);
445 9 : if (DECL_THUNK_P (fn)
446 12 : || lambda_static_thunk_p (fn))
447 : /* In a thunk, we pass through invisible reference parms, so this isn't
448 : actually a copy. */
449 : return false;
450 : }
451 :
452 20339208 : return
453 20339208 : (TREE_CODE (op) == EMPTY_CLASS_EXPR
454 20339178 : || code == MODIFY_EXPR
455 17253179 : || is_gimple_lvalue (op)
456 13660690 : || INDIRECT_REF_P (op)
457 13225270 : || (TREE_CODE (op) == CONSTRUCTOR
458 2927567 : && CONSTRUCTOR_NELTS (op) == 0)
459 10594824 : || (TREE_CODE (op) == CALL_EXPR
460 2791408 : && !CALL_EXPR_RETURN_SLOT_OPT (op)))
461 12424788 : && !TREE_CLOBBER_P (op)
462 32133032 : && is_really_empty_class (type, /*ignore_vptr*/true);
463 : }
464 :
465 : /* Returns true if evaluating E as an lvalue has side-effects;
466 : specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
467 : have side-effects until there is a read or write through it. */
468 :
469 : static bool
470 2743513 : lvalue_has_side_effects (tree e)
471 : {
472 2743513 : if (!TREE_SIDE_EFFECTS (e))
473 : return false;
474 60596 : while (handled_component_p (e))
475 : {
476 6448 : if (TREE_CODE (e) == ARRAY_REF
477 6448 : && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
478 : return true;
479 4627 : e = TREE_OPERAND (e, 0);
480 : }
481 54148 : if (DECL_P (e))
482 : /* Just naming a variable has no side-effects. */
483 : return false;
484 37142 : else if (INDIRECT_REF_P (e))
485 : /* Similarly, indirection has no side-effects. */
486 37005 : return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
487 : else
488 : /* For anything else, trust TREE_SIDE_EFFECTS. */
489 137 : return TREE_SIDE_EFFECTS (e);
490 : }
491 :
492 : /* Return true if FN is an immediate-escalating function. */
493 :
494 : bool
495 206729999 : immediate_escalating_function_p (tree fn)
496 : {
497 206729999 : if (!fn || !flag_immediate_escalation)
498 : return false;
499 :
500 206729531 : gcc_checking_assert (TREE_CODE (fn) == FUNCTION_DECL);
501 :
502 206729531 : if (DECL_IMMEDIATE_FUNCTION_P (fn))
503 : return false;
504 :
505 : /* An immediate-escalating function is
506 : -- the call operator of a lambda that is not declared with the consteval
507 : specifier */
508 210480577 : if (LAMBDA_FUNCTION_P (fn))
509 : return true;
510 : /* -- a non-user-provided defaulted function that is not declared with the
511 : consteval specifier */
512 204606529 : if (DECL_DEFAULTED_FN (fn) && !user_provided_p (fn))
513 : return true;
514 : /* -- a function that results from the instantiation of a templated entity
515 : defined with the constexpr specifier. */
516 196669644 : return is_instantiation_of_constexpr (fn);
517 : }
518 :
519 : /* Return true if FN is an immediate-escalating function that has not been
520 : checked for escalating expressions.. */
521 :
522 : static bool
523 206726626 : unchecked_immediate_escalating_function_p (tree fn)
524 : {
525 206726626 : return (immediate_escalating_function_p (fn)
526 206726626 : && !DECL_ESCALATION_CHECKED_P (fn));
527 : }
528 :
529 : /* Promote FN to an immediate function, including its clones. */
530 :
531 : void
532 2337 : promote_function_to_consteval (tree fn)
533 : {
534 2337 : SET_DECL_IMMEDIATE_FUNCTION_P (fn);
535 2337 : DECL_ESCALATION_CHECKED_P (fn) = true;
536 2337 : tree clone;
537 4865 : FOR_EACH_CLONE (clone, fn)
538 : {
539 2528 : SET_DECL_IMMEDIATE_FUNCTION_P (clone);
540 2528 : DECL_ESCALATION_CHECKED_P (clone) = true;
541 : }
542 2337 : }
543 :
544 : /* A wrapper around cp_fold_immediate_r. Return a non-null tree if
545 : we found a non-constant immediate function, or taking the address
546 : of an immediate function. */
547 :
548 : tree
549 16606884 : cp_fold_immediate (tree *tp, mce_value manifestly_const_eval,
550 : tree decl /*= current_function_decl*/)
551 : {
552 16606884 : if (cxx_dialect <= cxx17)
553 : return NULL_TREE;
554 :
555 16599506 : temp_override<tree> cfd (current_function_decl, decl);
556 :
557 16599506 : fold_flags_t flags = ff_none;
558 16599506 : if (manifestly_const_eval == mce_false)
559 9751631 : flags |= ff_mce_false;
560 :
561 16599506 : cp_fold_data data (flags);
562 16599506 : int save_errorcount = errorcount;
563 16599506 : tree r = cp_walk_tree (tp, cp_fold_immediate_r, &data, NULL);
564 16599506 : if (errorcount > save_errorcount)
565 49 : return integer_one_node;
566 : return r;
567 16599506 : }
568 :
569 : /* Maybe say that FN (a function decl with DECL_IMMEDIATE_FUNCTION_P set)
570 : was initially not an immediate function, but was promoted to one because
571 : its body contained an immediate-escalating expression or conversion. */
572 :
573 : static void
574 548 : maybe_explain_promoted_consteval (location_t loc, tree fn)
575 : {
576 548 : if (DECL_ESCALATION_CHECKED_P (fn))
577 : {
578 : /* See if we can figure out what made the function consteval. */
579 130 : tree x = cp_fold_immediate (&DECL_SAVED_TREE (fn), mce_unknown, NULL_TREE);
580 130 : if (x)
581 103 : inform (cp_expr_loc_or_loc (x, loc),
582 : "%qD was promoted to an immediate function because its "
583 : "body contains an immediate-escalating expression %qE", fn, x);
584 : else
585 27 : inform (loc, "%qD was promoted to an immediate function", fn);
586 : }
587 548 : }
588 :
589 : /* Gimplify *EXPR_P as rvalue into an expression that can't be modified
590 : by expressions with side-effects in other operands. */
591 :
592 : static enum gimplify_status
593 38304 : gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
594 : bool (*gimple_test_f) (tree))
595 : {
596 38304 : enum gimplify_status t
597 38304 : = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
598 38304 : if (t == GS_ERROR)
599 : return GS_ERROR;
600 38301 : else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
601 3112 : *expr_p = get_initialized_tmp_var (*expr_p, pre_p);
602 : return t;
603 : }
604 :
605 : /* Like gimplify_arg, but if ORDERED is set (which should be set if
606 : any of the arguments this argument is sequenced before has
607 : TREE_SIDE_EFFECTS set, make sure expressions with is_gimple_reg_type type
608 : are gimplified into SSA_NAME or a fresh temporary and for
609 : non-is_gimple_reg_type we don't optimize away TARGET_EXPRs. */
610 :
611 : static enum gimplify_status
612 4486508 : cp_gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
613 : bool ordered)
614 : {
615 4486508 : enum gimplify_status t;
616 4486508 : if (ordered
617 449130 : && !is_gimple_reg_type (TREE_TYPE (*arg_p))
618 4488399 : && TREE_CODE (*arg_p) == TARGET_EXPR)
619 : {
620 : /* gimplify_arg would strip away the TARGET_EXPR, but
621 : that can mean we don't copy the argument and some following
622 : argument with side-effect could modify it. */
623 1752 : protected_set_expr_location (*arg_p, call_location);
624 1752 : return gimplify_expr (arg_p, pre_p, NULL, is_gimple_lvalue, fb_either);
625 : }
626 : else
627 : {
628 4484756 : t = gimplify_arg (arg_p, pre_p, call_location);
629 4484756 : if (t == GS_ERROR)
630 : return GS_ERROR;
631 4484756 : else if (ordered
632 447378 : && is_gimple_reg_type (TREE_TYPE (*arg_p))
633 447239 : && is_gimple_variable (*arg_p)
634 225571 : && TREE_CODE (*arg_p) != SSA_NAME
635 : /* No need to force references into register, references
636 : can't be modified. */
637 138039 : && !TYPE_REF_P (TREE_TYPE (*arg_p))
638 : /* And this can't be modified either. */
639 4577024 : && *arg_p != current_class_ptr)
640 8632 : *arg_p = get_initialized_tmp_var (*arg_p, pre_p);
641 : return t;
642 : }
643 :
644 : }
645 :
646 : /* Emit a decl = {CLOBBER(bob)}; stmt before DECL_EXPR or first
647 : TARGET_EXPR gimplification for -flifetime-dse=2. */
648 :
649 : static void
650 1511957 : maybe_emit_clobber_object_begin (tree decl, gimple_seq *pre_p)
651 : {
652 1511957 : if (VAR_P (decl)
653 1511375 : && auto_var_p (decl)
654 1476020 : && TREE_TYPE (decl) != error_mark_node
655 1476002 : && DECL_NONTRIVIALLY_INITIALIZED_P (decl)
656 : /* Don't do it if it is fully initialized. */
657 912091 : && DECL_INITIAL (decl) == NULL_TREE
658 458181 : && !DECL_HAS_VALUE_EXPR_P (decl)
659 457864 : && !OPAQUE_TYPE_P (TREE_TYPE (decl))
660 : /* Nor going to have decl = .DEFERRED_INIT (...); added. */
661 1969817 : && (flag_auto_var_init == AUTO_INIT_UNINITIALIZED
662 86928 : || lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))
663 86928 : || lookup_attribute ("indeterminate", DECL_ATTRIBUTES (decl))))
664 : {
665 370933 : tree eltype = strip_array_types (TREE_TYPE (decl));
666 370933 : if (RECORD_OR_UNION_TYPE_P (eltype)
667 370933 : && !is_empty_class (eltype))
668 : {
669 155255 : tree clobber
670 155255 : = build_clobber (TREE_TYPE (decl), CLOBBER_OBJECT_BEGIN);
671 155255 : gimple *g = gimple_build_assign (decl, clobber);
672 155255 : gimple_set_location (g, DECL_SOURCE_LOCATION (decl));
673 155255 : gimple_seq_add_stmt_without_update (pre_p, g);
674 : }
675 : }
676 1511957 : }
677 :
678 : /* Do C++-specific gimplification. Args are as for gimplify_expr. */
679 :
680 : int
681 180014542 : cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
682 : {
683 180014542 : int saved_stmts_are_full_exprs_p = 0;
684 180014542 : location_t loc = cp_expr_loc_or_input_loc (*expr_p);
685 180014542 : enum tree_code code = TREE_CODE (*expr_p);
686 180014542 : enum gimplify_status ret;
687 :
688 180014542 : if (STATEMENT_CODE_P (code))
689 : {
690 4208608 : saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
691 8417216 : current_stmt_tree ()->stmts_are_full_exprs_p
692 4208608 : = STMT_IS_FULL_EXPR_P (*expr_p);
693 : }
694 :
695 180014542 : switch (code)
696 : {
697 376884 : case AGGR_INIT_EXPR:
698 376884 : simplify_aggr_init_expr (expr_p);
699 376884 : ret = GS_OK;
700 376884 : break;
701 :
702 0 : case VEC_INIT_EXPR:
703 0 : {
704 0 : *expr_p = expand_vec_init_expr (NULL_TREE, *expr_p,
705 : tf_warning_or_error);
706 :
707 0 : cp_fold_data data (ff_genericize | ff_mce_false);
708 0 : cp_walk_tree (expr_p, cp_fold_r, &data, NULL);
709 0 : cp_genericize_tree (expr_p, false);
710 0 : copy_if_shared (expr_p);
711 0 : ret = GS_OK;
712 0 : }
713 0 : break;
714 :
715 22745 : case THROW_EXPR:
716 : /* FIXME communicate throw type to back end, probably by moving
717 : THROW_EXPR into ../tree.def. */
718 22745 : *expr_p = TREE_OPERAND (*expr_p, 0);
719 22745 : ret = GS_OK;
720 22745 : break;
721 :
722 590747 : case MUST_NOT_THROW_EXPR:
723 590747 : ret = gimplify_must_not_throw_expr (expr_p, pre_p);
724 590747 : break;
725 :
726 : /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
727 : LHS of an assignment might also be involved in the RHS, as in bug
728 : 25979. */
729 12149514 : case INIT_EXPR:
730 12149514 : cp_gimplify_init_expr (expr_p);
731 12149514 : if (TREE_CODE (*expr_p) != INIT_EXPR)
732 : return GS_OK;
733 : /* Fall through. */
734 16310359 : case MODIFY_EXPR:
735 12032463 : modify_expr_case:
736 16310359 : {
737 : /* If the back end isn't clever enough to know that the lhs and rhs
738 : types are the same, add an explicit conversion. */
739 16310359 : tree op0 = TREE_OPERAND (*expr_p, 0);
740 16310359 : tree op1 = TREE_OPERAND (*expr_p, 1);
741 :
742 16310359 : if (!error_operand_p (op0)
743 16310359 : && !error_operand_p (op1)
744 16310340 : && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
745 16307339 : || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
746 16313369 : && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
747 9 : TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
748 9 : TREE_TYPE (op0), op1);
749 :
750 16310350 : else if (simple_empty_class_p (TREE_TYPE (op0), op1, code))
751 : {
752 223894 : while (TREE_CODE (op1) == TARGET_EXPR)
753 : /* We're disconnecting the initializer from its target,
754 : don't create a temporary. */
755 6966 : op1 = TARGET_EXPR_INITIAL (op1);
756 :
757 : /* Remove any copies of empty classes. Also drop volatile
758 : variables on the RHS to avoid infinite recursion from
759 : gimplify_expr trying to load the value. */
760 216928 : if (TREE_SIDE_EFFECTS (op1))
761 : {
762 16173 : if (TREE_THIS_VOLATILE (op1)
763 0 : && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
764 0 : op1 = build_fold_addr_expr (op1);
765 :
766 16173 : suppress_warning (op1, OPT_Wunused_result);
767 16173 : gimplify_and_add (op1, pre_p);
768 : }
769 216928 : gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
770 : is_gimple_lvalue, fb_lvalue);
771 216928 : *expr_p = TREE_OPERAND (*expr_p, 0);
772 216928 : if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p))
773 : /* Avoid 'return *<retval>;' */
774 1267 : *expr_p = TREE_OPERAND (*expr_p, 0);
775 : }
776 : /* P0145 says that the RHS is sequenced before the LHS.
777 : gimplify_modify_expr gimplifies the RHS before the LHS, but that
778 : isn't quite strong enough in two cases:
779 :
780 : 1) gimplify.cc wants to leave a CALL_EXPR on the RHS, which would
781 : mean it's evaluated after the LHS.
782 :
783 : 2) the value calculation of the RHS is also sequenced before the
784 : LHS, so for scalar assignment we need to preevaluate if the
785 : RHS could be affected by LHS side-effects even if it has no
786 : side-effects of its own. We don't need this for classes because
787 : class assignment takes its RHS by reference. */
788 16093422 : else if (flag_strong_eval_order > 1
789 14718460 : && TREE_CODE (*expr_p) == MODIFY_EXPR
790 2743513 : && lvalue_has_side_effects (op0)
791 16132241 : && (TREE_CODE (op1) == CALL_EXPR
792 31801 : || (SCALAR_TYPE_P (TREE_TYPE (op1))
793 25249 : && !TREE_CONSTANT (op1))))
794 21775 : TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);
795 : }
796 : ret = GS_OK;
797 : break;
798 :
799 100198 : case EMPTY_CLASS_EXPR:
800 : /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
801 100198 : *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
802 100198 : ret = GS_OK;
803 100198 : break;
804 :
805 0 : case BASELINK:
806 0 : *expr_p = BASELINK_FUNCTIONS (*expr_p);
807 0 : ret = GS_OK;
808 0 : break;
809 :
810 19247 : case TRY_BLOCK:
811 19247 : genericize_try_block (expr_p);
812 19247 : ret = GS_OK;
813 19247 : break;
814 :
815 22423 : case HANDLER:
816 22423 : genericize_catch_block (expr_p);
817 22423 : ret = GS_OK;
818 22423 : break;
819 :
820 5841 : case EH_SPEC_BLOCK:
821 5841 : genericize_eh_spec_block (expr_p);
822 5841 : ret = GS_OK;
823 5841 : break;
824 :
825 0 : case USING_STMT:
826 0 : gcc_unreachable ();
827 :
828 0 : case FOR_STMT:
829 0 : case WHILE_STMT:
830 0 : case DO_STMT:
831 0 : case SWITCH_STMT:
832 0 : case CONTINUE_STMT:
833 0 : case BREAK_STMT:
834 0 : gcc_unreachable ();
835 :
836 45617 : case OMP_FOR:
837 45617 : case OMP_SIMD:
838 45617 : case OMP_DISTRIBUTE:
839 45617 : case OMP_LOOP:
840 45617 : case OMP_TASKLOOP:
841 45617 : case OMP_TILE:
842 45617 : case OMP_UNROLL:
843 45617 : ret = cp_gimplify_omp_for (expr_p, pre_p);
844 45617 : break;
845 :
846 4161097 : case EXPR_STMT:
847 4161097 : gimplify_expr_stmt (expr_p);
848 4161097 : ret = GS_OK;
849 4161097 : break;
850 :
851 0 : case UNARY_PLUS_EXPR:
852 0 : {
853 0 : tree arg = TREE_OPERAND (*expr_p, 0);
854 0 : tree type = TREE_TYPE (*expr_p);
855 0 : *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
856 : : arg;
857 0 : ret = GS_OK;
858 : }
859 0 : break;
860 :
861 9048891 : case CALL_EXPR:
862 9048891 : ret = GS_OK;
863 9048891 : if (flag_strong_eval_order == 2
864 8541631 : && CALL_EXPR_FN (*expr_p)
865 8164646 : && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)
866 16291936 : && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
867 : {
868 38304 : tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
869 38304 : enum gimplify_status t
870 38304 : = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
871 : is_gimple_call_addr);
872 38304 : if (t == GS_ERROR)
873 : ret = GS_ERROR;
874 : /* GIMPLE considers most pointer conversion useless, but for
875 : calls we actually care about the exact function pointer type. */
876 38301 : else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
877 9107 : CALL_EXPR_FN (*expr_p)
878 18214 : = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
879 : }
880 9048891 : if (!CALL_EXPR_FN (*expr_p))
881 : /* Internal function call. */
882 399572 : switch (CALL_EXPR_IFN (*expr_p))
883 : {
884 36 : case IFN_BSWAP:
885 36 : case IFN_BITREVERSE:
886 36 : if (ret == GS_OK)
887 : {
888 36 : location_t loc = EXPR_LOCATION (*expr_p);
889 36 : internal_fn ifn = CALL_EXPR_IFN (*expr_p);
890 36 : tree arg = CALL_EXPR_ARG (*expr_p, 0);
891 36 : tree r = fold_build_builtin_bswapg_bitreverseg (loc, ifn,
892 : arg);
893 36 : if (TREE_CODE (r) == CALL_EXPR
894 27 : && !CALL_EXPR_FN (r)
895 36 : && CALL_EXPR_IFN (r) == ifn)
896 : break;
897 36 : *expr_p = r;
898 36 : return ret;
899 : }
900 : break;
901 : default:
902 : break;
903 : }
904 8649319 : else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
905 : {
906 : /* This is a call to a (compound) assignment operator that used
907 : the operator syntax; gimplify the RHS first. */
908 50758 : gcc_assert (call_expr_nargs (*expr_p) == 2);
909 50758 : gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
910 50758 : enum gimplify_status t
911 50758 : = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc,
912 50758 : TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, 0)));
913 50758 : if (t == GS_ERROR)
914 : ret = GS_ERROR;
915 : }
916 8598561 : else if (CALL_EXPR_ORDERED_ARGS (*expr_p))
917 : {
918 : /* Leave the last argument for gimplify_call_expr, to avoid problems
919 : with __builtin_va_arg_pack(). */
920 329788 : int nargs = call_expr_nargs (*expr_p) - 1;
921 329788 : int last_side_effects_arg = -1;
922 650079 : for (int i = nargs; i > 0; --i)
923 348302 : if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
924 : {
925 : last_side_effects_arg = i;
926 : break;
927 : }
928 689353 : for (int i = 0; i < nargs; ++i)
929 : {
930 359565 : enum gimplify_status t
931 359565 : = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc,
932 : i < last_side_effects_arg);
933 359565 : if (t == GS_ERROR)
934 0 : ret = GS_ERROR;
935 : }
936 : }
937 8268773 : else if (flag_strong_eval_order
938 8268773 : && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
939 : {
940 : /* If flag_strong_eval_order, evaluate the object argument first. */
941 7660921 : tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
942 7660921 : if (INDIRECT_TYPE_P (fntype))
943 7660918 : fntype = TREE_TYPE (fntype);
944 7660921 : tree decl = cp_get_callee_fndecl_nofold (*expr_p);
945 : /* We can't just rely on 'decl' because virtual function callees
946 : are expressed as OBJ_TYPE_REF. Note that the xobj memfn check
947 : will also hold for calls of the form (&A::f)(a, ...) which does
948 : not require such sequencing, though it's allowed under
949 : "indeterminately sequenced". */
950 7660921 : if (TREE_CODE (fntype) == METHOD_TYPE
951 7660921 : || (decl && DECL_LANG_SPECIFIC (decl)
952 3573990 : && DECL_XOBJ_MEMBER_FUNCTION_P (decl)))
953 : {
954 4076185 : int nargs = call_expr_nargs (*expr_p);
955 4076185 : bool side_effects = false;
956 5737656 : for (int i = 1; i < nargs; ++i)
957 2065621 : if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
958 : {
959 : side_effects = true;
960 : break;
961 : }
962 4076185 : enum gimplify_status t
963 4076185 : = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc,
964 : side_effects);
965 4076185 : if (t == GS_ERROR)
966 : ret = GS_ERROR;
967 : }
968 : }
969 9048855 : if (ret != GS_ERROR)
970 : {
971 9048852 : tree decl = cp_get_callee_fndecl_nofold (*expr_p);
972 9048852 : if (!decl)
973 : break;
974 8606054 : if (fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
975 81 : switch (DECL_FE_FUNCTION_CODE (decl))
976 : {
977 0 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
978 0 : *expr_p = boolean_false_node;
979 0 : break;
980 0 : case CP_BUILT_IN_SOURCE_LOCATION:
981 0 : *expr_p
982 0 : = fold_builtin_source_location (*expr_p);
983 0 : break;
984 0 : case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
985 0 : *expr_p
986 0 : = fold_builtin_is_corresponding_member
987 0 : (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
988 : &CALL_EXPR_ARG (*expr_p, 0));
989 0 : break;
990 0 : case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
991 0 : *expr_p
992 0 : = fold_builtin_is_pointer_inverconvertible_with_class
993 0 : (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
994 : &CALL_EXPR_ARG (*expr_p, 0));
995 0 : break;
996 0 : case CP_BUILT_IN_EH_PTR_ADJUST_REF:
997 0 : error_at (EXPR_LOCATION (*expr_p),
998 : "%qs used outside of constant expressions",
999 : "__builtin_eh_ptr_adjust_ref");
1000 0 : *expr_p = void_node;
1001 0 : break;
1002 9 : case CP_BUILT_IN_CURRENT_EXCEPTION:
1003 9 : case CP_BUILT_IN_UNCAUGHT_EXCEPTIONS:
1004 9 : {
1005 9 : const char *name
1006 : = (DECL_FE_FUNCTION_CODE (decl)
1007 : == CP_BUILT_IN_CURRENT_EXCEPTION
1008 9 : ? "current_exception" : "uncaught_exceptions");
1009 9 : tree newdecl = lookup_qualified_name (std_node, name);
1010 9 : if (error_operand_p (newdecl))
1011 0 : *expr_p = build_zero_cst (TREE_TYPE (*expr_p));
1012 9 : else if (TREE_CODE (newdecl) != FUNCTION_DECL
1013 9 : || !same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
1014 : TREE_TYPE (TREE_TYPE (decl)))
1015 18 : || (TYPE_ARG_TYPES (TREE_TYPE (newdecl))
1016 9 : != void_list_node))
1017 : {
1018 0 : error_at (EXPR_LOCATION (*expr_p),
1019 : "unexpected %<std::%s%> declaration",
1020 : name);
1021 0 : *expr_p = build_zero_cst (TREE_TYPE (*expr_p));
1022 : }
1023 : else
1024 9 : *expr_p = build_call_expr_loc (EXPR_LOCATION (*expr_p),
1025 : newdecl, 0);
1026 : break;
1027 : }
1028 0 : case CP_BUILT_IN_IS_STRING_LITERAL:
1029 0 : *expr_p
1030 0 : = fold_builtin_is_string_literal (EXPR_LOCATION (*expr_p),
1031 0 : call_expr_nargs (*expr_p),
1032 : &CALL_EXPR_ARG (*expr_p,
1033 : 0));
1034 0 : break;
1035 0 : case CP_BUILT_IN_CONSTEXPR_DIAG:
1036 0 : *expr_p = void_node;
1037 0 : break;
1038 72 : case CP_BUILT_IN_START_LIFETIME:
1039 72 : *expr_p = fold_convert (void_type_node,
1040 : CALL_EXPR_ARG (*expr_p, 0));
1041 72 : break;
1042 : default:
1043 : break;
1044 : }
1045 8605973 : else if (fndecl_built_in_p (decl, BUILT_IN_CLZG, BUILT_IN_CTZG))
1046 33 : ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p,
1047 : post_p);
1048 : else
1049 : /* All consteval functions should have been processed by now. */
1050 8605940 : gcc_checking_assert (!immediate_invocation_p (decl));
1051 : }
1052 : break;
1053 :
1054 714003 : case TARGET_EXPR:
1055 : /* A TARGET_EXPR that expresses direct-initialization should have been
1056 : elided by cp_gimplify_init_expr. */
1057 714003 : gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
1058 : /* Likewise, but allow extra temps of trivial type so that
1059 : gimplify_init_ctor_preeval can materialize subobjects of a CONSTRUCTOR
1060 : on the rhs of an assignment, as in constexpr-aggr1.C. */
1061 714003 : gcc_checking_assert (!TARGET_EXPR_ELIDING_P (*expr_p)
1062 : || !TREE_ADDRESSABLE (TREE_TYPE (*expr_p)));
1063 714003 : if (flag_lifetime_dse > 1
1064 713875 : && TARGET_EXPR_INITIAL (*expr_p)
1065 1418850 : && VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (*expr_p))))
1066 261605 : maybe_emit_clobber_object_begin (TARGET_EXPR_SLOT (*expr_p), pre_p);
1067 : ret = GS_UNHANDLED;
1068 : break;
1069 :
1070 3 : case PTRMEM_CST:
1071 3 : *expr_p = cplus_expand_constant (*expr_p);
1072 3 : if (TREE_CODE (*expr_p) == PTRMEM_CST)
1073 : ret = GS_ERROR;
1074 : else
1075 179897455 : ret = GS_OK;
1076 : break;
1077 :
1078 1250580 : case DECL_EXPR:
1079 1250580 : if (flag_lifetime_dse > 1)
1080 1250352 : maybe_emit_clobber_object_begin (DECL_EXPR_DECL (*expr_p), pre_p);
1081 : ret = GS_UNHANDLED;
1082 : break;
1083 :
1084 1261105 : case RETURN_EXPR:
1085 1261105 : if (TREE_OPERAND (*expr_p, 0)
1086 1261105 : && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
1087 13250 : || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
1088 : {
1089 1191897 : expr_p = &TREE_OPERAND (*expr_p, 0);
1090 : /* Avoid going through the INIT_EXPR case, which can
1091 : degrade INIT_EXPRs into AGGR_INIT_EXPRs. */
1092 1191897 : goto modify_expr_case;
1093 : }
1094 : /* Fall through. */
1095 :
1096 147228856 : default:
1097 147228856 : ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
1098 147228856 : break;
1099 : }
1100 :
1101 : /* Restore saved state. */
1102 179897455 : if (STATEMENT_CODE_P (code))
1103 4208608 : current_stmt_tree ()->stmts_are_full_exprs_p
1104 4208608 : = saved_stmts_are_full_exprs_p;
1105 :
1106 : return ret;
1107 : }
1108 :
1109 : bool
1110 2068379703 : is_invisiref_parm (const_tree t)
1111 : {
1112 1938705846 : return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
1113 2113914557 : && DECL_BY_REFERENCE (t));
1114 : }
1115 :
1116 : /* A stable comparison routine for use with splay trees and DECLs. */
1117 :
1118 : static int
1119 62362 : splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
1120 : {
1121 62362 : tree a = (tree) xa;
1122 62362 : tree b = (tree) xb;
1123 :
1124 62362 : return DECL_UID (a) - DECL_UID (b);
1125 : }
1126 :
1127 : /* OpenMP context during genericization. */
1128 :
1129 : struct cp_genericize_omp_taskreg
1130 : {
1131 : bool is_parallel;
1132 : bool default_shared;
1133 : struct cp_genericize_omp_taskreg *outer;
1134 : splay_tree variables;
1135 : };
1136 :
1137 : /* Return true if genericization should try to determine if
1138 : DECL is firstprivate or shared within task regions. */
1139 :
1140 : static bool
1141 119550 : omp_var_to_track (tree decl)
1142 : {
1143 119550 : tree type = TREE_TYPE (decl);
1144 119550 : if (is_invisiref_parm (decl))
1145 537 : type = TREE_TYPE (type);
1146 119013 : else if (TYPE_REF_P (type))
1147 4249 : type = TREE_TYPE (type);
1148 144559 : while (TREE_CODE (type) == ARRAY_TYPE)
1149 25009 : type = TREE_TYPE (type);
1150 119550 : if (type == error_mark_node || !CLASS_TYPE_P (type))
1151 : return false;
1152 14084 : if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
1153 : return false;
1154 14081 : if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
1155 57 : return false;
1156 : return true;
1157 : }
1158 :
1159 : /* Note DECL use in OpenMP region OMP_CTX during genericization. */
1160 :
1161 : static void
1162 14267 : omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
1163 : {
1164 14267 : splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
1165 : (splay_tree_key) decl);
1166 14267 : if (n == NULL)
1167 : {
1168 4319 : int flags = OMP_CLAUSE_DEFAULT_SHARED;
1169 4319 : if (omp_ctx->outer)
1170 1257 : omp_cxx_notice_variable (omp_ctx->outer, decl);
1171 4319 : if (!omp_ctx->default_shared)
1172 : {
1173 948 : struct cp_genericize_omp_taskreg *octx;
1174 :
1175 1065 : for (octx = omp_ctx->outer; octx; octx = octx->outer)
1176 : {
1177 902 : n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
1178 902 : if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
1179 : {
1180 : flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
1181 : break;
1182 : }
1183 859 : if (octx->is_parallel)
1184 : break;
1185 : }
1186 948 : if (octx == NULL
1187 948 : && (TREE_CODE (decl) == PARM_DECL
1188 120 : || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1189 41 : && DECL_CONTEXT (decl) == current_function_decl)))
1190 : flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
1191 864 : if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
1192 : {
1193 : /* DECL is implicitly determined firstprivate in
1194 : the current task construct. Ensure copy ctor and
1195 : dtor are instantiated, because during gimplification
1196 : it will be already too late. */
1197 127 : tree type = TREE_TYPE (decl);
1198 127 : if (is_invisiref_parm (decl))
1199 2 : type = TREE_TYPE (type);
1200 125 : else if (TYPE_REF_P (type))
1201 52 : type = TREE_TYPE (type);
1202 177 : while (TREE_CODE (type) == ARRAY_TYPE)
1203 50 : type = TREE_TYPE (type);
1204 127 : get_copy_ctor (type, tf_none);
1205 127 : get_dtor (type, tf_none);
1206 : }
1207 : }
1208 4319 : splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
1209 : }
1210 14267 : }
1211 :
1212 : /* True if any of the element initializers in CTOR are TARGET_EXPRs that are
1213 : not expected to elide, e.g. because unsafe_copy_elision_p is true. */
1214 :
1215 : static bool
1216 133978 : any_non_eliding_target_exprs (tree ctor)
1217 : {
1218 623238 : for (const constructor_elt &e : *CONSTRUCTOR_ELTS (ctor))
1219 : {
1220 489263 : if (TREE_CODE (e.value) == TARGET_EXPR
1221 489263 : && !TARGET_EXPR_ELIDING_P (e.value))
1222 : return true;
1223 : }
1224 : return false;
1225 : }
1226 :
1227 : /* If we might need to clean up a partially constructed object, break down the
1228 : CONSTRUCTOR with split_nonconstant_init. Also expand VEC_INIT_EXPR at this
1229 : point. If initializing TO with FROM is non-trivial, overwrite *REPLACE with
1230 : the result. */
1231 :
1232 : static void
1233 84582751 : cp_genericize_init (tree *replace, tree from, tree to, vec<tree,va_gc>** flags)
1234 : {
1235 84582751 : tree init = NULL_TREE;
1236 84582751 : if (TREE_CODE (from) == VEC_INIT_EXPR)
1237 999 : init = expand_vec_init_expr (to, from, tf_warning_or_error, flags);
1238 84581752 : else if (TREE_CODE (from) == CONSTRUCTOR
1239 4858932 : && TREE_SIDE_EFFECTS (from)
1240 84717130 : && ((flag_exceptions
1241 135291 : && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (from)))
1242 133978 : || any_non_eliding_target_exprs (from)))
1243 : {
1244 1403 : to = cp_stabilize_reference (to);
1245 1403 : replace_placeholders (from, to);
1246 1403 : init = split_nonconstant_init (to, from);
1247 : }
1248 :
1249 2402 : if (init)
1250 : {
1251 2402 : if (*replace == from)
1252 : /* Make cp_gimplify_init_expr call replace_decl on this
1253 : TARGET_EXPR_INITIAL. */
1254 724 : init = fold_convert (void_type_node, init);
1255 2402 : *replace = init;
1256 : }
1257 84582751 : }
1258 :
1259 : /* For an INIT_EXPR, replace the INIT_EXPR itself. */
1260 :
1261 : static void
1262 63620295 : cp_genericize_init_expr (tree *stmt_p)
1263 : {
1264 63620295 : iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
1265 63620295 : tree to = TREE_OPERAND (*stmt_p, 0);
1266 63620295 : tree from = TREE_OPERAND (*stmt_p, 1);
1267 6646285 : if (SIMPLE_TARGET_EXPR_P (from)
1268 : /* Return gets confused if we clobber its INIT_EXPR this soon. */
1269 68567316 : && TREE_CODE (to) != RESULT_DECL)
1270 176070 : from = TARGET_EXPR_INITIAL (from);
1271 63620295 : cp_genericize_init (stmt_p, from, to, nullptr);
1272 63620295 : }
1273 :
1274 : /* For a TARGET_EXPR, change the TARGET_EXPR_INITIAL. We will need to use
1275 : replace_decl later when we know what we're initializing. */
1276 :
1277 : static void
1278 20962456 : cp_genericize_target_expr (tree *stmt_p)
1279 : {
1280 20962456 : iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
1281 20962456 : tree slot = TARGET_EXPR_SLOT (*stmt_p);
1282 20962456 : vec<tree, va_gc> *flags = make_tree_vector ();
1283 20962456 : cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p),
1284 20962456 : TARGET_EXPR_INITIAL (*stmt_p), slot, &flags);
1285 20962456 : gcc_assert (!DECL_INITIAL (slot));
1286 62887400 : for (tree f : flags)
1287 : {
1288 : /* Once initialization is complete TARGET_EXPR_CLEANUP becomes active, so
1289 : disable any subobject cleanups. */
1290 32 : tree d = build_disable_temp_cleanup (f);
1291 32 : auto &r = TARGET_EXPR_INITIAL (*stmt_p);
1292 32 : r = add_stmt_to_compound (r, d);
1293 : }
1294 20962456 : release_tree_vector (flags);
1295 20962456 : }
1296 :
1297 : /* Similar to if (target_expr_needs_replace) replace_decl, but TP is the
1298 : TARGET_EXPR_INITIAL, and this also updates *_SLOT. We need this extra
1299 : replacement when cp_folding TARGET_EXPR to preserve the invariant that
1300 : AGGR_INIT_EXPR_SLOT agrees with the enclosing TARGET_EXPR_SLOT. */
1301 :
1302 : static bool
1303 130 : maybe_replace_decl (tree *tp, tree decl, tree replacement)
1304 : {
1305 130 : if (!*tp || !VOID_TYPE_P (TREE_TYPE (*tp)))
1306 : return false;
1307 50 : tree t = *tp;
1308 50 : while (TREE_CODE (t) == COMPOUND_EXPR)
1309 0 : t = TREE_OPERAND (t, 1);
1310 50 : if (TREE_CODE (t) == AGGR_INIT_EXPR)
1311 50 : replace_decl (&AGGR_INIT_EXPR_SLOT (t), decl, replacement);
1312 0 : else if (TREE_CODE (t) == VEC_INIT_EXPR)
1313 0 : replace_decl (&VEC_INIT_EXPR_SLOT (t), decl, replacement);
1314 : else
1315 0 : replace_decl (tp, decl, replacement);
1316 : return true;
1317 : }
1318 :
1319 : /* Genericization context. */
1320 :
1321 52206258 : struct cp_genericize_data
1322 : {
1323 : hash_set<tree> *p_set;
1324 : auto_vec<tree> bind_expr_stack;
1325 : struct cp_genericize_omp_taskreg *omp_ctx;
1326 : tree try_block;
1327 : bool no_sanitize_p;
1328 : bool handle_invisiref_parm_p;
1329 : };
1330 :
1331 : /* Emit an error about taking the address of an immediate function.
1332 : EXPR is the whole expression; DECL is the immediate function. */
1333 :
1334 : static void
1335 71 : taking_address_of_imm_fn_error (tree expr, tree decl)
1336 : {
1337 71 : auto_diagnostic_group d;
1338 71 : const location_t loc = (TREE_CODE (expr) == PTRMEM_CST
1339 71 : ? PTRMEM_CST_LOCATION (expr)
1340 71 : : EXPR_LOCATION (expr));
1341 71 : error_at (loc, "taking address of an immediate function %qD", decl);
1342 71 : maybe_explain_promoted_consteval (loc, decl);
1343 71 : }
1344 :
1345 : /* Build up an INIT_EXPR to initialize the object of a constructor call that
1346 : has been folded to a constant value. CALL is the CALL_EXPR for the
1347 : constructor call; INIT is the value. */
1348 :
1349 : static tree
1350 489 : cp_build_init_expr_for_ctor (tree call, tree init)
1351 : {
1352 489 : tree a = CALL_EXPR_ARG (call, 0);
1353 489 : if (is_dummy_object (a))
1354 : return init;
1355 489 : const bool return_this = targetm.cxx.cdtor_returns_this ();
1356 489 : const location_t loc = EXPR_LOCATION (call);
1357 489 : if (return_this)
1358 0 : a = cp_save_expr (a);
1359 489 : tree s = build_fold_indirect_ref_loc (loc, a);
1360 489 : init = cp_build_init_expr (s, init);
1361 489 : if (return_this)
1362 : {
1363 0 : init = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (call), init,
1364 0 : fold_convert_loc (loc, TREE_TYPE (call), a));
1365 0 : suppress_warning (init);
1366 : }
1367 : return init;
1368 : }
1369 :
1370 : /* A walk_tree callback for cp_fold_function and cp_fully_fold_init to handle
1371 : immediate functions. */
1372 :
1373 : static tree
1374 3275388206 : cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_)
1375 : {
1376 3275388206 : auto data = static_cast<cp_fold_data *>(data_);
1377 3275388206 : tree stmt = *stmt_p;
1378 : /* The purpose of this is not to emit errors for mce_unknown. */
1379 3275388206 : const tsubst_flags_t complain = (data->flags & ff_mce_false
1380 3275388206 : ? tf_error : tf_none);
1381 3275388206 : const tree_code code = TREE_CODE (stmt);
1382 :
1383 : /* No need to look into types or unevaluated operands.
1384 : NB: This affects cp_fold_r as well. */
1385 3275388206 : if (TYPE_P (stmt)
1386 3272955358 : || unevaluated_p (code)
1387 : /* We do not use in_immediate_context here because it checks
1388 : more than is desirable, e.g., sk_template_parms. */
1389 3272600597 : || cp_unevaluated_operand
1390 6547988803 : || (current_function_decl
1391 6364010880 : && DECL_IMMEDIATE_FUNCTION_P (current_function_decl)))
1392 : {
1393 2808230 : *walk_subtrees = 0;
1394 2808230 : return NULL_TREE;
1395 : }
1396 :
1397 3272579976 : tree decl = NULL_TREE;
1398 3272579976 : bool call_p = false;
1399 :
1400 : /* We are looking for &fn or fn(). */
1401 3272579976 : switch (code)
1402 : {
1403 37162153 : case DECL_EXPR:
1404 : /* Clear consteval-only DECL_EXPRs. */
1405 37162153 : if (flag_reflection)
1406 : {
1407 767706 : tree d = DECL_EXPR_DECL (stmt);
1408 767706 : if (VAR_P (d) && consteval_only_p (d))
1409 884 : *stmt_p = void_node;
1410 : }
1411 : break;
1412 158064264 : case CALL_EXPR:
1413 158064264 : case AGGR_INIT_EXPR:
1414 158064264 : if (tree fn = cp_get_callee (stmt))
1415 157748389 : if (TREE_CODE (fn) != ADDR_EXPR || ADDR_EXPR_DENOTES_CALL_P (fn))
1416 150917771 : decl = cp_get_fndecl_from_callee (fn, /*fold*/false);
1417 : call_p = true;
1418 : break;
1419 33250 : case PTRMEM_CST:
1420 33250 : decl = PTRMEM_CST_MEMBER (stmt);
1421 33250 : break;
1422 239118220 : case ADDR_EXPR:
1423 239118220 : if (!ADDR_EXPR_DENOTES_CALL_P (stmt))
1424 89940193 : decl = TREE_OPERAND (stmt, 0);
1425 : break;
1426 21927891 : case IF_STMT:
1427 21927891 : if (IF_STMT_CONSTEVAL_P (stmt))
1428 : {
1429 78890 : if (!data->pset.add (stmt))
1430 78890 : cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_immediate_r, data_,
1431 : nullptr);
1432 78890 : *walk_subtrees = 0;
1433 78890 : return NULL_TREE;
1434 : }
1435 : /* FALLTHRU */
1436 2838123199 : default:
1437 2838123199 : if (data->pset.add (stmt))
1438 484537982 : *walk_subtrees = 0;
1439 : return NULL_TREE;
1440 : }
1441 :
1442 240892098 : if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
1443 : return NULL_TREE;
1444 :
1445 : /* Fully escalate once all templates have been instantiated. What we're
1446 : calling is not a consteval function but it may become one. This
1447 : requires recursing; DECL may be promoted to consteval because it
1448 : contains an escalating expression E, but E itself may have to be
1449 : promoted first, etc. */
1450 157518585 : if (at_eof > 1 && unchecked_immediate_escalating_function_p (decl))
1451 : {
1452 : /* Set before the actual walk to avoid endless recursion. */
1453 6057083 : DECL_ESCALATION_CHECKED_P (decl) = true;
1454 : /* We're only looking for the first escalating expression. Let us not
1455 : walk more trees than necessary, hence mce_unknown. */
1456 6057083 : cp_fold_immediate (&DECL_SAVED_TREE (decl), mce_unknown, decl);
1457 : }
1458 :
1459 : /* [expr.const]p16 "An expression or conversion is immediate-escalating if
1460 : it is not initially in an immediate function context and it is either
1461 : -- an immediate invocation that is not a constant expression and is not
1462 : a subexpression of an immediate invocation."
1463 :
1464 : If we are in an immediate-escalating function, the immediate-escalating
1465 : expression or conversion makes it an immediate function. So STMT does
1466 : not need to produce a constant expression. */
1467 315037170 : if (DECL_IMMEDIATE_FUNCTION_P (decl))
1468 : {
1469 479985 : tree e = cxx_constant_value (stmt, tf_none);
1470 479985 : if (e == error_mark_node)
1471 : {
1472 : /* This takes care of, e.g.,
1473 : template <typename T>
1474 : constexpr int f(T t)
1475 : {
1476 : return id(t);
1477 : }
1478 : where id (consteval) causes f<int> to be promoted. */
1479 2915 : if (immediate_escalating_function_p (current_function_decl))
1480 2267 : promote_function_to_consteval (current_function_decl);
1481 648 : else if (complain & tf_error)
1482 : {
1483 536 : if (call_p)
1484 : {
1485 477 : auto_diagnostic_group d;
1486 477 : location_t loc = cp_expr_loc_or_input_loc (stmt);
1487 477 : error_at (loc, "call to consteval function %qE is "
1488 : "not a constant expression", stmt);
1489 : /* Explain why it's not a constant expression. */
1490 477 : cxx_constant_value (stmt, complain);
1491 477 : *stmt_p = error_mark_node;
1492 477 : maybe_explain_promoted_consteval (loc, decl);
1493 477 : }
1494 59 : else if (!data->pset.add (stmt))
1495 : {
1496 59 : taking_address_of_imm_fn_error (stmt, decl);
1497 59 : *stmt_p = build_zero_cst (TREE_TYPE (stmt));
1498 : }
1499 : /* If we're giving hard errors, continue the walk rather than
1500 : bailing out after the first error. */
1501 : return NULL_TREE;
1502 : }
1503 2379 : *walk_subtrees = 0;
1504 2379 : return stmt;
1505 : }
1506 :
1507 : /* We've evaluated the consteval function call. */
1508 477070 : if (call_p)
1509 : {
1510 573774 : if (code == CALL_EXPR && DECL_CONSTRUCTOR_P (decl))
1511 0 : *stmt_p = cp_build_init_expr_for_ctor (stmt, e);
1512 : else
1513 477070 : *stmt_p = e;
1514 : }
1515 : }
1516 : /* We've encountered a function call that may turn out to be consteval
1517 : later. Store its caller so that we can ensure that the call is
1518 : a constant expression. */
1519 157038600 : else if (unchecked_immediate_escalating_function_p (decl))
1520 : {
1521 : /* Make sure we're not inserting new elements while walking
1522 : the deferred_escalating_exprs hash table; if we are, it's
1523 : likely that a function wasn't properly marked checked for
1524 : i-e expressions. */
1525 26702682 : gcc_checking_assert (at_eof <= 1);
1526 26702682 : if (current_function_decl)
1527 26702158 : remember_escalating_expr (current_function_decl);
1528 : /* auto p = &f<int>; in the global scope won't be ensconced in
1529 : a function we could store for later at this point. (If there's
1530 : no c_f_d at this point and we're dealing with a call, we should
1531 : see the call when cp_fold_function __static_i_and_d.) */
1532 524 : else if (!call_p)
1533 143 : remember_escalating_expr (stmt);
1534 : }
1535 :
1536 : return NULL_TREE;
1537 : }
1538 :
1539 : /* A walk_tree helper to replace constant-initialized references in an
1540 : OMP_CLAUSE with the the declaration that they refer to. Such refs
1541 : will have been folded out in the body by cp_fold_non_odr_use_1 and
1542 : so we need to follow suit to prevent confusion. */
1543 :
1544 : static tree
1545 98164 : cp_fold_omp_clause_refs_r (tree *expr_p, int *walk_subtrees, void */*data*/)
1546 : {
1547 98164 : tree expr = *expr_p;
1548 :
1549 98164 : if (TYPE_P (expr))
1550 : {
1551 0 : *walk_subtrees = 0;
1552 0 : return NULL_TREE;
1553 : }
1554 :
1555 98164 : if (DECL_P (expr))
1556 : {
1557 53831 : *walk_subtrees = 0;
1558 :
1559 53831 : if (decl_constant_var_p (expr)
1560 53831 : && TYPE_REF_P (TREE_TYPE (expr)))
1561 : {
1562 532 : tree init = maybe_constant_value (expr);
1563 532 : if (TREE_CONSTANT (init))
1564 532 : *expr_p = tree_strip_nop_conversions (init);
1565 : }
1566 : }
1567 :
1568 : return NULL_TREE;
1569 : }
1570 :
1571 : /* Perform any pre-gimplification folding of C++ front end trees to
1572 : GENERIC.
1573 : Note: The folding of non-omp cases is something to move into
1574 : the middle-end. As for now we have most foldings only on GENERIC
1575 : in fold-const, we need to perform this before transformation to
1576 : GIMPLE-form.
1577 :
1578 : ??? This is algorithmically weird because walk_tree works in pre-order, so
1579 : we see outer expressions before inner expressions. This isn't as much of an
1580 : issue because cp_fold recurses into subexpressions in many cases, but then
1581 : walk_tree walks back into those subexpressions again. We avoid the
1582 : resulting complexity problem by caching the result of cp_fold, but it's
1583 : inelegant. */
1584 :
1585 : static tree
1586 4500649763 : cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
1587 : {
1588 4500649763 : cp_fold_data *data = (cp_fold_data*)data_;
1589 4500649763 : tree stmt = *stmt_p;
1590 4500649763 : enum tree_code code = TREE_CODE (stmt);
1591 :
1592 4500649763 : *stmt_p = stmt = cp_fold (*stmt_p, data->flags);
1593 :
1594 4500649763 : if (data->pset.add (stmt))
1595 : {
1596 : /* Don't walk subtrees of stmts we've already walked once, otherwise
1597 : we can have exponential complexity with e.g. lots of nested
1598 : SAVE_EXPRs or TARGET_EXPRs. cp_fold uses a cache and will return
1599 : always the same tree, which the first time cp_fold_r has been
1600 : called on it had the subtrees walked. */
1601 640473000 : *walk_subtrees = 0;
1602 640473000 : return NULL_TREE;
1603 : }
1604 :
1605 3860176763 : code = TREE_CODE (stmt);
1606 3860176763 : switch (code)
1607 : {
1608 52047 : tree x;
1609 52047 : int i, n;
1610 52047 : case OMP_FOR:
1611 52047 : case OMP_SIMD:
1612 52047 : case OMP_DISTRIBUTE:
1613 52047 : case OMP_LOOP:
1614 52047 : case OMP_TASKLOOP:
1615 52047 : case OMP_TILE:
1616 52047 : case OMP_UNROLL:
1617 52047 : case OACC_LOOP:
1618 52047 : cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
1619 52047 : cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
1620 52047 : cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
1621 52047 : x = OMP_FOR_COND (stmt);
1622 52047 : if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison)
1623 : {
1624 0 : cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL);
1625 0 : cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL);
1626 : }
1627 38395 : else if (x && TREE_CODE (x) == TREE_VEC)
1628 : {
1629 38395 : n = TREE_VEC_LENGTH (x);
1630 88132 : for (i = 0; i < n; i++)
1631 : {
1632 49737 : tree o = TREE_VEC_ELT (x, i);
1633 49737 : if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
1634 47911 : cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
1635 : }
1636 : }
1637 52047 : x = OMP_FOR_INCR (stmt);
1638 52047 : if (x && TREE_CODE (x) == TREE_VEC)
1639 : {
1640 38395 : n = TREE_VEC_LENGTH (x);
1641 88132 : for (i = 0; i < n; i++)
1642 : {
1643 49737 : tree o = TREE_VEC_ELT (x, i);
1644 49737 : if (o && TREE_CODE (o) == MODIFY_EXPR)
1645 12044 : o = TREE_OPERAND (o, 1);
1646 47911 : if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
1647 38767 : || TREE_CODE (o) == POINTER_PLUS_EXPR))
1648 : {
1649 12044 : cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL);
1650 12044 : cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
1651 : }
1652 : }
1653 : }
1654 52047 : cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
1655 52047 : *walk_subtrees = 0;
1656 52047 : return NULL_TREE;
1657 :
1658 167184 : case OMP_CLAUSE:
1659 167184 : if ((data->flags & ff_only_non_odr)
1660 83603 : && omp_clause_num_ops[OMP_CLAUSE_CODE (stmt)] >= 1
1661 70175 : && OMP_CLAUSE_CODE (stmt) >= OMP_CLAUSE_PRIVATE
1662 70175 : && OMP_CLAUSE_CODE (stmt) <= OMP_CLAUSE__SCANTEMP_
1663 213932 : && OMP_CLAUSE_DECL (stmt))
1664 : {
1665 45566 : tree *decl = &OMP_CLAUSE_DECL (stmt);
1666 45566 : cp_walk_tree (decl, cp_fold_omp_clause_refs_r, NULL, NULL);
1667 45566 : if (TREE_CODE (*decl) == ADDR_EXPR
1668 45566 : && DECL_P (TREE_OPERAND (*decl, 0)))
1669 148 : *decl = TREE_OPERAND (*decl, 0);
1670 45566 : data->pset.add (*decl);
1671 : }
1672 : break;
1673 :
1674 46107634 : case IF_STMT:
1675 46107634 : if (IF_STMT_CONSTEVAL_P (stmt))
1676 : {
1677 : /* Don't walk THEN_CLAUSE (stmt) for consteval if. IF_COND is always
1678 : boolean_false_node. */
1679 157780 : cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL);
1680 157780 : cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL);
1681 157780 : *walk_subtrees = 0;
1682 157780 : return NULL_TREE;
1683 : }
1684 : break;
1685 :
1686 : /* cp_genericize_{init,target}_expr are only for genericize time; they're
1687 : here rather than in cp_genericize to avoid problems with the invisible
1688 : reference transition. */
1689 128370414 : case INIT_EXPR:
1690 128370414 : if (!flag_no_inline
1691 121259036 : && (data->flags & ff_genericize))
1692 : {
1693 60102552 : tree to = TREE_OPERAND (*stmt_p, 0);
1694 60102552 : tree &from = TREE_OPERAND (*stmt_p, 1);
1695 60102552 : tree folded = maybe_constant_init (from, to, data->mce ());
1696 60102552 : if (folded != from && TREE_CONSTANT (folded))
1697 1524738 : from = folded;
1698 : }
1699 :
1700 128370414 : if (data->flags & ff_genericize)
1701 63620295 : cp_genericize_init_expr (stmt_p);
1702 : break;
1703 :
1704 44637772 : case TARGET_EXPR:
1705 44637772 : if (!flag_no_inline
1706 42030338 : && (data->flags & ff_genericize))
1707 19686961 : if (tree &init = TARGET_EXPR_INITIAL (stmt))
1708 : {
1709 19686961 : tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt),
1710 : data->mce ());
1711 19686961 : if (folded != init && TREE_CONSTANT (folded))
1712 1235989 : init = folded;
1713 : }
1714 :
1715 : /* This needs to happen between the constexpr evaluation (which wants
1716 : pre-generic trees) and fold (which wants the cp_genericize_init
1717 : transformations). */
1718 44637772 : if (data->flags & ff_genericize)
1719 20962456 : cp_genericize_target_expr (stmt_p);
1720 :
1721 44637772 : if (tree &init = TARGET_EXPR_INITIAL (stmt))
1722 : {
1723 44637772 : cp_walk_tree (&init, cp_fold_r, data, NULL);
1724 44637772 : cp_walk_tree (&TARGET_EXPR_CLEANUP (stmt), cp_fold_r, data, NULL);
1725 44637772 : *walk_subtrees = 0;
1726 : /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in
1727 : that case, strip it in favor of this one. */
1728 44637772 : if (TREE_CODE (init) == TARGET_EXPR)
1729 : {
1730 130 : tree sub = TARGET_EXPR_INITIAL (init);
1731 130 : maybe_replace_decl (&sub, TARGET_EXPR_SLOT (init),
1732 130 : TARGET_EXPR_SLOT (stmt));
1733 130 : init = sub;
1734 : }
1735 : }
1736 : break;
1737 :
1738 131689933 : case CONVERT_EXPR:
1739 : /* convert_to_void used to fold these away to void_node. Do it now;
1740 : other code (e.g., trees_out) depends on these being expunged. We
1741 : do it here before maybe_save_constexpr_fundef copies function
1742 : bodies. */
1743 131689933 : if ((data->flags & (ff_only_non_odr | ff_genericize))
1744 131562685 : && VOID_TYPE_P (TREE_TYPE (stmt))
1745 223936958 : && !TREE_SIDE_EFFECTS (stmt))
1746 : {
1747 : /* Since we're discarding it, it's our last chance to check for
1748 : out-of-consteval expressions. */
1749 380173 : check_out_of_consteval_use (stmt);
1750 380173 : *stmt_p = void_node;
1751 380173 : *walk_subtrees = 0;
1752 380173 : return NULL_TREE;
1753 : }
1754 : break;
1755 :
1756 : default:
1757 : break;
1758 : }
1759 :
1760 : return NULL_TREE;
1761 : }
1762 :
1763 : /* Fold ALL the trees! FIXME we should be able to remove this, but
1764 : apparently that still causes optimization regressions. */
1765 :
1766 : void
1767 68972404 : cp_fold_function (tree fndecl)
1768 : {
1769 : /* By now all manifestly-constant-evaluated expressions will have
1770 : been constant-evaluated already if possible, so we can safely
1771 : pass ff_mce_false. */
1772 68972404 : cp_fold_data data (ff_genericize | ff_mce_false);
1773 : /* Do cp_fold_immediate_r in separate whole IL walk instead of during
1774 : cp_fold_r, as otherwise expressions using results of immediate functions
1775 : might not be folded as cp_fold is called on those before cp_fold_r is
1776 : called on their argument. */
1777 68972404 : if (cxx_dialect >= cxx20)
1778 : {
1779 66987923 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_immediate_r,
1780 : &data, NULL);
1781 66987923 : data.pset.empty ();
1782 : }
1783 68972404 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
1784 :
1785 : /* This is merely an optimization: if FNDECL has no i-e expressions,
1786 : we'll not save c_f_d, and we can safely say that FNDECL will not
1787 : be promoted to consteval. */
1788 68972404 : if (deferred_escalating_exprs
1789 68972404 : && !deferred_escalating_exprs->contains (current_function_decl))
1790 51410896 : DECL_ESCALATION_CHECKED_P (fndecl) = true;
1791 68972404 : }
1792 :
1793 : /* Fold any non-ODR usages of constant variables in FNDECL. This occurs
1794 : before saving the constexpr fundef, so do as little other folding
1795 : as possible. */
1796 :
1797 : void
1798 70026581 : cp_fold_function_non_odr_use (tree fndecl)
1799 : {
1800 70026581 : cp_fold_data data (ff_only_non_odr);
1801 70026581 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
1802 70026581 : }
1803 :
1804 : /* We've stashed immediate-escalating functions. Now see if they indeed
1805 : ought to be promoted to consteval. */
1806 :
1807 : void
1808 99779 : process_and_check_pending_immediate_escalating_fns ()
1809 : {
1810 : /* This will be null for -fno-immediate-escalation. */
1811 99779 : if (!deferred_escalating_exprs)
1812 : return;
1813 :
1814 14257227 : for (auto e : *deferred_escalating_exprs)
1815 14237205 : if (TREE_CODE (e) == FUNCTION_DECL && !DECL_ESCALATION_CHECKED_P (e))
1816 9738632 : cp_fold_immediate (&DECL_SAVED_TREE (e), mce_false, e);
1817 :
1818 : /* We've escalated every function that could have been promoted to
1819 : consteval. Check that we are not taking the address of a consteval
1820 : function. */
1821 14257227 : for (auto e : *deferred_escalating_exprs)
1822 : {
1823 14237205 : if (TREE_CODE (e) == FUNCTION_DECL)
1824 14237062 : continue;
1825 143 : tree decl = (TREE_CODE (e) == PTRMEM_CST
1826 143 : ? PTRMEM_CST_MEMBER (e)
1827 143 : : TREE_OPERAND (e, 0));
1828 286 : if (DECL_IMMEDIATE_FUNCTION_P (decl))
1829 12 : taking_address_of_imm_fn_error (e, decl);
1830 : }
1831 :
1832 20022 : deferred_escalating_exprs = nullptr;
1833 : }
1834 :
1835 : /* Turn SPACESHIP_EXPR EXPR into GENERIC. */
1836 :
1837 239018 : static tree genericize_spaceship (tree expr)
1838 : {
1839 239018 : iloc_sentinel s (cp_expr_location (expr));
1840 239018 : tree type = TREE_TYPE (expr);
1841 239018 : tree op0 = TREE_OPERAND (expr, 0);
1842 239018 : tree op1 = TREE_OPERAND (expr, 1);
1843 239018 : return genericize_spaceship (input_location, type, op0, op1);
1844 239018 : }
1845 :
1846 : /* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
1847 : to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
1848 : the middle-end (c++/88256). If EXPR is a DECL, use add_stmt and return
1849 : NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR. */
1850 :
1851 : tree
1852 144818932 : predeclare_vla (tree expr)
1853 : {
1854 144818932 : tree type = TREE_TYPE (expr);
1855 144818932 : if (type == error_mark_node)
1856 : return expr;
1857 144818794 : if (is_typedef_decl (expr))
1858 144818794 : type = DECL_ORIGINAL_TYPE (expr);
1859 :
1860 : /* We need to strip pointers for gimplify_type_sizes. */
1861 144818794 : tree vla = type;
1862 220853410 : while (POINTER_TYPE_P (vla))
1863 : {
1864 78594656 : if (TYPE_NAME (vla))
1865 : return expr;
1866 76034616 : vla = TREE_TYPE (vla);
1867 : }
1868 74073260 : if (vla == type || TYPE_NAME (vla)
1869 142840122 : || !variably_modified_type_p (vla, NULL_TREE))
1870 : return expr;
1871 :
1872 215 : tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
1873 215 : DECL_ARTIFICIAL (decl) = 1;
1874 215 : TYPE_NAME (vla) = decl;
1875 215 : tree dexp = build_stmt (input_location, DECL_EXPR, decl);
1876 215 : if (DECL_P (expr))
1877 : {
1878 5 : add_stmt (dexp);
1879 5 : return NULL_TREE;
1880 : }
1881 : else
1882 : {
1883 210 : expr = build2 (COMPOUND_EXPR, type, dexp, expr);
1884 210 : return expr;
1885 : }
1886 : }
1887 :
1888 : /* Perform any pre-gimplification lowering of C++ front end trees to
1889 : GENERIC. */
1890 :
1891 : static tree
1892 1877210751 : cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
1893 : {
1894 1899612948 : tree stmt = *stmt_p;
1895 1899612948 : struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
1896 1899612948 : hash_set<tree> *p_set = wtd->p_set;
1897 :
1898 : /* If in an OpenMP context, note var uses. */
1899 1899612948 : if (UNLIKELY (wtd->omp_ctx != NULL)
1900 600021 : && (VAR_P (stmt)
1901 : || TREE_CODE (stmt) == PARM_DECL
1902 : || TREE_CODE (stmt) == RESULT_DECL)
1903 1899721024 : && omp_var_to_track (stmt))
1904 12507 : omp_cxx_notice_variable (wtd->omp_ctx, stmt);
1905 :
1906 : /* Don't dereference parms in a thunk, pass the references through. */
1907 76622285 : if ((TREE_CODE (stmt) == CALL_EXPR && call_from_lambda_thunk_p (stmt))
1908 1976166467 : || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
1909 : {
1910 68980 : *walk_subtrees = 0;
1911 68980 : return NULL;
1912 : }
1913 :
1914 : /* Dereference invisible reference parms. */
1915 1899543968 : if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
1916 : {
1917 1325812 : *stmt_p = convert_from_reference (stmt);
1918 1325812 : p_set->add (*stmt_p);
1919 1325812 : *walk_subtrees = 0;
1920 1325812 : return NULL;
1921 : }
1922 :
1923 : /* Map block scope extern declarations to visible declarations with the
1924 : same name and type in outer scopes if any. */
1925 1898218156 : if (VAR_OR_FUNCTION_DECL_P (stmt) && DECL_LOCAL_DECL_P (stmt))
1926 22208 : if (tree alias = DECL_LOCAL_DECL_ALIAS (stmt))
1927 : {
1928 22208 : if (alias != error_mark_node)
1929 : {
1930 22205 : *stmt_p = alias;
1931 22205 : TREE_USED (alias) |= TREE_USED (stmt);
1932 : }
1933 22208 : *walk_subtrees = 0;
1934 22208 : return NULL;
1935 : }
1936 :
1937 1898195948 : if (TREE_CODE (stmt) == INTEGER_CST
1938 218089721 : && TYPE_REF_P (TREE_TYPE (stmt))
1939 168 : && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1940 1898195949 : && !wtd->no_sanitize_p)
1941 : {
1942 1 : ubsan_maybe_instrument_reference (stmt_p);
1943 1 : if (*stmt_p != stmt)
1944 : {
1945 1 : *walk_subtrees = 0;
1946 1 : return NULL_TREE;
1947 : }
1948 : }
1949 :
1950 : /* Other than invisiref parms, don't walk the same tree twice. */
1951 1898195947 : if (p_set->contains (stmt))
1952 : {
1953 377522791 : *walk_subtrees = 0;
1954 377522791 : return NULL_TREE;
1955 : }
1956 :
1957 1520673156 : if ((TREE_CODE (stmt) == VAR_DECL
1958 : || TREE_CODE (stmt) == PARM_DECL
1959 : || TREE_CODE (stmt) == RESULT_DECL)
1960 162568809 : && DECL_HAS_VALUE_EXPR_P (stmt))
1961 : {
1962 860360 : tree ve = DECL_VALUE_EXPR (stmt);
1963 860360 : cp_walk_tree (&ve, cp_genericize_r, data, NULL);
1964 860360 : SET_DECL_VALUE_EXPR (stmt, ve);
1965 : }
1966 :
1967 1520673156 : switch (TREE_CODE (stmt))
1968 : {
1969 122920996 : case ADDR_EXPR:
1970 122920996 : if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
1971 : {
1972 : /* If in an OpenMP context, note var uses. */
1973 574540 : if (UNLIKELY (wtd->omp_ctx != NULL)
1974 574540 : && omp_var_to_track (TREE_OPERAND (stmt, 0)))
1975 412 : omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
1976 574540 : *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
1977 574540 : *walk_subtrees = 0;
1978 : }
1979 122920996 : check_out_of_consteval_use (stmt);
1980 122920996 : break;
1981 :
1982 45525113 : case RETURN_EXPR:
1983 45525113 : if (TREE_OPERAND (stmt, 0))
1984 : {
1985 44819259 : if (error_operand_p (TREE_OPERAND (stmt, 0))
1986 44819259 : && warn_return_type)
1987 : /* Suppress -Wreturn-type for this function. */
1988 15 : suppress_warning (current_function_decl, OPT_Wreturn_type);
1989 :
1990 44819259 : if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
1991 : /* Don't dereference an invisiref RESULT_DECL inside a
1992 : RETURN_EXPR. */
1993 680 : *walk_subtrees = 0;
1994 44819259 : if (RETURN_EXPR_LOCAL_ADDR_P (stmt))
1995 : {
1996 : /* Don't return the address of a local variable. */
1997 175 : tree *p = &TREE_OPERAND (stmt, 0);
1998 350 : while (TREE_CODE (*p) == COMPOUND_EXPR)
1999 0 : p = &TREE_OPERAND (*p, 0);
2000 175 : if (TREE_CODE (*p) == INIT_EXPR)
2001 : {
2002 175 : tree op = TREE_OPERAND (*p, 1);
2003 175 : tree new_op = build2 (COMPOUND_EXPR, TREE_TYPE (op), op,
2004 175 : build_zero_cst (TREE_TYPE (op)));
2005 175 : TREE_OPERAND (*p, 1) = new_op;
2006 : }
2007 : }
2008 : }
2009 : break;
2010 :
2011 83490 : case OMP_CLAUSE:
2012 83490 : switch (OMP_CLAUSE_CODE (stmt))
2013 : {
2014 2590 : case OMP_CLAUSE_LASTPRIVATE:
2015 : /* Don't dereference an invisiref in OpenMP clauses. */
2016 2590 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
2017 : {
2018 53 : *walk_subtrees = 0;
2019 53 : if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
2020 48 : cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
2021 : cp_genericize_r, data, NULL);
2022 : }
2023 : break;
2024 2094 : case OMP_CLAUSE_PRIVATE:
2025 : /* Don't dereference an invisiref in OpenMP clauses. */
2026 2094 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
2027 8 : *walk_subtrees = 0;
2028 2086 : else if (wtd->omp_ctx != NULL)
2029 : {
2030 : /* Private clause doesn't cause any references to the
2031 : var in outer contexts, avoid calling
2032 : omp_cxx_notice_variable for it. */
2033 584 : struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
2034 584 : wtd->omp_ctx = NULL;
2035 584 : cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
2036 : data, NULL);
2037 584 : wtd->omp_ctx = old;
2038 584 : *walk_subtrees = 0;
2039 : }
2040 : break;
2041 6077 : case OMP_CLAUSE_SHARED:
2042 6077 : case OMP_CLAUSE_FIRSTPRIVATE:
2043 6077 : case OMP_CLAUSE_COPYIN:
2044 6077 : case OMP_CLAUSE_COPYPRIVATE:
2045 6077 : case OMP_CLAUSE_INCLUSIVE:
2046 6077 : case OMP_CLAUSE_EXCLUSIVE:
2047 : /* Don't dereference an invisiref in OpenMP clauses. */
2048 6077 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
2049 87 : *walk_subtrees = 0;
2050 : break;
2051 8593 : case OMP_CLAUSE_REDUCTION:
2052 8593 : case OMP_CLAUSE_IN_REDUCTION:
2053 8593 : case OMP_CLAUSE_TASK_REDUCTION:
2054 : /* Don't dereference an invisiref in reduction clause's
2055 : OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
2056 : still needs to be genericized. */
2057 8593 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
2058 : {
2059 38 : *walk_subtrees = 0;
2060 38 : if (OMP_CLAUSE_REDUCTION_INIT (stmt))
2061 38 : cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
2062 : cp_genericize_r, data, NULL);
2063 38 : if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
2064 38 : cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
2065 : cp_genericize_r, data, NULL);
2066 : }
2067 : break;
2068 : default:
2069 : break;
2070 : }
2071 : break;
2072 :
2073 : /* Due to the way voidify_wrapper_expr is written, we don't get a chance
2074 : to lower this construct before scanning it, so we need to lower these
2075 : before doing anything else. */
2076 5928110 : case CLEANUP_STMT:
2077 5928110 : *stmt_p = build2_loc (EXPR_LOCATION (stmt),
2078 5928110 : CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
2079 : : TRY_FINALLY_EXPR,
2080 : void_type_node,
2081 5928110 : CLEANUP_BODY (stmt),
2082 5928110 : CLEANUP_EXPR (stmt));
2083 5928110 : break;
2084 :
2085 22401141 : case IF_STMT:
2086 22401141 : genericize_if_stmt (stmt_p);
2087 : /* *stmt_p has changed, tail recurse to handle it again. */
2088 22401141 : return cp_genericize_r (stmt_p, walk_subtrees, data);
2089 :
2090 : /* COND_EXPR might have incompatible types in branches if one or both
2091 : arms are bitfields. Fix it up now. */
2092 20116637 : case COND_EXPR:
2093 20116637 : {
2094 20116637 : tree type_left
2095 20116637 : = (TREE_OPERAND (stmt, 1)
2096 20116637 : ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
2097 : : NULL_TREE);
2098 20116637 : tree type_right
2099 20116637 : = (TREE_OPERAND (stmt, 2)
2100 20116637 : ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
2101 : : NULL_TREE);
2102 20116637 : if (type_left
2103 20116670 : && !useless_type_conversion_p (TREE_TYPE (stmt),
2104 33 : TREE_TYPE (TREE_OPERAND (stmt, 1))))
2105 : {
2106 30 : TREE_OPERAND (stmt, 1)
2107 30 : = fold_convert (type_left, TREE_OPERAND (stmt, 1));
2108 30 : gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
2109 : type_left));
2110 : }
2111 20116637 : if (type_right
2112 20116654 : && !useless_type_conversion_p (TREE_TYPE (stmt),
2113 17 : TREE_TYPE (TREE_OPERAND (stmt, 2))))
2114 : {
2115 17 : TREE_OPERAND (stmt, 2)
2116 17 : = fold_convert (type_right, TREE_OPERAND (stmt, 2));
2117 17 : gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
2118 : type_right));
2119 : }
2120 : }
2121 : break;
2122 :
2123 26448626 : case BIND_EXPR:
2124 26448626 : if (UNLIKELY (wtd->omp_ctx != NULL))
2125 : {
2126 27441 : tree decl;
2127 33754 : for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
2128 6313 : if (VAR_P (decl)
2129 6265 : && !DECL_EXTERNAL (decl)
2130 12578 : && omp_var_to_track (decl))
2131 : {
2132 586 : splay_tree_node n
2133 586 : = splay_tree_lookup (wtd->omp_ctx->variables,
2134 : (splay_tree_key) decl);
2135 586 : if (n == NULL)
2136 586 : splay_tree_insert (wtd->omp_ctx->variables,
2137 : (splay_tree_key) decl,
2138 586 : TREE_STATIC (decl)
2139 : ? OMP_CLAUSE_DEFAULT_SHARED
2140 : : OMP_CLAUSE_DEFAULT_PRIVATE);
2141 : }
2142 : }
2143 26448626 : if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
2144 : {
2145 : /* The point here is to not sanitize static initializers. */
2146 3558 : bool no_sanitize_p = wtd->no_sanitize_p;
2147 3558 : wtd->no_sanitize_p = true;
2148 3558 : for (tree decl = BIND_EXPR_VARS (stmt);
2149 7004 : decl;
2150 3446 : decl = DECL_CHAIN (decl))
2151 3446 : if (VAR_P (decl)
2152 3031 : && TREE_STATIC (decl)
2153 3520 : && DECL_INITIAL (decl))
2154 12 : cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
2155 3558 : wtd->no_sanitize_p = no_sanitize_p;
2156 : }
2157 26448626 : if (flag_reflection)
2158 : /* Adjust consteval-only vars in BIND_EXPR_VARS so that REFLECT_EXPR
2159 : doesn't leak into the ME. */
2160 1169501 : for (tree *p = &BIND_EXPR_VARS (stmt); *p; )
2161 : {
2162 562662 : if (VAR_P (*p))
2163 : {
2164 : /* First, adjust null reflections. */
2165 480946 : if (DECL_INITIAL (*p))
2166 230431 : rewrite_null_reflection (DECL_INITIAL (*p));
2167 : /* If the variable is still consteval-only, remove it. */
2168 480946 : if (consteval_only_p (*p))
2169 : {
2170 884 : if (BIND_EXPR_BLOCK (stmt)
2171 884 : && *p == BLOCK_VARS (BIND_EXPR_BLOCK (stmt)))
2172 410 : BLOCK_VARS (BIND_EXPR_BLOCK (stmt)) = DECL_CHAIN (*p);
2173 884 : *p = DECL_CHAIN (*p);
2174 884 : continue;
2175 : }
2176 : }
2177 561778 : p = &DECL_CHAIN (*p);
2178 : }
2179 26448626 : wtd->bind_expr_stack.safe_push (stmt);
2180 26448626 : cp_walk_tree (&BIND_EXPR_BODY (stmt),
2181 : cp_genericize_r, data, NULL);
2182 26448626 : wtd->bind_expr_stack.pop ();
2183 26448626 : break;
2184 :
2185 1056 : case ASSERTION_STMT:
2186 1056 : case PRECONDITION_STMT:
2187 1056 : case POSTCONDITION_STMT:
2188 1056 : if (tree check = build_contract_check (stmt))
2189 : {
2190 1056 : *stmt_p = check;
2191 1056 : return cp_genericize_r (stmt_p, walk_subtrees, data);
2192 : }
2193 : /* If we didn't build a check, replace it with void_node so we don't
2194 : leak contracts into GENERIC. */
2195 0 : *stmt_p = void_node;
2196 0 : *walk_subtrees = 0;
2197 0 : break;
2198 :
2199 18635 : case USING_STMT:
2200 18635 : {
2201 18635 : tree block = NULL_TREE;
2202 :
2203 : /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
2204 : BLOCK, and append an IMPORTED_DECL to its
2205 : BLOCK_VARS chained list. */
2206 18635 : if (wtd->bind_expr_stack.exists ())
2207 : {
2208 18635 : int i;
2209 18635 : for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
2210 18635 : if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
2211 : break;
2212 : }
2213 18635 : if (block)
2214 : {
2215 18635 : tree decl = TREE_OPERAND (stmt, 0);
2216 18635 : gcc_assert (decl);
2217 :
2218 18635 : if (undeduced_auto_decl (decl))
2219 : /* Omit from the GENERIC, the back-end can't handle it. */;
2220 : else
2221 : {
2222 18632 : tree using_directive = make_node (IMPORTED_DECL);
2223 18632 : TREE_TYPE (using_directive) = void_type_node;
2224 18632 : DECL_CONTEXT (using_directive) = current_function_decl;
2225 37264 : DECL_SOURCE_LOCATION (using_directive)
2226 18632 : = cp_expr_loc_or_input_loc (stmt);
2227 :
2228 18632 : IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
2229 18632 : DECL_CHAIN (using_directive) = BLOCK_VARS (block);
2230 18632 : BLOCK_VARS (block) = using_directive;
2231 : }
2232 : }
2233 : /* The USING_STMT won't appear in GENERIC. */
2234 18635 : *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
2235 18635 : *walk_subtrees = 0;
2236 : }
2237 18635 : break;
2238 :
2239 26119158 : case DECL_EXPR:
2240 26119158 : if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
2241 : {
2242 : /* Using decls inside DECL_EXPRs are just dropped on the floor. */
2243 21049 : *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
2244 21049 : *walk_subtrees = 0;
2245 : }
2246 : else
2247 : {
2248 26098109 : tree d = DECL_EXPR_DECL (stmt);
2249 26098109 : if (VAR_P (d))
2250 52194693 : gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
2251 : }
2252 : break;
2253 :
2254 11736 : case OMP_PARALLEL:
2255 11736 : case OMP_TASK:
2256 11736 : case OMP_TASKLOOP:
2257 11736 : {
2258 11736 : struct cp_genericize_omp_taskreg omp_ctx;
2259 11736 : tree c, decl;
2260 11736 : splay_tree_node n;
2261 :
2262 11736 : *walk_subtrees = 0;
2263 11736 : cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
2264 11736 : omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
2265 11736 : omp_ctx.default_shared = omp_ctx.is_parallel;
2266 11736 : omp_ctx.outer = wtd->omp_ctx;
2267 11736 : omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
2268 11736 : wtd->omp_ctx = &omp_ctx;
2269 27814 : for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
2270 16078 : switch (OMP_CLAUSE_CODE (c))
2271 : {
2272 4797 : case OMP_CLAUSE_SHARED:
2273 4797 : case OMP_CLAUSE_PRIVATE:
2274 4797 : case OMP_CLAUSE_FIRSTPRIVATE:
2275 4797 : case OMP_CLAUSE_LASTPRIVATE:
2276 4797 : decl = OMP_CLAUSE_DECL (c);
2277 4797 : if (decl == error_mark_node || !omp_var_to_track (decl))
2278 : break;
2279 519 : n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
2280 519 : if (n != NULL)
2281 : break;
2282 1020 : splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
2283 510 : OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
2284 : ? OMP_CLAUSE_DEFAULT_SHARED
2285 : : OMP_CLAUSE_DEFAULT_PRIVATE);
2286 510 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
2287 91 : omp_cxx_notice_variable (omp_ctx.outer, decl);
2288 : break;
2289 1647 : case OMP_CLAUSE_DEFAULT:
2290 1647 : if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
2291 731 : omp_ctx.default_shared = true;
2292 : default:
2293 : break;
2294 : }
2295 11736 : if (TREE_CODE (stmt) == OMP_TASKLOOP)
2296 1001 : c_genericize_control_stmt (stmt_p, walk_subtrees, data,
2297 : cp_genericize_r, cp_walk_subtrees);
2298 : else
2299 10735 : cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
2300 11736 : wtd->omp_ctx = omp_ctx.outer;
2301 11736 : splay_tree_delete (omp_ctx.variables);
2302 : }
2303 11736 : break;
2304 :
2305 6959 : case OMP_TARGET:
2306 6959 : cfun->has_omp_target = true;
2307 6959 : break;
2308 :
2309 142161 : case TRY_BLOCK:
2310 142161 : {
2311 142161 : *walk_subtrees = 0;
2312 142161 : tree try_block = wtd->try_block;
2313 142161 : wtd->try_block = stmt;
2314 142161 : cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
2315 142161 : wtd->try_block = try_block;
2316 142161 : cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
2317 : }
2318 142161 : break;
2319 :
2320 25921270 : case MUST_NOT_THROW_EXPR:
2321 : /* MUST_NOT_THROW_COND might be something else with TM. */
2322 25921270 : if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
2323 : {
2324 25921252 : *walk_subtrees = 0;
2325 25921252 : tree try_block = wtd->try_block;
2326 25921252 : wtd->try_block = stmt;
2327 25921252 : cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
2328 25921252 : wtd->try_block = try_block;
2329 : }
2330 : break;
2331 :
2332 148757 : case THROW_EXPR:
2333 148757 : {
2334 148757 : location_t loc = location_of (stmt);
2335 148757 : if (warning_suppressed_p (stmt /* What warning? */))
2336 : /* Never mind. */;
2337 48361 : else if (wtd->try_block)
2338 : {
2339 11244 : if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
2340 : {
2341 18 : auto_diagnostic_group d;
2342 31 : if (warning_at (loc, OPT_Wterminate,
2343 : "%<throw%> will always call %<terminate%>")
2344 10 : && cxx_dialect >= cxx11
2345 36 : && DECL_DESTRUCTOR_P (current_function_decl))
2346 5 : inform (loc, "in C++11 destructors default to %<noexcept%>");
2347 18 : }
2348 : }
2349 : else
2350 : {
2351 103 : if (warn_cxx11_compat && cxx_dialect < cxx11
2352 206 : && DECL_DESTRUCTOR_P (current_function_decl)
2353 1 : && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
2354 : == NULL_TREE)
2355 37118 : && (get_defaulted_eh_spec (current_function_decl)
2356 1 : == empty_except_spec))
2357 1 : warning_at (loc, OPT_Wc__11_compat,
2358 : "in C++11 this %<throw%> will call %<terminate%> "
2359 : "because destructors default to %<noexcept%>");
2360 : }
2361 : }
2362 : break;
2363 :
2364 42811191 : case CONVERT_EXPR:
2365 42811191 : gcc_checking_assert (!AGGREGATE_TYPE_P (TREE_TYPE (stmt)));
2366 42811191 : gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
2367 : break;
2368 :
2369 239018 : case SPACESHIP_EXPR:
2370 239018 : *stmt_p = genericize_spaceship (*stmt_p);
2371 239018 : break;
2372 :
2373 32069 : case PTRMEM_CST:
2374 : /* By the time we get here we're handing off to the back end, so we don't
2375 : need or want to preserve PTRMEM_CST anymore. */
2376 32069 : *stmt_p = cplus_expand_constant (stmt);
2377 32069 : *walk_subtrees = 0;
2378 32069 : break;
2379 :
2380 283157 : case MEM_REF:
2381 : /* For MEM_REF, make sure not to sanitize the second operand even
2382 : if it has reference type. It is just an offset with a type
2383 : holding other information. There is no other processing we
2384 : need to do for INTEGER_CSTs, so just ignore the second argument
2385 : unconditionally. */
2386 283157 : cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
2387 283157 : *walk_subtrees = 0;
2388 283157 : break;
2389 :
2390 41963164 : case INDIRECT_REF:
2391 : /* A pointer to a class might point to a base subobject, which is
2392 : only guaranteed the alignment of the class as a base (the ABI
2393 : "nvalign"). That is less than TYPE_ALIGN if a virtual base needs
2394 : more alignment than the rest of the class, so don't let the middle
2395 : end assume more (PR c++/103303). */
2396 41963164 : {
2397 41963164 : tree type = TREE_TYPE (stmt);
2398 30498986 : if (CLASS_TYPE_P (type)
2399 30302739 : && COMPLETE_TYPE_P (type)
2400 29736855 : && CLASSTYPE_AS_BASE (type)
2401 29736855 : && CLASSTYPE_ALIGN (type) < TYPE_ALIGN (type)
2402 95 : && resolves_to_fixed_type_p (stmt) <= 0
2403 : /* Respect an alignment the user specified on a variant. */
2404 41963253 : && TYPE_ALIGN (type) == TYPE_ALIGN (TYPE_MAIN_VARIANT (type)))
2405 89 : TREE_TYPE (stmt) = build_aligned_type (type, CLASSTYPE_ALIGN (type));
2406 : }
2407 : break;
2408 :
2409 121027386 : case NOP_EXPR:
2410 121027386 : *stmt_p = predeclare_vla (*stmt_p);
2411 :
2412 : /* Warn of new allocations that are not big enough for the target
2413 : type. Don't warn for calls from new expressions, new TYPE[0]
2414 : is fine and new expansion should arrange for the right size
2415 : to be provided. */
2416 121027386 : if (warn_alloc_size
2417 1086044 : && TREE_CODE (TREE_OPERAND (stmt, 0)) == CALL_EXPR
2418 64807 : && !CALL_FROM_NEW_OR_DELETE_P (TREE_OPERAND (stmt, 0))
2419 121091642 : && POINTER_TYPE_P (TREE_TYPE (stmt)))
2420 : {
2421 23092 : if (tree fndecl = get_callee_fndecl (TREE_OPERAND (stmt, 0)))
2422 23078 : if (DECL_IS_MALLOC (fndecl))
2423 : {
2424 629 : tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
2425 629 : tree alloc_size = lookup_attribute ("alloc_size", attrs);
2426 629 : if (alloc_size)
2427 627 : warn_for_alloc_size (EXPR_LOCATION (stmt),
2428 627 : TREE_TYPE (TREE_TYPE (stmt)),
2429 627 : TREE_OPERAND (stmt, 0), alloc_size);
2430 : }
2431 : }
2432 :
2433 121027386 : if (!wtd->no_sanitize_p
2434 121027381 : && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
2435 121043384 : && TYPE_REF_P (TREE_TYPE (stmt)))
2436 2506 : ubsan_maybe_instrument_reference (stmt_p);
2437 : break;
2438 :
2439 76549153 : case CALL_EXPR:
2440 76549153 : if (!wtd->no_sanitize_p
2441 76549153 : && sanitize_flags_p ((SANITIZE_NULL
2442 : | SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
2443 : {
2444 16146 : tree fn = CALL_EXPR_FN (stmt);
2445 16146 : if (fn != NULL_TREE
2446 10015 : && !error_operand_p (fn)
2447 10015 : && INDIRECT_TYPE_P (TREE_TYPE (fn))
2448 26161 : && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
2449 : {
2450 5675 : bool is_ctor
2451 5675 : = TREE_CODE (fn) == ADDR_EXPR
2452 5552 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
2453 16779 : && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
2454 5675 : if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
2455 5064 : ubsan_maybe_instrument_member_call (stmt, is_ctor);
2456 5675 : if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
2457 4830 : cp_ubsan_maybe_instrument_member_call (stmt);
2458 : }
2459 10471 : else if (fn == NULL_TREE
2460 6131 : && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
2461 5024 : && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
2462 10477 : && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
2463 6 : *walk_subtrees = 0;
2464 : }
2465 : /* Fall through. */
2466 81447018 : case AGGR_INIT_EXPR:
2467 : /* For calls to a multi-versioned function, overload resolution
2468 : returns the function with the highest target priority, that is,
2469 : the version that will checked for dispatching first. If this
2470 : version is inlinable, a direct call to this version can be made
2471 : otherwise the call should go through the dispatcher.
2472 : This is done at multiple_target.cc for target_version semantics. */
2473 81447018 : {
2474 81447018 : tree fn = cp_get_callee_fndecl_nofold (stmt);
2475 81447018 : if (TARGET_HAS_FMV_TARGET_ATTRIBUTE
2476 : && fn
2477 80265269 : && DECL_FUNCTION_VERSIONED (fn)
2478 81447153 : && (current_function_decl == NULL
2479 135 : || !targetm.target_option.can_inline_p
2480 135 : (current_function_decl, fn)))
2481 123 : if (tree dis = get_function_version_dispatcher (fn))
2482 : {
2483 123 : mark_versions_used (dis);
2484 123 : dis = build_address (dis);
2485 123 : if (TREE_CODE (stmt) == CALL_EXPR)
2486 120 : CALL_EXPR_FN (stmt) = dis;
2487 : else
2488 3 : AGGR_INIT_EXPR_FN (stmt) = dis;
2489 : }
2490 : }
2491 : break;
2492 :
2493 19706547 : case TARGET_EXPR:
2494 19706547 : if (TARGET_EXPR_INITIAL (stmt)
2495 19706547 : && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
2496 22167063 : && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
2497 169 : TARGET_EXPR_NO_ELIDE (stmt) = 1;
2498 : break;
2499 :
2500 642 : case TEMPLATE_ID_EXPR:
2501 642 : gcc_assert (concept_check_p (stmt));
2502 : /* Emit the value of the concept check. */
2503 642 : *stmt_p = evaluate_concept_check (stmt);
2504 642 : walk_subtrees = 0;
2505 642 : break;
2506 :
2507 4241 : case OMP_DISTRIBUTE:
2508 : /* Need to explicitly instantiate copy ctors on class iterators of
2509 : composite distribute parallel for. */
2510 4241 : if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
2511 : {
2512 3742 : tree *data[4] = { NULL, NULL, NULL, NULL };
2513 3742 : tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
2514 : find_combined_omp_for, data, NULL);
2515 3742 : if (inner != NULL_TREE
2516 3708 : && TREE_CODE (inner) == OMP_FOR)
2517 : {
2518 4554 : for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
2519 2859 : if (TREE_VEC_ELT (OMP_FOR_INIT (inner), i)
2520 2843 : && OMP_FOR_ORIG_DECLS (inner)
2521 2843 : && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
2522 : i)) == TREE_LIST
2523 2883 : && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
2524 : i)))
2525 : {
2526 12 : tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
2527 : /* Class iterators aren't allowed on OMP_SIMD, so the only
2528 : case we need to solve is distribute parallel for. */
2529 12 : gcc_assert (TREE_CODE (inner) == OMP_FOR
2530 : && data[1]);
2531 12 : tree orig_decl = TREE_PURPOSE (orig);
2532 12 : tree c, cl = NULL_TREE;
2533 12 : for (c = OMP_FOR_CLAUSES (inner);
2534 16 : c; c = OMP_CLAUSE_CHAIN (c))
2535 12 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
2536 5 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2537 13 : && OMP_CLAUSE_DECL (c) == orig_decl)
2538 : {
2539 : cl = c;
2540 : break;
2541 : }
2542 12 : if (cl == NULL_TREE)
2543 : {
2544 4 : for (c = OMP_PARALLEL_CLAUSES (*data[1]);
2545 4 : c; c = OMP_CLAUSE_CHAIN (c))
2546 1 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
2547 1 : && OMP_CLAUSE_DECL (c) == orig_decl)
2548 : {
2549 : cl = c;
2550 : break;
2551 : }
2552 : }
2553 4 : if (cl)
2554 : {
2555 9 : orig_decl = require_complete_type (orig_decl);
2556 9 : tree inner_type = TREE_TYPE (orig_decl);
2557 9 : if (orig_decl == error_mark_node)
2558 0 : continue;
2559 9 : if (TYPE_REF_P (TREE_TYPE (orig_decl)))
2560 0 : inner_type = TREE_TYPE (inner_type);
2561 :
2562 9 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
2563 0 : inner_type = TREE_TYPE (inner_type);
2564 9 : get_copy_ctor (inner_type, tf_warning_or_error);
2565 : }
2566 : }
2567 : }
2568 : }
2569 : /* FALLTHRU */
2570 :
2571 5096134 : case FOR_STMT:
2572 5096134 : case WHILE_STMT:
2573 5096134 : case DO_STMT:
2574 5096134 : case SWITCH_STMT:
2575 5096134 : case CONTINUE_STMT:
2576 5096134 : case BREAK_STMT:
2577 5096134 : case OMP_FOR:
2578 5096134 : case OMP_SIMD:
2579 5096134 : case OMP_LOOP:
2580 5096134 : case OMP_TILE:
2581 5096134 : case OMP_UNROLL:
2582 5096134 : case OACC_LOOP:
2583 : /* These cases are handled by shared code. */
2584 5096134 : c_genericize_control_stmt (stmt_p, walk_subtrees, data,
2585 : cp_genericize_r, cp_walk_subtrees);
2586 5096134 : break;
2587 :
2588 71137043 : case STATEMENT_LIST:
2589 : /* As above, handled by shared code. */
2590 71137043 : c_genericize_control_stmt (stmt_p, walk_subtrees, data,
2591 : cp_genericize_r, cp_walk_subtrees);
2592 : /* If a statement list is freed as part of genericisation it will be
2593 : pushed onto the top of a statement list cache stack. A subsequent
2594 : action can cause a new statement list to be required - and the one
2595 : just pushed will be returned. If that is marked as visited, it can
2596 : prevent a tail recursion from processing the 'new' statement list,
2597 : so we do not mark statement lists as visited. */
2598 71137043 : return NULL_TREE;
2599 77103 : break;
2600 :
2601 77103 : case BIT_CAST_EXPR:
2602 77103 : *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
2603 77103 : TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
2604 77103 : break;
2605 :
2606 22301411 : case MODIFY_EXPR:
2607 : /* Mark stores to parts of complex automatic non-addressable
2608 : variables as DECL_NOT_GIMPLE_REG_P for -O0. This can't be
2609 : done during gimplification. See PR119120. */
2610 22301411 : if ((TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
2611 22272882 : || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR)
2612 57069 : && !optimize
2613 552 : && DECL_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0))
2614 22301505 : && is_gimple_reg (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)))
2615 50 : DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)) = 1;
2616 : break;
2617 :
2618 151 : case REFLECT_EXPR:
2619 : /* Only the null reflection may reach the ME. */
2620 151 : check_out_of_consteval_use (stmt);
2621 151 : *stmt_p = build_int_cst (meta_info_type_node, 0);
2622 151 : break;
2623 :
2624 818757277 : default:
2625 818757277 : if (IS_TYPE_OR_DECL_P (stmt))
2626 268002694 : *walk_subtrees = 0;
2627 : break;
2628 : }
2629 :
2630 1427133916 : p_set->add (*stmt_p);
2631 :
2632 1427133916 : return NULL;
2633 : }
2634 :
2635 : /* Lower C++ front end trees to GENERIC in T_P. */
2636 :
2637 : static void
2638 52206258 : cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
2639 : {
2640 52206258 : struct cp_genericize_data wtd;
2641 :
2642 52206258 : wtd.p_set = new hash_set<tree>;
2643 52206258 : wtd.bind_expr_stack.create (0);
2644 52206258 : wtd.omp_ctx = NULL;
2645 52206258 : wtd.try_block = NULL_TREE;
2646 52206258 : wtd.no_sanitize_p = false;
2647 52206258 : wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
2648 52206258 : cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
2649 104412516 : delete wtd.p_set;
2650 52206258 : if (sanitize_flags_p (SANITIZE_VPTR))
2651 5754 : cp_ubsan_instrument_member_accesses (t_p);
2652 52206258 : }
2653 :
2654 : /* If a function that should end with a return in non-void
2655 : function doesn't obviously end with return, add ubsan
2656 : instrumentation code to verify it at runtime. If -fsanitize=return
2657 : is not enabled, instrument __builtin_unreachable. */
2658 :
2659 : static void
2660 52206258 : cp_maybe_instrument_return (tree fndecl)
2661 : {
2662 52206258 : if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
2663 74863062 : || DECL_CONSTRUCTOR_P (fndecl)
2664 37431531 : || DECL_DESTRUCTOR_P (fndecl)
2665 89637789 : || !targetm.warn_func_return (fndecl))
2666 : return;
2667 :
2668 37431519 : if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
2669 : /* Don't add __builtin_unreachable () if not optimizing, it will not
2670 : improve any optimizations in that case, just break UB code.
2671 : Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
2672 : UBSan covers this with ubsan_instrument_return above where sufficient
2673 : information is provided, while the __builtin_unreachable () below
2674 : if return sanitization is disabled will just result in hard to
2675 : understand runtime error without location. */
2676 37431519 : && ((!optimize && !flag_unreachable_traps)
2677 37427637 : || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
2678 : return;
2679 :
2680 37431489 : tree t = DECL_SAVED_TREE (fndecl);
2681 64619849 : while (t)
2682 : {
2683 64619849 : switch (TREE_CODE (t))
2684 : {
2685 4993472 : case BIND_EXPR:
2686 4993472 : t = BIND_EXPR_BODY (t);
2687 4993472 : continue;
2688 9067856 : case TRY_FINALLY_EXPR:
2689 9067856 : case CLEANUP_POINT_EXPR:
2690 9067856 : t = TREE_OPERAND (t, 0);
2691 9067856 : continue;
2692 13129837 : case STATEMENT_LIST:
2693 13129837 : {
2694 13129837 : tree_stmt_iterator i = tsi_last (t);
2695 13133498 : while (!tsi_end_p (i))
2696 : {
2697 13130693 : tree p = tsi_stmt (i);
2698 13130693 : if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
2699 : break;
2700 3661 : tsi_prev (&i);
2701 : }
2702 13129837 : if (!tsi_end_p (i))
2703 : {
2704 13127032 : t = tsi_stmt (i);
2705 13127032 : continue;
2706 : }
2707 : }
2708 2805 : break;
2709 : case RETURN_EXPR:
2710 : return;
2711 : default:
2712 : break;
2713 14061328 : }
2714 : break;
2715 : }
2716 20667783 : if (t == NULL_TREE)
2717 : return;
2718 20667783 : tree *p = &DECL_SAVED_TREE (fndecl);
2719 20667783 : if (TREE_CODE (*p) == BIND_EXPR)
2720 936971 : p = &BIND_EXPR_BODY (*p);
2721 :
2722 20667783 : location_t loc = DECL_SOURCE_LOCATION (fndecl);
2723 20667783 : if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
2724 1807 : t = ubsan_instrument_return (loc);
2725 : else
2726 20665976 : t = build_builtin_unreachable (BUILTINS_LOCATION);
2727 :
2728 20667783 : append_to_statement_list (t, p);
2729 : }
2730 :
2731 : void
2732 68971916 : cp_genericize (tree fndecl)
2733 : {
2734 68971916 : tree t;
2735 :
2736 : /* Fix up the types of parms passed by invisible reference. */
2737 182796250 : for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
2738 113824334 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
2739 : {
2740 : /* If a function's arguments are copied to create a thunk,
2741 : then DECL_BY_REFERENCE will be set -- but the type of the
2742 : argument will be a pointer type, so we will never get
2743 : here. */
2744 133552 : gcc_assert (!DECL_BY_REFERENCE (t));
2745 133552 : gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
2746 133552 : TREE_TYPE (t) = DECL_ARG_TYPE (t);
2747 133552 : DECL_BY_REFERENCE (t) = 1;
2748 133552 : TREE_ADDRESSABLE (t) = 0;
2749 133552 : relayout_decl (t);
2750 : }
2751 :
2752 : /* Do the same for the return value. */
2753 68971916 : if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
2754 : {
2755 1175071 : t = DECL_RESULT (fndecl);
2756 1175071 : TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
2757 1175071 : DECL_BY_REFERENCE (t) = 1;
2758 1175071 : TREE_ADDRESSABLE (t) = 0;
2759 1175071 : relayout_decl (t);
2760 1175071 : if (DECL_NAME (t))
2761 : {
2762 : /* Adjust DECL_VALUE_EXPR of the original var. */
2763 131513 : tree outer = outer_curly_brace_block (current_function_decl);
2764 131513 : tree var;
2765 :
2766 131513 : if (outer)
2767 308901 : for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
2768 308173 : if (VAR_P (var)
2769 297997 : && DECL_NAME (t) == DECL_NAME (var)
2770 130785 : && DECL_HAS_VALUE_EXPR_P (var)
2771 438958 : && DECL_VALUE_EXPR (var) == t)
2772 : {
2773 130785 : tree val = convert_from_reference (t);
2774 130785 : SET_DECL_VALUE_EXPR (var, val);
2775 130785 : break;
2776 : }
2777 : }
2778 : }
2779 :
2780 : /* If we're a clone, the body is already GIMPLE. */
2781 68971916 : if (DECL_CLONED_FUNCTION_P (fndecl))
2782 16765658 : return;
2783 :
2784 : /* Allow cp_genericize calls to be nested. */
2785 52206258 : bc_state_t save_state;
2786 52206258 : save_bc_state (&save_state);
2787 :
2788 : /* We do want to see every occurrence of the parms, so we can't just use
2789 : walk_tree's hash functionality. */
2790 52206258 : cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
2791 :
2792 52206258 : cp_maybe_instrument_return (fndecl);
2793 :
2794 : /* Do everything else. */
2795 52206258 : c_genericize (fndecl);
2796 52206258 : restore_bc_state (&save_state);
2797 : }
2798 :
2799 : /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
2800 : NULL if there is in fact nothing to do. ARG2 may be null if FN
2801 : actually only takes one argument. */
2802 :
2803 : static tree
2804 3680 : cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
2805 : {
2806 3680 : tree defparm, parm, t;
2807 3680 : int i = 0;
2808 3680 : int nargs;
2809 3680 : tree *argarray;
2810 :
2811 3680 : if (fn == NULL)
2812 : return NULL;
2813 :
2814 2824 : nargs = list_length (DECL_ARGUMENTS (fn));
2815 2824 : argarray = XALLOCAVEC (tree, nargs);
2816 :
2817 2824 : defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
2818 2824 : if (arg2)
2819 944 : defparm = TREE_CHAIN (defparm);
2820 :
2821 2824 : bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
2822 2824 : if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
2823 : {
2824 27 : tree inner_type = TREE_TYPE (arg1);
2825 27 : tree start1, end1, p1;
2826 27 : tree start2 = NULL, p2 = NULL;
2827 27 : tree ret = NULL, lab;
2828 :
2829 27 : start1 = arg1;
2830 27 : start2 = arg2;
2831 27 : do
2832 : {
2833 27 : inner_type = TREE_TYPE (inner_type);
2834 27 : start1 = build4 (ARRAY_REF, inner_type, start1,
2835 : size_zero_node, NULL, NULL);
2836 27 : if (arg2)
2837 9 : start2 = build4 (ARRAY_REF, inner_type, start2,
2838 : size_zero_node, NULL, NULL);
2839 : }
2840 27 : while (TREE_CODE (inner_type) == ARRAY_TYPE);
2841 27 : start1 = build_fold_addr_expr_loc (input_location, start1);
2842 27 : if (arg2)
2843 9 : start2 = build_fold_addr_expr_loc (input_location, start2);
2844 :
2845 27 : end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
2846 27 : end1 = fold_build_pointer_plus (start1, end1);
2847 :
2848 27 : p1 = create_tmp_var (TREE_TYPE (start1));
2849 27 : t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
2850 27 : append_to_statement_list (t, &ret);
2851 :
2852 27 : if (arg2)
2853 : {
2854 9 : p2 = create_tmp_var (TREE_TYPE (start2));
2855 9 : t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
2856 9 : append_to_statement_list (t, &ret);
2857 : }
2858 :
2859 27 : lab = create_artificial_label (input_location);
2860 27 : t = build1 (LABEL_EXPR, void_type_node, lab);
2861 27 : append_to_statement_list (t, &ret);
2862 :
2863 27 : argarray[i++] = p1;
2864 27 : if (arg2)
2865 9 : argarray[i++] = p2;
2866 : /* Handle default arguments. */
2867 27 : for (parm = defparm; parm && parm != void_list_node;
2868 0 : parm = TREE_CHAIN (parm), i++)
2869 0 : argarray[i] = convert_default_arg (TREE_VALUE (parm),
2870 0 : TREE_PURPOSE (parm), fn,
2871 : i - is_method, tf_warning_or_error);
2872 27 : t = build_call_a (fn, i, argarray);
2873 27 : if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
2874 0 : t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
2875 27 : t = fold_convert (void_type_node, t);
2876 27 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
2877 27 : append_to_statement_list (t, &ret);
2878 :
2879 27 : t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
2880 27 : t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
2881 27 : append_to_statement_list (t, &ret);
2882 :
2883 27 : if (arg2)
2884 : {
2885 9 : t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
2886 9 : t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
2887 9 : append_to_statement_list (t, &ret);
2888 : }
2889 :
2890 27 : t = build2 (NE_EXPR, boolean_type_node, p1, end1);
2891 27 : t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
2892 27 : append_to_statement_list (t, &ret);
2893 :
2894 27 : return ret;
2895 : }
2896 : else
2897 : {
2898 2797 : argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
2899 2797 : if (arg2)
2900 935 : argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
2901 : /* Handle default arguments. */
2902 2802 : for (parm = defparm; parm && parm != void_list_node;
2903 5 : parm = TREE_CHAIN (parm), i++)
2904 10 : argarray[i] = convert_default_arg (TREE_VALUE (parm),
2905 5 : TREE_PURPOSE (parm), fn,
2906 : i - is_method, tf_warning_or_error);
2907 2797 : t = build_call_a (fn, i, argarray);
2908 2797 : if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
2909 1 : t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
2910 2797 : t = fold_convert (void_type_node, t);
2911 2797 : return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
2912 : }
2913 : }
2914 :
2915 : /* Return code to initialize DECL with its default constructor, or
2916 : NULL if there's nothing to do. */
2917 :
2918 : tree
2919 42638 : cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
2920 : {
2921 42638 : tree info = CP_OMP_CLAUSE_INFO (clause);
2922 42638 : tree ret = NULL;
2923 :
2924 42638 : if (info)
2925 1401 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
2926 :
2927 42638 : return ret;
2928 : }
2929 :
2930 : /* Return code to initialize DST with a copy constructor from SRC. */
2931 :
2932 : tree
2933 12354 : cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
2934 : {
2935 12354 : tree info = CP_OMP_CLAUSE_INFO (clause);
2936 12354 : tree ret = NULL;
2937 :
2938 12354 : if (info)
2939 283 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
2940 283 : if (ret == NULL)
2941 12136 : ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
2942 :
2943 12354 : return ret;
2944 : }
2945 :
2946 : /* Similarly, except use an assignment operator instead. */
2947 :
2948 : tree
2949 12686 : cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
2950 : {
2951 12686 : tree info = CP_OMP_CLAUSE_INFO (clause);
2952 12686 : tree ret = NULL;
2953 :
2954 12686 : if (info)
2955 748 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
2956 748 : if (ret == NULL)
2957 11960 : ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
2958 :
2959 12686 : return ret;
2960 : }
2961 :
2962 : /* Return code to destroy DECL. */
2963 :
2964 : tree
2965 62658 : cxx_omp_clause_dtor (tree clause, tree decl)
2966 : {
2967 62658 : tree info = CP_OMP_CLAUSE_INFO (clause);
2968 62658 : tree ret = NULL;
2969 :
2970 62658 : if (info)
2971 1248 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
2972 :
2973 62658 : return ret;
2974 : }
2975 :
2976 : /* True if OpenMP should privatize what this DECL points to rather
2977 : than the DECL itself. */
2978 :
2979 : bool
2980 985645 : cxx_omp_privatize_by_reference (const_tree decl)
2981 : {
2982 985645 : return (TYPE_REF_P (TREE_TYPE (decl))
2983 985645 : || is_invisiref_parm (decl));
2984 : }
2985 :
2986 : /* Return true if DECL is const qualified var having no mutable member. */
2987 : bool
2988 15435 : cxx_omp_const_qual_no_mutable (tree decl)
2989 : {
2990 15435 : tree type = TREE_TYPE (decl);
2991 15435 : if (TYPE_REF_P (type))
2992 : {
2993 864 : if (!is_invisiref_parm (decl))
2994 : return false;
2995 0 : type = TREE_TYPE (type);
2996 :
2997 0 : if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
2998 : {
2999 : /* NVR doesn't preserve const qualification of the
3000 : variable's type. */
3001 0 : tree outer = outer_curly_brace_block (current_function_decl);
3002 0 : tree var;
3003 :
3004 0 : if (outer)
3005 0 : for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
3006 0 : if (VAR_P (var)
3007 0 : && DECL_NAME (decl) == DECL_NAME (var)
3008 0 : && (TYPE_MAIN_VARIANT (type)
3009 0 : == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
3010 : {
3011 0 : if (TYPE_READONLY (TREE_TYPE (var)))
3012 0 : type = TREE_TYPE (var);
3013 : break;
3014 : }
3015 : }
3016 : }
3017 :
3018 14571 : if (type == error_mark_node)
3019 : return false;
3020 :
3021 : /* Variables with const-qualified type having no mutable member
3022 : are predetermined shared. */
3023 14556 : if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
3024 69 : return true;
3025 :
3026 : return false;
3027 : }
3028 :
3029 : /* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
3030 : of DECL is predetermined. */
3031 :
3032 : enum omp_clause_default_kind
3033 55800 : cxx_omp_predetermined_sharing_1 (tree decl)
3034 : {
3035 : /* Static data members are predetermined shared. */
3036 55800 : if (TREE_STATIC (decl))
3037 : {
3038 15173 : tree ctx = CP_DECL_CONTEXT (decl);
3039 15173 : if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
3040 : return OMP_CLAUSE_DEFAULT_SHARED;
3041 :
3042 15067 : if (c_omp_predefined_variable (decl))
3043 : return OMP_CLAUSE_DEFAULT_SHARED;
3044 : }
3045 :
3046 : /* this may not be specified in data-sharing clauses, still we need
3047 : to predetermined it firstprivate. */
3048 55649 : if (decl == current_class_ptr)
3049 113 : return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
3050 :
3051 : return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
3052 : }
3053 :
3054 : /* Likewise, but also include the artificial vars. We don't want to
3055 : disallow the artificial vars being mentioned in explicit clauses,
3056 : as we use artificial vars e.g. for loop constructs with random
3057 : access iterators other than pointers, but during gimplification
3058 : we want to treat them as predetermined. */
3059 :
3060 : enum omp_clause_default_kind
3061 35150 : cxx_omp_predetermined_sharing (tree decl)
3062 : {
3063 35150 : enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
3064 35150 : if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
3065 : return ret;
3066 :
3067 : /* Predetermine artificial variables holding integral values, those
3068 : are usually result of gimplify_one_sizepos or SAVE_EXPR
3069 : gimplification. */
3070 34933 : if (VAR_P (decl)
3071 23002 : && DECL_ARTIFICIAL (decl)
3072 7154 : && INTEGRAL_TYPE_P (TREE_TYPE (decl))
3073 35457 : && !(DECL_LANG_SPECIFIC (decl)
3074 2 : && DECL_OMP_PRIVATIZED_MEMBER (decl)))
3075 : return OMP_CLAUSE_DEFAULT_SHARED;
3076 :
3077 : /* Similarly for typeinfo symbols. */
3078 34411 : if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl))
3079 60 : return OMP_CLAUSE_DEFAULT_SHARED;
3080 :
3081 : return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
3082 : }
3083 :
3084 : enum omp_clause_defaultmap_kind
3085 17642 : cxx_omp_predetermined_mapping (tree decl)
3086 : {
3087 : /* Predetermine artificial variables holding integral values, those
3088 : are usually result of gimplify_one_sizepos or SAVE_EXPR
3089 : gimplification. */
3090 17642 : if (VAR_P (decl)
3091 1679 : && DECL_ARTIFICIAL (decl)
3092 142 : && INTEGRAL_TYPE_P (TREE_TYPE (decl))
3093 17708 : && !(DECL_LANG_SPECIFIC (decl)
3094 6 : && DECL_OMP_PRIVATIZED_MEMBER (decl)))
3095 : return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
3096 :
3097 17576 : if (c_omp_predefined_variable (decl))
3098 12 : return OMP_CLAUSE_DEFAULTMAP_TO;
3099 :
3100 : return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
3101 : }
3102 :
3103 : /* Finalize an implicitly determined clause. */
3104 :
3105 : void
3106 64365 : cxx_omp_finish_clause (tree c, gimple_seq *, bool /* openacc */)
3107 : {
3108 64365 : tree decl, inner_type;
3109 64365 : bool make_shared = false;
3110 :
3111 64365 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
3112 56864 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
3113 94440 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
3114 4752 : || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
3115 : return;
3116 :
3117 34305 : decl = OMP_CLAUSE_DECL (c);
3118 34305 : decl = require_complete_type (decl);
3119 34305 : inner_type = TREE_TYPE (decl);
3120 34305 : if (decl == error_mark_node)
3121 34305 : make_shared = true;
3122 34305 : else if (TYPE_REF_P (TREE_TYPE (decl)))
3123 86 : inner_type = TREE_TYPE (inner_type);
3124 :
3125 : /* We're interested in the base element, not arrays. */
3126 34565 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
3127 260 : inner_type = TREE_TYPE (inner_type);
3128 :
3129 : /* Check for special function availability by building a call to one.
3130 : Save the results, because later we won't be in the right context
3131 : for making these queries. */
3132 34305 : bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
3133 34305 : bool last = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE;
3134 34305 : if (!make_shared
3135 34305 : && CLASS_TYPE_P (inner_type)
3136 34528 : && cxx_omp_create_clause_info (c, inner_type, !first, first, last,
3137 : true))
3138 : make_shared = true;
3139 :
3140 34299 : if (make_shared)
3141 : {
3142 6 : OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
3143 6 : OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
3144 6 : OMP_CLAUSE_SHARED_READONLY (c) = 0;
3145 : }
3146 : }
3147 :
3148 : tree
3149 38 : cxx_omp_finish_mapper_clauses (tree clauses)
3150 : {
3151 38 : return finish_omp_clauses (clauses, C_ORT_OMP);
3152 : }
3153 :
3154 : /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
3155 : disregarded in OpenMP construct, because it is going to be
3156 : remapped during OpenMP lowering. SHARED is true if DECL
3157 : is going to be shared, false if it is going to be privatized. */
3158 :
3159 : bool
3160 670129 : cxx_omp_disregard_value_expr (tree decl, bool shared)
3161 : {
3162 670129 : if (shared)
3163 : return false;
3164 402792 : if (VAR_P (decl)
3165 380653 : && DECL_HAS_VALUE_EXPR_P (decl)
3166 9549 : && DECL_ARTIFICIAL (decl)
3167 9038 : && DECL_LANG_SPECIFIC (decl)
3168 410691 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
3169 : return true;
3170 397379 : if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
3171 : return true;
3172 : return false;
3173 : }
3174 :
3175 : /* Fold any non-ODR-usages of a constant variable in expression X. */
3176 :
3177 : static tree
3178 594485813 : cp_fold_non_odr_use_1 (tree x)
3179 : {
3180 594485813 : tree var = x;
3181 896814969 : while (!VAR_P (var))
3182 820556326 : switch (TREE_CODE (var))
3183 : {
3184 290023949 : case ARRAY_REF:
3185 290023949 : case BIT_FIELD_REF:
3186 290023949 : case COMPONENT_REF:
3187 290023949 : case VIEW_CONVERT_EXPR:
3188 290023949 : CASE_CONVERT:
3189 290023949 : var = TREE_OPERAND (var, 0);
3190 290023949 : break;
3191 :
3192 29151680 : case INDIRECT_REF:
3193 29151680 : if (REFERENCE_REF_P (var))
3194 12305207 : var = TREE_OPERAND (var, 0);
3195 : else
3196 : return x;
3197 12305207 : break;
3198 :
3199 : default:
3200 : return x;
3201 : }
3202 :
3203 76258643 : if (TREE_THIS_VOLATILE (var)
3204 76258643 : || !decl_constant_var_p (var))
3205 : return x;
3206 :
3207 : /* We mustn't fold std::hardware_destructive_interference_size here
3208 : so that maybe_warn_about_constant_value can complain if it's used
3209 : in a manifestly constant-evaluated context. */
3210 5903614 : if (decl_in_std_namespace_p (var)
3211 2818233 : && DECL_NAME (var)
3212 8721847 : && id_equal (DECL_NAME (var), "hardware_destructive_interference_size"))
3213 : return x;
3214 :
3215 5903614 : tree t = maybe_constant_value (x);
3216 5903614 : return TREE_CONSTANT (t) ? t : x;
3217 : }
3218 :
3219 : /* Fold expression X which is used as an rvalue if RVAL is true. */
3220 :
3221 : static tree
3222 2625290368 : cp_fold_maybe_rvalue (tree x, bool rval, fold_flags_t flags)
3223 : {
3224 2646468644 : while (true)
3225 : {
3226 2635879506 : if (rval && (flags & ff_only_non_odr))
3227 577412619 : x = cp_fold_non_odr_use_1 (x);
3228 2635879506 : x = cp_fold (x, flags);
3229 2635879506 : if (rval)
3230 : {
3231 1761121090 : x = mark_rvalue_use (x);
3232 1761121090 : if (!(flags & ff_only_non_odr)
3233 1761121090 : && DECL_P (x) && !TYPE_REF_P (TREE_TYPE (x)))
3234 : {
3235 264902905 : tree v = decl_constant_value (x);
3236 264902905 : if (v != x && v != error_mark_node)
3237 : {
3238 10589138 : x = v;
3239 10589138 : continue;
3240 : }
3241 : }
3242 : }
3243 2625290368 : break;
3244 10589138 : }
3245 2625290368 : return x;
3246 : }
3247 :
3248 : tree
3249 77595433 : cp_fold_maybe_rvalue (tree x, bool rval)
3250 : {
3251 77595433 : return cp_fold_maybe_rvalue (x, rval, ff_none);
3252 : }
3253 :
3254 : /* Fold expression X which is used as an rvalue. */
3255 :
3256 : static tree
3257 278502420 : cp_fold_rvalue (tree x, fold_flags_t flags)
3258 : {
3259 10370892 : return cp_fold_maybe_rvalue (x, true, flags);
3260 : }
3261 :
3262 : tree
3263 2176491 : cp_fold_rvalue (tree x)
3264 : {
3265 2176491 : return cp_fold_rvalue (x, ff_none);
3266 : }
3267 :
3268 : /* Fold any non-ODR used constants in an expression X which
3269 : is used as an rvalue if RVAL is true. */
3270 :
3271 : tree
3272 745396 : cp_fold_non_odr_use (tree x, bool rval)
3273 : {
3274 745396 : return cp_fold_maybe_rvalue (x, rval, ff_only_non_odr);
3275 : }
3276 :
3277 : /* Perform folding on expression X. */
3278 :
3279 : static tree
3280 292258323 : cp_fully_fold (tree x, mce_value manifestly_const_eval)
3281 : {
3282 292258323 : if (processing_template_decl)
3283 : return x;
3284 : /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
3285 : have to call both. */
3286 265955037 : if (cxx_dialect >= cxx11)
3287 : {
3288 264824890 : x = maybe_constant_value (x, /*decl=*/NULL_TREE, manifestly_const_eval);
3289 : /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
3290 : a TARGET_EXPR; undo that here. */
3291 264824890 : if (TREE_CODE (x) == TARGET_EXPR)
3292 686846 : x = TARGET_EXPR_INITIAL (x);
3293 264138044 : else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
3294 28100676 : && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
3295 264138233 : && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
3296 189 : x = TREE_OPERAND (x, 0);
3297 : }
3298 265955037 : fold_flags_t flags = ff_none;
3299 265955037 : if (manifestly_const_eval == mce_false)
3300 46054703 : flags |= ff_mce_false;
3301 265955037 : return cp_fold_rvalue (x, flags);
3302 : }
3303 :
3304 : tree
3305 246203620 : cp_fully_fold (tree x)
3306 : {
3307 246203620 : return cp_fully_fold (x, mce_unknown);
3308 : }
3309 :
3310 : /* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
3311 : in some cases. */
3312 :
3313 : tree
3314 48406314 : cp_fully_fold_init (tree x)
3315 : {
3316 48406314 : if (processing_template_decl)
3317 2351611 : return x;
3318 46054703 : x = cp_fully_fold (x, mce_false);
3319 46054703 : cp_fold_data data (ff_mce_false);
3320 46054703 : if (cxx_dialect >= cxx20)
3321 : {
3322 45414984 : cp_walk_tree (&x, cp_fold_immediate_r, &data, NULL);
3323 45414984 : data.pset.empty ();
3324 : }
3325 46054703 : cp_walk_tree (&x, cp_fold_r, &data, NULL);
3326 46054703 : return x;
3327 46054703 : }
3328 :
3329 : /* c-common interface to cp_fold. If IN_INIT, this is in a static initializer
3330 : and certain changes are made to the folding done. Or should be (FIXME). We
3331 : never touch maybe_const, as it is only used for the C front-end
3332 : C_MAYBE_CONST_EXPR. */
3333 :
3334 : tree
3335 77595433 : c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
3336 : {
3337 77595433 : return cp_fold_maybe_rvalue (x, !lval);
3338 : }
3339 :
3340 : static GTY((deletable)) hash_map<tree, tree> *fold_caches[3];
3341 :
3342 : /* Subroutine of cp_fold. Returns which fold cache to use according
3343 : to the given flags. We need multiple caches since the result of
3344 : folding may depend on which flags are used. */
3345 :
3346 : static hash_map<tree, tree> *&
3347 4855248983 : get_fold_cache (fold_flags_t flags)
3348 : {
3349 0 : if (flags & ff_mce_false)
3350 2185507703 : return fold_caches[2];
3351 2669741280 : else if (flags & ff_only_non_odr)
3352 2299496099 : return fold_caches[1];
3353 : else
3354 370245181 : return fold_caches[0];
3355 : }
3356 :
3357 : /* Dispose of the whole FOLD_CACHE. */
3358 :
3359 : void
3360 41438208 : clear_fold_cache (void)
3361 : {
3362 165752832 : for (auto& fold_cache : fold_caches)
3363 124314624 : if (fold_cache != NULL)
3364 148843688 : fold_cache->empty ();
3365 41438208 : }
3366 :
3367 : /* This function tries to fold an expression X.
3368 : To avoid combinatorial explosion, folding results are kept in fold_cache.
3369 : If X is invalid, we don't fold at all.
3370 : For performance reasons we don't cache expressions representing a
3371 : declaration or constant.
3372 : Function returns X or its folded variant. */
3373 :
3374 : static tree
3375 7904505291 : cp_fold (tree x, fold_flags_t flags)
3376 : {
3377 7904505291 : tree op0, op1, op2, op3;
3378 7904505291 : tree org_x = x, r = NULL_TREE;
3379 7904505291 : enum tree_code code;
3380 7904505291 : location_t loc;
3381 7904505291 : bool rval_ops = true;
3382 :
3383 7904505291 : if (!x || x == error_mark_node)
3384 : return x;
3385 :
3386 7897950145 : if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
3387 : return x;
3388 :
3389 : /* Don't bother to cache DECLs or constants. */
3390 7897645267 : if (DECL_P (x) || CONSTANT_CLASS_P (x))
3391 : return x;
3392 :
3393 4855248983 : auto& fold_cache = get_fold_cache (flags);
3394 4855248983 : if (fold_cache == NULL)
3395 525219 : fold_cache = hash_map<tree, tree>::create_ggc (101);
3396 :
3397 4855248983 : if (tree *cached = fold_cache->get (x))
3398 : {
3399 : /* unshare_expr doesn't recurse into SAVE_EXPRs. If SAVE_EXPR's
3400 : argument has been folded into a tree invariant, make sure it is
3401 : unshared. See PR112727. */
3402 1114594395 : if (TREE_CODE (x) == SAVE_EXPR && *cached != x)
3403 85 : return unshare_expr (*cached);
3404 1114594310 : return *cached;
3405 : }
3406 :
3407 3740654588 : uid_sensitive_constexpr_evaluation_checker c;
3408 :
3409 3740654588 : code = TREE_CODE (x);
3410 3740654588 : switch (code)
3411 : {
3412 212467124 : case CLEANUP_POINT_EXPR:
3413 : /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
3414 : effects. */
3415 212467124 : r = cp_fold (TREE_OPERAND (x, 0), flags);
3416 212467124 : if (!TREE_SIDE_EFFECTS (r) && !(flags & ff_only_non_odr))
3417 2430770 : x = r;
3418 : break;
3419 :
3420 1737392 : case SIZEOF_EXPR:
3421 1737392 : x = fold_sizeof_expr (x);
3422 1737392 : break;
3423 :
3424 333246203 : case VIEW_CONVERT_EXPR:
3425 333246203 : rval_ops = false;
3426 : /* FALLTHRU */
3427 1026911586 : case NON_LVALUE_EXPR:
3428 1026911586 : CASE_CONVERT:
3429 :
3430 1026911586 : if (VOID_TYPE_P (TREE_TYPE (x)))
3431 : {
3432 : /* This is just to make sure we don't end up with casts to
3433 : void from error_mark_node. If we just return x, then
3434 : cp_fold_r might fold the operand into error_mark_node and
3435 : leave the conversion in the IR. STRIP_USELESS_TYPE_CONVERSION
3436 : during gimplification doesn't like such casts.
3437 : Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
3438 : folding of the operand should be in the caches and if in cp_fold_r
3439 : it will modify it in place. */
3440 94139856 : op0 = cp_fold (TREE_OPERAND (x, 0), flags);
3441 94139856 : if (op0 == error_mark_node)
3442 119 : x = error_mark_node;
3443 : break;
3444 : }
3445 :
3446 932771730 : loc = EXPR_LOCATION (x);
3447 932771730 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3448 :
3449 932771730 : if (op0 == error_mark_node)
3450 3 : x = error_mark_node;
3451 932771727 : else if (flags & ff_only_non_odr)
3452 : {
3453 347220037 : if (op0 != TREE_OPERAND (x, 0))
3454 2127471 : x = build1_loc (loc, code, TREE_TYPE (x), op0);
3455 347220037 : if (code == NOP_EXPR)
3456 177299695 : REINTERPRET_CAST_P (x) = REINTERPRET_CAST_P (org_x);
3457 : }
3458 585551690 : else if (code == CONVERT_EXPR
3459 46358856 : && SCALAR_TYPE_P (TREE_TYPE (x))
3460 631909518 : && op0 != void_node)
3461 : /* During parsing we used convert_to_*_nofold; re-convert now using the
3462 : folding variants, since fold() doesn't do those transformations. */
3463 41905489 : x = fold (convert (TREE_TYPE (x), op0));
3464 543646201 : else if (op0 != TREE_OPERAND (x, 0))
3465 144587693 : x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
3466 : else
3467 399058508 : x = fold (x);
3468 :
3469 : /* Conversion of an out-of-range value has implementation-defined
3470 : behavior; the language considers it different from arithmetic
3471 : overflow, which is undefined. */
3472 932771730 : if (TREE_CODE (op0) == INTEGER_CST
3473 932771730 : && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
3474 44 : TREE_OVERFLOW (x) = false;
3475 :
3476 : break;
3477 :
3478 261 : case EXCESS_PRECISION_EXPR:
3479 261 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3480 261 : if (op0 == error_mark_node)
3481 0 : x = error_mark_node;
3482 261 : else if (flags & ff_only_non_odr)
3483 : {
3484 67 : if (op0 != TREE_OPERAND (x, 0))
3485 0 : x = build1_loc (EXPR_LOCATION (x), code, TREE_TYPE (x), op0);
3486 : }
3487 : else
3488 194 : x = fold_convert_loc (EXPR_LOCATION (x), TREE_TYPE (x), op0);
3489 : break;
3490 :
3491 128612194 : case INDIRECT_REF:
3492 : /* We don't need the decltype(auto) obfuscation anymore. */
3493 128612194 : if (REF_PARENTHESIZED_P (x))
3494 : {
3495 855 : tree p = maybe_undo_parenthesized_ref (x);
3496 855 : if (p != x)
3497 0 : return cp_fold (p, flags);
3498 : }
3499 : /* When folding non-ODR usages of constants, we also want to
3500 : remove any constant-initialized references, even when
3501 : used as lvalues. */
3502 128612194 : if ((flags & ff_only_non_odr) && REFERENCE_REF_P (x))
3503 : {
3504 17073194 : op0 = cp_fold_non_odr_use_1 (TREE_OPERAND (x, 0));
3505 17073194 : if (op0 != TREE_OPERAND (x, 0))
3506 1515 : return convert_from_reference (cp_fold (op0, flags));
3507 : }
3508 128610679 : goto unary;
3509 :
3510 321521759 : case ADDR_EXPR:
3511 321521759 : loc = EXPR_LOCATION (x);
3512 321521759 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false, flags);
3513 :
3514 : /* Cope with user tricks that amount to offsetof. */
3515 321521759 : if (op0 != error_mark_node
3516 321521759 : && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0))
3517 441164875 : && !(flags & ff_only_non_odr))
3518 : {
3519 66360122 : tree val = get_base_address (op0);
3520 66360122 : if (val
3521 66360122 : && INDIRECT_REF_P (val)
3522 25747339 : && COMPLETE_TYPE_P (TREE_TYPE (val))
3523 92107371 : && TREE_CONSTANT (TREE_OPERAND (val, 0)))
3524 : {
3525 261 : val = TREE_OPERAND (val, 0);
3526 261 : STRIP_NOPS (val);
3527 261 : val = maybe_constant_value (val);
3528 261 : if (TREE_CODE (val) == INTEGER_CST)
3529 127 : return fold_offsetof (op0, TREE_TYPE (x));
3530 : }
3531 : }
3532 321521632 : goto finish_unary;
3533 :
3534 : case REALPART_EXPR:
3535 : case IMAGPART_EXPR:
3536 171891651 : rval_ops = false;
3537 : /* FALLTHRU */
3538 171891651 : case CONJ_EXPR:
3539 171891651 : case FIX_TRUNC_EXPR:
3540 171891651 : case FLOAT_EXPR:
3541 171891651 : case NEGATE_EXPR:
3542 171891651 : case ABS_EXPR:
3543 171891651 : case ABSU_EXPR:
3544 171891651 : case BIT_NOT_EXPR:
3545 171891651 : case TRUTH_NOT_EXPR:
3546 171891651 : case FIXED_CONVERT_EXPR:
3547 171891651 : unary:
3548 :
3549 171891651 : loc = EXPR_LOCATION (x);
3550 171891651 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3551 :
3552 493413283 : finish_unary:
3553 493413283 : if (op0 == error_mark_node)
3554 3 : x = error_mark_node;
3555 493413280 : else if (op0 != TREE_OPERAND (x, 0))
3556 : {
3557 31926359 : if (flags & ff_only_non_odr)
3558 428865 : x = build1_loc (loc, code, TREE_TYPE (x), op0);
3559 : else
3560 31497494 : x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
3561 31926359 : if (code == INDIRECT_REF
3562 9775988 : && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
3563 : {
3564 9775783 : TREE_READONLY (x) = TREE_READONLY (org_x);
3565 9775783 : TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
3566 9775783 : TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
3567 : }
3568 : }
3569 461486921 : else if (!(flags & ff_only_non_odr))
3570 228096873 : x = fold (x);
3571 :
3572 493413283 : gcc_assert (TREE_CODE (x) != COND_EXPR
3573 : || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
3574 : break;
3575 :
3576 320572 : case UNARY_PLUS_EXPR:
3577 320572 : op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
3578 320572 : if (op0 == error_mark_node)
3579 0 : x = error_mark_node;
3580 320572 : else if (flags & ff_only_non_odr)
3581 : {
3582 126700 : if (op0 != TREE_OPERAND (x, 0))
3583 12 : x = build1_loc (EXPR_LOCATION (x), code, TREE_TYPE (x), op0);
3584 : }
3585 : else
3586 193872 : x = fold_convert (TREE_TYPE (x), op0);
3587 : break;
3588 :
3589 202826805 : case POSTDECREMENT_EXPR:
3590 202826805 : case POSTINCREMENT_EXPR:
3591 202826805 : case INIT_EXPR:
3592 202826805 : case PREDECREMENT_EXPR:
3593 202826805 : case PREINCREMENT_EXPR:
3594 202826805 : case COMPOUND_EXPR:
3595 202826805 : case MODIFY_EXPR:
3596 202826805 : rval_ops = false;
3597 : /* FALLTHRU */
3598 421130859 : case POINTER_PLUS_EXPR:
3599 421130859 : case PLUS_EXPR:
3600 421130859 : case POINTER_DIFF_EXPR:
3601 421130859 : case MINUS_EXPR:
3602 421130859 : case MULT_EXPR:
3603 421130859 : case TRUNC_DIV_EXPR:
3604 421130859 : case CEIL_DIV_EXPR:
3605 421130859 : case FLOOR_DIV_EXPR:
3606 421130859 : case ROUND_DIV_EXPR:
3607 421130859 : case TRUNC_MOD_EXPR:
3608 421130859 : case CEIL_MOD_EXPR:
3609 421130859 : case ROUND_MOD_EXPR:
3610 421130859 : case RDIV_EXPR:
3611 421130859 : case EXACT_DIV_EXPR:
3612 421130859 : case MIN_EXPR:
3613 421130859 : case MAX_EXPR:
3614 421130859 : case LSHIFT_EXPR:
3615 421130859 : case RSHIFT_EXPR:
3616 421130859 : case LROTATE_EXPR:
3617 421130859 : case RROTATE_EXPR:
3618 421130859 : case BIT_AND_EXPR:
3619 421130859 : case BIT_IOR_EXPR:
3620 421130859 : case BIT_XOR_EXPR:
3621 421130859 : case TRUTH_AND_EXPR:
3622 421130859 : case TRUTH_ANDIF_EXPR:
3623 421130859 : case TRUTH_OR_EXPR:
3624 421130859 : case TRUTH_ORIF_EXPR:
3625 421130859 : case TRUTH_XOR_EXPR:
3626 421130859 : case LT_EXPR: case LE_EXPR:
3627 421130859 : case GT_EXPR: case GE_EXPR:
3628 421130859 : case EQ_EXPR: case NE_EXPR:
3629 421130859 : case UNORDERED_EXPR: case ORDERED_EXPR:
3630 421130859 : case UNLT_EXPR: case UNLE_EXPR:
3631 421130859 : case UNGT_EXPR: case UNGE_EXPR:
3632 421130859 : case UNEQ_EXPR: case LTGT_EXPR:
3633 421130859 : case RANGE_EXPR: case COMPLEX_EXPR:
3634 :
3635 421130859 : loc = EXPR_LOCATION (x);
3636 421130859 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3637 421130859 : bool clear_decl_read;
3638 421130859 : clear_decl_read = false;
3639 421130859 : if (code == MODIFY_EXPR
3640 53009047 : && (VAR_P (op0) || TREE_CODE (op0) == PARM_DECL)
3641 435991785 : && !DECL_READ_P (op0))
3642 : clear_decl_read = true;
3643 421130859 : op1 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 1),
3644 : code != COMPOUND_EXPR, flags);
3645 421130859 : if (clear_decl_read)
3646 782909 : DECL_READ_P (op0) = 0;
3647 :
3648 421130859 : if (flags & ff_only_non_odr)
3649 : {
3650 183347282 : if (op0 == error_mark_node || op1 == error_mark_node)
3651 24 : x = error_mark_node;
3652 183347258 : else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
3653 : {
3654 8135171 : if (code == INIT_EXPR && op1 != TREE_OPERAND (x, 1))
3655 2547691 : set_target_expr_eliding (op1);
3656 8135171 : x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
3657 : }
3658 : break;
3659 : }
3660 :
3661 : /* decltype(nullptr) has only one value, so optimize away all comparisons
3662 : with that type right away, keeping them in the IL causes troubles for
3663 : various optimizations. */
3664 237783577 : if (COMPARISON_CLASS_P (org_x)
3665 39521179 : && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
3666 237783604 : && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
3667 : {
3668 27 : switch (code)
3669 : {
3670 12 : case EQ_EXPR:
3671 12 : x = constant_boolean_node (true, TREE_TYPE (x));
3672 12 : break;
3673 15 : case NE_EXPR:
3674 15 : x = constant_boolean_node (false, TREE_TYPE (x));
3675 15 : break;
3676 0 : default:
3677 0 : gcc_unreachable ();
3678 : }
3679 27 : return omit_two_operands_loc (loc, TREE_TYPE (x), x,
3680 27 : op0, op1);
3681 : }
3682 :
3683 237783550 : if (op0 == error_mark_node || op1 == error_mark_node)
3684 105 : x = error_mark_node;
3685 237783445 : else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
3686 163572406 : x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
3687 : else
3688 74211039 : x = fold (x);
3689 :
3690 : /* This is only needed for -Wnonnull-compare and only if
3691 : TREE_NO_WARNING (org_x), but to avoid that option affecting code
3692 : generation, we do it always. */
3693 237783550 : if (COMPARISON_CLASS_P (org_x))
3694 : {
3695 39521152 : if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
3696 : ;
3697 38374383 : else if (COMPARISON_CLASS_P (x))
3698 : {
3699 37350617 : if (warn_nonnull_compare
3700 37350617 : && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
3701 122805 : suppress_warning (x, OPT_Wnonnull_compare);
3702 : }
3703 : /* Otherwise give up on optimizing these, let GIMPLE folders
3704 : optimize those later on. */
3705 1023766 : else if (op0 != TREE_OPERAND (org_x, 0)
3706 1023766 : || op1 != TREE_OPERAND (org_x, 1))
3707 : {
3708 1021677 : x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
3709 1021677 : if (warn_nonnull_compare
3710 1021677 : && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
3711 16 : suppress_warning (x, OPT_Wnonnull_compare);
3712 : }
3713 : else
3714 2089 : x = org_x;
3715 : }
3716 :
3717 : break;
3718 :
3719 10050320 : case VEC_COND_EXPR:
3720 10050320 : case COND_EXPR:
3721 10050320 : loc = EXPR_LOCATION (x);
3722 10050320 : op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
3723 10050320 : op1 = cp_fold (TREE_OPERAND (x, 1), flags);
3724 10050320 : op2 = cp_fold (TREE_OPERAND (x, 2), flags);
3725 :
3726 10050320 : if (flags & ff_only_non_odr)
3727 : {
3728 4232206 : if (op0 == error_mark_node
3729 4232200 : || op1 == error_mark_node
3730 4232200 : || op2 == error_mark_node)
3731 6 : x = error_mark_node;
3732 4232200 : else if (op0 != TREE_OPERAND (x, 0)
3733 4154257 : || op1 != TREE_OPERAND (x, 1)
3734 8156106 : || op2 != TREE_OPERAND (x, 2))
3735 323275 : x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
3736 : break;
3737 : }
3738 :
3739 5818114 : if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
3740 : {
3741 21191 : warning_sentinel s (warn_int_in_bool_context);
3742 21191 : if (!VOID_TYPE_P (TREE_TYPE (op1)))
3743 21191 : op1 = cp_truthvalue_conversion (op1, tf_warning_or_error);
3744 21191 : if (!VOID_TYPE_P (TREE_TYPE (op2)))
3745 21170 : op2 = cp_truthvalue_conversion (op2, tf_warning_or_error);
3746 21191 : }
3747 5796923 : else if (VOID_TYPE_P (TREE_TYPE (x)))
3748 : {
3749 1894823 : if (TREE_CODE (op0) == INTEGER_CST)
3750 : {
3751 : /* If the condition is constant, fold can fold away
3752 : the COND_EXPR. If some statement-level uses of COND_EXPR
3753 : have one of the branches NULL, avoid folding crash. */
3754 340559 : if (!op1)
3755 0 : op1 = build_empty_stmt (loc);
3756 340559 : if (!op2)
3757 12 : op2 = build_empty_stmt (loc);
3758 : }
3759 : else
3760 : {
3761 : /* Otherwise, don't bother folding a void condition, since
3762 : it can't produce a constant value. */
3763 1554264 : if (op0 != TREE_OPERAND (x, 0)
3764 1465123 : || op1 != TREE_OPERAND (x, 1)
3765 2648522 : || op2 != TREE_OPERAND (x, 2))
3766 462252 : x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
3767 : break;
3768 : }
3769 : }
3770 :
3771 4263850 : if (op0 == error_mark_node
3772 4263850 : || op1 == error_mark_node
3773 4263836 : || op2 == error_mark_node)
3774 62 : x = error_mark_node;
3775 4263788 : else if (op0 != TREE_OPERAND (x, 0)
3776 1718460 : || op1 != TREE_OPERAND (x, 1)
3777 5609193 : || op2 != TREE_OPERAND (x, 2))
3778 3026634 : x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
3779 : else
3780 1237154 : x = fold (x);
3781 :
3782 : /* A COND_EXPR might have incompatible types in branches if one or both
3783 : arms are bitfields. If folding exposed such a branch, fix it up. */
3784 4263850 : if (TREE_CODE (x) != code
3785 982231 : && x != error_mark_node
3786 5246019 : && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
3787 17849 : x = fold_convert (TREE_TYPE (org_x), x);
3788 :
3789 : break;
3790 :
3791 233627309 : case CALL_EXPR:
3792 233627309 : {
3793 233627309 : tree callee = get_callee_fndecl (x);
3794 :
3795 : /* "Inline" calls to std::move/forward and other cast-like functions
3796 : by simply folding them into a corresponding cast to their return
3797 : type. This is cheaper than relying on the middle end to do so, and
3798 : also means we avoid generating useless debug info for them at all.
3799 :
3800 : At this point the argument has already been converted into a
3801 : reference, so it suffices to use a NOP_EXPR to express the
3802 : cast. */
3803 233627309 : if ((OPTION_SET_P (flag_fold_simple_inlines)
3804 233627309 : ? flag_fold_simple_inlines
3805 233626994 : : !flag_no_inline)
3806 220977662 : && !(flags & ff_only_non_odr)
3807 127656377 : && call_expr_nargs (x) == 1
3808 67212834 : && decl_in_std_namespace_p (callee)
3809 43012337 : && DECL_NAME (callee) != NULL_TREE
3810 276639646 : && (id_equal (DECL_NAME (callee), "move")
3811 41684894 : || id_equal (DECL_NAME (callee), "forward")
3812 40058706 : || id_equal (DECL_NAME (callee), "forward_like")
3813 40058560 : || id_equal (DECL_NAME (callee), "addressof")
3814 : /* This addressof equivalent is used heavily in libstdc++. */
3815 39716764 : || id_equal (DECL_NAME (callee), "__addressof")
3816 39328348 : || id_equal (DECL_NAME (callee), "to_underlying")
3817 39328342 : || id_equal (DECL_NAME (callee), "as_const")))
3818 : {
3819 3686598 : r = CALL_EXPR_ARG (x, 0);
3820 : /* These type-checks must be performed here, because invalid
3821 : definitions of these functions could fail to ensure those and
3822 : build_nop could misbehave. See PR122185. */
3823 3686598 : if (id_equal (DECL_NAME (callee), "to_underlying")
3824 3686598 : ? TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
3825 6 : && INTEGRAL_TYPE_P (TREE_TYPE (x))
3826 6642972 : : INDIRECT_TYPE_P (TREE_TYPE (x))
3827 6642960 : && INDIRECT_TYPE_P (TREE_TYPE (r)))
3828 : {
3829 3686583 : r = build_nop (TREE_TYPE (x), r);
3830 3686583 : x = cp_fold (r, flags);
3831 : }
3832 : break;
3833 : }
3834 :
3835 229940711 : int sv = optimize, nw = sv;
3836 :
3837 : /* Some built-in function calls will be evaluated at compile-time in
3838 : fold (). Set optimize to 1 when folding __builtin_constant_p inside
3839 : a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
3840 227494993 : if (callee && fndecl_built_in_p (callee) && !optimize
3841 2134539 : && DECL_IS_BUILTIN_CONSTANT_P (callee)
3842 50132 : && current_function_decl
3843 229990827 : && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
3844 : nw = 1;
3845 :
3846 227494993 : if (callee && !(flags & ff_only_non_odr)
3847 359696816 : && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
3848 : {
3849 62509 : iloc_sentinel ils (EXPR_LOCATION (x));
3850 62509 : switch (DECL_FE_FUNCTION_CODE (callee))
3851 : {
3852 55686 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
3853 : /* Defer folding __builtin_is_constant_evaluated unless
3854 : we know this isn't a manifestly constant-evaluated
3855 : context. */
3856 55686 : if (flags & ff_mce_false)
3857 28224 : x = boolean_false_node;
3858 : break;
3859 3 : case CP_BUILT_IN_SOURCE_LOCATION:
3860 3 : x = fold_builtin_source_location (x);
3861 3 : break;
3862 456 : case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
3863 912 : x = fold_builtin_is_corresponding_member
3864 456 : (EXPR_LOCATION (x), call_expr_nargs (x),
3865 : &CALL_EXPR_ARG (x, 0));
3866 456 : break;
3867 400 : case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
3868 800 : x = fold_builtin_is_pointer_inverconvertible_with_class
3869 400 : (EXPR_LOCATION (x), call_expr_nargs (x),
3870 : &CALL_EXPR_ARG (x, 0));
3871 400 : break;
3872 : default:
3873 : break;
3874 : }
3875 62509 : break;
3876 62509 : }
3877 :
3878 229878202 : bool changed = false;
3879 229878202 : int m = call_expr_nargs (x);
3880 566795971 : for (int i = 0; i < m; i++)
3881 : {
3882 336917769 : r = cp_fold (CALL_EXPR_ARG (x, i), flags);
3883 336917769 : if (r != CALL_EXPR_ARG (x, i))
3884 : {
3885 110832113 : if (r == error_mark_node)
3886 : {
3887 0 : x = error_mark_node;
3888 0 : break;
3889 : }
3890 110832113 : if (!changed)
3891 70698749 : x = copy_node (x);
3892 110832113 : CALL_EXPR_ARG (x, i) = r;
3893 110832113 : changed = true;
3894 : }
3895 : }
3896 : /* Don't fold away the function entirely if we're just folding
3897 : non-ODR-used variables. */
3898 229878202 : if (x == error_mark_node || (flags & ff_only_non_odr))
3899 : break;
3900 :
3901 131107088 : optimize = nw;
3902 131107088 : r = fold (x);
3903 131107088 : optimize = sv;
3904 :
3905 131107088 : if (TREE_CODE (r) != CALL_EXPR)
3906 : {
3907 2977988 : x = cp_fold (r, flags);
3908 2977988 : break;
3909 : }
3910 :
3911 128129100 : optimize = nw;
3912 :
3913 : /* Invoke maybe_constant_value for functions declared
3914 : constexpr and not called with AGGR_INIT_EXPRs.
3915 : TODO:
3916 : Do constexpr expansion of expressions where the call itself is not
3917 : constant, but the call followed by an INDIRECT_REF is. */
3918 126715608 : if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
3919 : && !(flags & ff_only_non_odr)
3920 191482319 : && (!flag_no_inline
3921 3750203 : || lookup_attribute ("always_inline",
3922 3750203 : DECL_ATTRIBUTES (callee))))
3923 : {
3924 60438110 : mce_value manifestly_const_eval = mce_unknown;
3925 60438110 : if (flags & ff_mce_false)
3926 : /* Allow folding __builtin_is_constant_evaluated to false during
3927 : constexpr evaluation of this call. */
3928 46891798 : manifestly_const_eval = mce_false;
3929 60438110 : r = maybe_constant_value (x, /*decl=*/NULL_TREE,
3930 : manifestly_const_eval);
3931 : }
3932 128129100 : optimize = sv;
3933 :
3934 128129100 : if (TREE_CODE (r) != CALL_EXPR)
3935 : {
3936 9207766 : if (DECL_CONSTRUCTOR_P (callee))
3937 489 : r = cp_build_init_expr_for_ctor (x, r);
3938 4603883 : x = r;
3939 4603883 : break;
3940 : }
3941 :
3942 : break;
3943 : }
3944 :
3945 24494710 : case CONSTRUCTOR:
3946 24494710 : {
3947 24494710 : unsigned i;
3948 24494710 : constructor_elt *p;
3949 24494710 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
3950 24494710 : vec<constructor_elt, va_gc> *nelts = NULL;
3951 117394373 : FOR_EACH_VEC_SAFE_ELT (elts, i, p)
3952 : {
3953 81647105 : tree op = cp_fold (p->value, flags);
3954 81647105 : if (op == error_mark_node)
3955 : {
3956 0 : x = error_mark_node;
3957 0 : vec_free (nelts);
3958 : break;
3959 : }
3960 81647105 : else if (op != p->value)
3961 : {
3962 1256490 : if (nelts == NULL)
3963 808000 : nelts = elts->copy ();
3964 1256490 : (*nelts)[i].value = op;
3965 : }
3966 : }
3967 24494710 : if (nelts)
3968 : {
3969 808000 : x = build_constructor (TREE_TYPE (x), nelts);
3970 808000 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
3971 808000 : = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
3972 808000 : CONSTRUCTOR_MUTABLE_POISON (x)
3973 1616000 : = CONSTRUCTOR_MUTABLE_POISON (org_x);
3974 : }
3975 24494710 : if (VECTOR_TYPE_P (TREE_TYPE (x)))
3976 78700 : x = fold (x);
3977 : break;
3978 : }
3979 832463 : case TREE_VEC:
3980 832463 : {
3981 832463 : bool changed = false;
3982 832463 : int n = TREE_VEC_LENGTH (x);
3983 :
3984 2094831 : for (int i = 0; i < n; i++)
3985 : {
3986 1262368 : tree op = cp_fold (TREE_VEC_ELT (x, i), flags);
3987 1262368 : if (op != TREE_VEC_ELT (x, i))
3988 : {
3989 865 : if (!changed)
3990 822 : x = copy_node (x);
3991 865 : TREE_VEC_ELT (x, i) = op;
3992 865 : changed = true;
3993 : }
3994 : }
3995 : }
3996 :
3997 : break;
3998 :
3999 3263578 : case ARRAY_REF:
4000 3263578 : case ARRAY_RANGE_REF:
4001 :
4002 3263578 : loc = EXPR_LOCATION (x);
4003 3263578 : op0 = cp_fold (TREE_OPERAND (x, 0), flags);
4004 3263578 : op1 = cp_fold (TREE_OPERAND (x, 1), flags);
4005 3263578 : op2 = cp_fold (TREE_OPERAND (x, 2), flags);
4006 3263578 : op3 = cp_fold (TREE_OPERAND (x, 3), flags);
4007 :
4008 3263578 : if (op0 == error_mark_node
4009 3263578 : || op1 == error_mark_node
4010 3263578 : || op2 == error_mark_node
4011 3263578 : || op3 == error_mark_node)
4012 0 : x = error_mark_node;
4013 3263578 : else if (op0 != TREE_OPERAND (x, 0)
4014 2243585 : || op1 != TREE_OPERAND (x, 1)
4015 1739113 : || op2 != TREE_OPERAND (x, 2)
4016 5002691 : || op3 != TREE_OPERAND (x, 3))
4017 : {
4018 1524465 : x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
4019 1524465 : TREE_READONLY (x) = TREE_READONLY (org_x);
4020 1524465 : TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
4021 1524465 : TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
4022 : }
4023 :
4024 3263578 : if (!(flags & ff_only_non_odr))
4025 1898776 : x = fold (x);
4026 : break;
4027 :
4028 1720762 : case SAVE_EXPR:
4029 : /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
4030 : folding, evaluates to an invariant. In that case no need to wrap
4031 : this folded tree with a SAVE_EXPR. */
4032 1720762 : r = cp_fold (TREE_OPERAND (x, 0), flags);
4033 1720762 : if (tree_invariant_p (r))
4034 57 : x = r;
4035 : break;
4036 :
4037 16 : case REQUIRES_EXPR:
4038 16 : x = evaluate_requires_expr (x);
4039 16 : break;
4040 :
4041 : default:
4042 : return org_x;
4043 : }
4044 :
4045 2429970208 : if (EXPR_P (x) && TREE_CODE (x) == code)
4046 : {
4047 2021581569 : TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
4048 2021581569 : copy_warning (x, org_x);
4049 : }
4050 :
4051 2429970208 : if (!c.evaluation_restricted_p ())
4052 : {
4053 2429924385 : fold_cache->put (org_x, x);
4054 : /* Prevent that we try to fold an already folded result again. */
4055 2429924385 : if (x != org_x)
4056 762869468 : fold_cache->put (x, x);
4057 : }
4058 :
4059 : return x;
4060 : }
4061 :
4062 : /* Look up "hot", "cold", "likely" or "unlikely" in attribute list LIST. */
4063 :
4064 : tree
4065 316299715 : lookup_hotness_attribute (tree list)
4066 : {
4067 316408419 : for (; list; list = TREE_CHAIN (list))
4068 : {
4069 2043681 : tree name = get_attribute_name (list);
4070 2043681 : if ((is_attribute_p ("hot", name)
4071 2043681 : || is_attribute_p ("cold", name)
4072 2043678 : || is_attribute_p ("likely", name)
4073 1405500 : || is_attribute_p ("unlikely", name))
4074 3978667 : && is_attribute_namespace_p ("", list))
4075 : break;
4076 : }
4077 316299715 : return list;
4078 : }
4079 :
4080 : /* Remove "hot", "cold", "likely" and "unlikely" attributes from LIST. */
4081 :
4082 : static tree
4083 1934968 : remove_hotness_attribute (tree list)
4084 : {
4085 3869954 : for (tree *p = &list; *p; )
4086 : {
4087 1934986 : tree l = *p;
4088 1934986 : tree name = get_attribute_name (l);
4089 1934986 : if ((is_attribute_p ("hot", name)
4090 1934986 : || is_attribute_p ("cold", name)
4091 1934983 : || is_attribute_p ("likely", name)
4092 1296805 : || is_attribute_p ("unlikely", name))
4093 3869972 : && is_attribute_namespace_p ("", l))
4094 : {
4095 1934977 : *p = TREE_CHAIN (l);
4096 1934977 : continue;
4097 : }
4098 9 : p = &TREE_CHAIN (l);
4099 : }
4100 1934968 : return list;
4101 : }
4102 :
4103 : /* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
4104 : PREDICT_EXPR. */
4105 :
4106 : tree
4107 314364765 : process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc)
4108 : {
4109 314364765 : if (std_attrs == error_mark_node)
4110 : return std_attrs;
4111 314364747 : if (tree attr = lookup_hotness_attribute (std_attrs))
4112 : {
4113 1934968 : tree name = get_attribute_name (attr);
4114 1934968 : bool hot = (is_attribute_p ("hot", name)
4115 1934968 : || is_attribute_p ("likely", name));
4116 1934968 : tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL,
4117 : hot ? TAKEN : NOT_TAKEN);
4118 1934968 : SET_EXPR_LOCATION (pred, attrs_loc);
4119 1934968 : add_stmt (pred);
4120 1934968 : if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
4121 : {
4122 9 : auto_urlify_attributes sentinel;
4123 9 : warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
4124 : get_attribute_name (other), name);
4125 9 : }
4126 1934968 : std_attrs = remove_hotness_attribute (std_attrs);
4127 : }
4128 : return std_attrs;
4129 : }
4130 :
4131 : /* Build IFN_ASSUME internal call for assume condition ARG. */
4132 :
4133 : tree
4134 11922 : build_assume_call (location_t loc, tree arg)
4135 : {
4136 11922 : if (!processing_template_decl)
4137 11821 : arg = fold_build_cleanup_point_expr (TREE_TYPE (arg), arg);
4138 11922 : return build_call_expr_internal_loc (loc, IFN_ASSUME, void_type_node,
4139 11922 : 1, arg);
4140 : }
4141 :
4142 : /* If [[assume (cond)]] appears on this statement, handle it. */
4143 :
4144 : tree
4145 247602707 : process_stmt_assume_attribute (tree std_attrs, tree statement,
4146 : location_t attrs_loc)
4147 : {
4148 247602707 : if (std_attrs == error_mark_node)
4149 : return std_attrs;
4150 247602689 : tree attr = lookup_attribute ("gnu", "assume", std_attrs);
4151 247602689 : if (!attr)
4152 : return std_attrs;
4153 : /* The next token after the assume attribute is not ';'. */
4154 11838 : if (statement)
4155 : {
4156 12 : warning_at (attrs_loc, OPT_Wattributes,
4157 : "%<assume%> attribute not followed by %<;%>");
4158 12 : attr = NULL_TREE;
4159 : }
4160 23700 : for (; attr; attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
4161 : {
4162 11862 : tree args = TREE_VALUE (attr);
4163 11862 : if (args && PACK_EXPANSION_P (args))
4164 : {
4165 6 : auto_diagnostic_group d;
4166 6 : error_at (attrs_loc, "pack expansion of %qE attribute",
4167 : get_attribute_name (attr));
4168 6 : if (cxx_dialect >= cxx17)
4169 4 : inform (attrs_loc, "use fold expression in the attribute "
4170 : "argument instead");
4171 6 : continue;
4172 6 : }
4173 11856 : int nargs = list_length (args);
4174 11856 : if (nargs != 1)
4175 : {
4176 42 : auto_diagnostic_group d;
4177 42 : error_at (attrs_loc, "wrong number of arguments specified for "
4178 : "%qE attribute", get_attribute_name (attr));
4179 42 : inform (attrs_loc, "expected %i, found %i", 1, nargs);
4180 42 : }
4181 : else
4182 : {
4183 11814 : tree arg = TREE_VALUE (args);
4184 11814 : if (!type_dependent_expression_p (arg))
4185 11713 : arg = contextual_conv_bool (arg, tf_warning_or_error);
4186 11814 : if (error_operand_p (arg))
4187 18 : continue;
4188 11796 : finish_expr_stmt (build_assume_call (attrs_loc, arg));
4189 : }
4190 : }
4191 11838 : return remove_attribute ("gnu", "assume", std_attrs);
4192 : }
4193 :
4194 : /* Return the type std::source_location::__impl after performing
4195 : verification on it. */
4196 :
4197 : tree
4198 10400 : get_source_location_impl_type ()
4199 : {
4200 10400 : tree name = get_identifier ("source_location");
4201 10400 : tree decl = lookup_qualified_name (std_node, name);
4202 10400 : if (TREE_CODE (decl) != TYPE_DECL)
4203 : {
4204 6 : auto_diagnostic_group d;
4205 6 : if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
4206 3 : qualified_name_lookup_error (std_node, name, decl, input_location);
4207 : else
4208 3 : error ("%qD is not a type", decl);
4209 6 : return error_mark_node;
4210 6 : }
4211 10394 : name = get_identifier ("__impl");
4212 10394 : tree type = TREE_TYPE (decl);
4213 10394 : decl = lookup_qualified_name (type, name);
4214 10394 : if (TREE_CODE (decl) != TYPE_DECL)
4215 : {
4216 9 : auto_diagnostic_group d;
4217 9 : if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
4218 6 : qualified_name_lookup_error (type, name, decl, input_location);
4219 : else
4220 3 : error ("%qD is not a type", decl);
4221 9 : return error_mark_node;
4222 9 : }
4223 10385 : type = TREE_TYPE (decl);
4224 10385 : if (TREE_CODE (type) != RECORD_TYPE)
4225 : {
4226 3 : error ("%qD is not a class type", decl);
4227 3 : return error_mark_node;
4228 : }
4229 :
4230 10382 : int cnt = 0;
4231 10382 : for (tree field = TYPE_FIELDS (type);
4232 51871 : (field = next_aggregate_field (field)) != NULL_TREE;
4233 41489 : field = DECL_CHAIN (field))
4234 : {
4235 41498 : if (DECL_NAME (field) != NULL_TREE)
4236 : {
4237 41498 : const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
4238 41498 : if (strcmp (n, "_M_file_name") == 0
4239 31119 : || strcmp (n, "_M_function_name") == 0)
4240 : {
4241 20755 : if (TREE_TYPE (field) != const_string_type_node)
4242 : {
4243 3 : error ("%qD does not have %<const char *%> type", field);
4244 3 : return error_mark_node;
4245 : }
4246 20752 : cnt++;
4247 20752 : continue;
4248 : }
4249 20743 : else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0)
4250 : {
4251 20740 : if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
4252 : {
4253 3 : error ("%qD does not have integral type", field);
4254 3 : return error_mark_node;
4255 : }
4256 20737 : cnt++;
4257 20737 : continue;
4258 : }
4259 : }
4260 : cnt = 0;
4261 : break;
4262 : }
4263 10376 : if (cnt != 4)
4264 : {
4265 9 : error ("%<std::source_location::__impl%> does not contain only "
4266 : "non-static data members %<_M_file_name%>, "
4267 : "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
4268 9 : return error_mark_node;
4269 : }
4270 10367 : return build_qualified_type (type, TYPE_QUAL_CONST);
4271 : }
4272 :
4273 : /* Type for source_location_table hash_set. */
4274 : struct GTY((for_user)) source_location_table_entry {
4275 : location_t loc;
4276 : unsigned uid;
4277 : tree var;
4278 : };
4279 :
4280 : /* Traits class for function start hash maps below. */
4281 :
4282 : struct source_location_table_entry_hash
4283 : : ggc_remove <source_location_table_entry>
4284 : {
4285 : typedef source_location_table_entry value_type;
4286 : typedef source_location_table_entry compare_type;
4287 :
4288 : static hashval_t
4289 59699 : hash (const source_location_table_entry &ref)
4290 : {
4291 59699 : inchash::hash hstate (0);
4292 59699 : hstate.add_int (ref.loc);
4293 59699 : hstate.add_int (ref.uid);
4294 59699 : return hstate.end ();
4295 : }
4296 :
4297 : static bool
4298 51639 : equal (const source_location_table_entry &ref1,
4299 : const source_location_table_entry &ref2)
4300 : {
4301 51639 : return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
4302 : }
4303 :
4304 : static void
4305 : mark_deleted (source_location_table_entry &ref)
4306 : {
4307 : ref.loc = UNKNOWN_LOCATION;
4308 : ref.uid = -1U;
4309 : ref.var = NULL_TREE;
4310 : }
4311 :
4312 : static const bool empty_zero_p = true;
4313 :
4314 : static void
4315 0 : mark_empty (source_location_table_entry &ref)
4316 : {
4317 0 : ref.loc = UNKNOWN_LOCATION;
4318 0 : ref.uid = 0;
4319 0 : ref.var = NULL_TREE;
4320 : }
4321 :
4322 : static bool
4323 83781 : is_deleted (const source_location_table_entry &ref)
4324 : {
4325 83781 : return (ref.loc == UNKNOWN_LOCATION
4326 0 : && ref.uid == -1U
4327 83781 : && ref.var == NULL_TREE);
4328 : }
4329 :
4330 : static bool
4331 316361 : is_empty (const source_location_table_entry &ref)
4332 : {
4333 316361 : return (ref.loc == UNKNOWN_LOCATION
4334 140069 : && ref.uid == 0
4335 456430 : && ref.var == NULL_TREE);
4336 : }
4337 :
4338 : static void
4339 3 : pch_nx (source_location_table_entry &p)
4340 : {
4341 3 : extern void gt_pch_nx (source_location_table_entry &);
4342 3 : gt_pch_nx (p);
4343 : }
4344 :
4345 : static void
4346 3 : pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
4347 : {
4348 3 : extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
4349 : void *);
4350 3 : gt_pch_nx (&p, op, cookie);
4351 : }
4352 : };
4353 :
4354 : static GTY(()) hash_table <source_location_table_entry_hash>
4355 : *source_location_table;
4356 :
4357 : /* Build a std::source_location::__impl from a location_t. */
4358 :
4359 : tree
4360 12158 : build_source_location_impl (location_t loc, tree fndecl,
4361 : tree source_location_impl)
4362 : {
4363 12158 : if (source_location_table == NULL)
4364 390 : source_location_table
4365 390 : = hash_table <source_location_table_entry_hash>::create_ggc (64);
4366 12158 : const line_map_ordinary *map;
4367 12158 : source_location_table_entry entry;
4368 12158 : entry.loc
4369 12158 : = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
4370 : &map);
4371 12158 : entry.uid = fndecl ? DECL_UID (fndecl) : -1;
4372 12158 : entry.var = error_mark_node;
4373 12158 : source_location_table_entry *entryp
4374 12158 : = source_location_table->find_slot (entry, INSERT);
4375 :
4376 12158 : if (entryp->var)
4377 : return entryp->var;
4378 :
4379 8973 : tree var = build_decl (loc, VAR_DECL, generate_internal_label ("Lsrc_loc"),
4380 : source_location_impl);
4381 8973 : TREE_STATIC (var) = 1;
4382 8973 : TREE_PUBLIC (var) = 0;
4383 8973 : DECL_ARTIFICIAL (var) = 1;
4384 8973 : DECL_IGNORED_P (var) = 1;
4385 8973 : DECL_EXTERNAL (var) = 0;
4386 8973 : DECL_DECLARED_CONSTEXPR_P (var) = 1;
4387 8973 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
4388 8973 : layout_decl (var, 0);
4389 :
4390 8973 : vec<constructor_elt, va_gc> *v = NULL;
4391 8973 : vec_alloc (v, 4);
4392 8973 : for (tree field = TYPE_FIELDS (source_location_impl);
4393 44865 : (field = next_aggregate_field (field)) != NULL_TREE;
4394 35892 : field = DECL_CHAIN (field))
4395 : {
4396 35892 : const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
4397 35892 : tree val = NULL_TREE;
4398 35892 : if (strcmp (n, "_M_file_name") == 0)
4399 : {
4400 8973 : if (const char *fname = LOCATION_FILE (loc))
4401 : {
4402 8973 : fname = remap_macro_filename (fname);
4403 8973 : val = build_string_literal (fname);
4404 : }
4405 : else
4406 0 : val = build_string_literal ("");
4407 : }
4408 26919 : else if (strcmp (n, "_M_function_name") == 0)
4409 : {
4410 8973 : const char *name = "";
4411 :
4412 8973 : if (fndecl)
4413 : {
4414 : /* If this is a coroutine, we should get the name of the user
4415 : function rather than the actor we generate. */
4416 8574 : if (tree ramp = DECL_RAMP_FN (fndecl))
4417 12 : name = cxx_printable_name (ramp, 2);
4418 : else
4419 8562 : name = cxx_printable_name (fndecl, 2);
4420 : }
4421 :
4422 8973 : val = build_string_literal (name);
4423 : }
4424 17946 : else if (strcmp (n, "_M_line") == 0)
4425 8973 : val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
4426 8973 : else if (strcmp (n, "_M_column") == 0)
4427 8973 : val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
4428 : else
4429 0 : gcc_unreachable ();
4430 35892 : CONSTRUCTOR_APPEND_ELT (v, field, val);
4431 : }
4432 :
4433 8973 : tree ctor = build_constructor (source_location_impl, v);
4434 8973 : TREE_CONSTANT (ctor) = 1;
4435 8973 : TREE_STATIC (ctor) = 1;
4436 8973 : DECL_INITIAL (var) = ctor;
4437 8973 : varpool_node::finalize_decl (var);
4438 8973 : *entryp = entry;
4439 8973 : entryp->var = var;
4440 8973 : return var;
4441 : }
4442 :
4443 : /* Fold the __builtin_source_location () call T. */
4444 :
4445 : tree
4446 11106 : fold_builtin_source_location (const_tree t)
4447 : {
4448 11106 : gcc_assert (TREE_CODE (t) == CALL_EXPR);
4449 : /* TREE_TYPE (t) is const std::source_location::__impl* */
4450 11106 : tree source_location_impl = TREE_TYPE (TREE_TYPE (t));
4451 11106 : if (source_location_impl == error_mark_node)
4452 0 : return build_zero_cst (const_ptr_type_node);
4453 11106 : gcc_assert (CLASS_TYPE_P (source_location_impl)
4454 : && id_equal (TYPE_IDENTIFIER (source_location_impl), "__impl"));
4455 :
4456 11106 : location_t loc = EXPR_LOCATION (t);
4457 11106 : tree var = build_source_location_impl (loc, current_function_decl,
4458 : source_location_impl);
4459 11106 : return build_fold_addr_expr_with_type_loc (loc, var, TREE_TYPE (t));
4460 : }
4461 :
4462 : #include "gt-cp-cp-gimplify.h"
|