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