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