Branch data Line data Source code
1 : : /* C++-specific tree lowering bits; see also c-gimplify.cc and gimple.cc.
2 : :
3 : : Copyright (C) 2002-2024 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 : :
46 : : /* Keep track of forward references to immediate-escalating functions in
47 : : case they become consteval. This vector contains ADDR_EXPRs and
48 : : PTRMEM_CSTs; it also stores FUNCTION_DECLs that had an escalating
49 : : function call in them, to check that they can be evaluated to a constant,
50 : : and immediate-escalating functions that may become consteval. */
51 : : static GTY(()) hash_set<tree> *deferred_escalating_exprs;
52 : :
53 : : static void
54 : 4384689 : remember_escalating_expr (tree t)
55 : : {
56 : 4384689 : if (uses_template_parms (t))
57 : : /* Templates don't escalate, and cp_fold_immediate can get confused by
58 : : other template trees in the function body (c++/115986). */
59 : : return;
60 : 4384689 : if (!deferred_escalating_exprs)
61 : 5325 : deferred_escalating_exprs = hash_set<tree>::create_ggc (37);
62 : 4384689 : deferred_escalating_exprs->add (t);
63 : : }
64 : :
65 : : /* Flags for cp_fold and cp_fold_r. */
66 : :
67 : : enum fold_flags {
68 : : ff_none = 0,
69 : : /* Whether we're being called from cp_fold_function. */
70 : : ff_genericize = 1 << 0,
71 : : /* Whether we're folding a point where we know we're
72 : : definitely not in a manifestly constant-evaluated
73 : : context. */
74 : : ff_mce_false = 1 << 1,
75 : : };
76 : :
77 : : using fold_flags_t = int;
78 : :
79 : 84147966 : struct cp_fold_data
80 : : {
81 : : hash_set<tree> pset;
82 : : fold_flags_t flags;
83 : 84147966 : cp_fold_data (fold_flags_t flags): flags (flags) {}
84 : : };
85 : :
86 : : /* Forward declarations. */
87 : :
88 : : static tree cp_genericize_r (tree *, int *, void *);
89 : : static tree cp_fold_r (tree *, int *, void *);
90 : : static void cp_genericize_tree (tree*, bool);
91 : : static tree cp_fold (tree, fold_flags_t);
92 : : static tree cp_fold_immediate_r (tree *, int *, void *);
93 : :
94 : : /* Genericize a TRY_BLOCK. */
95 : :
96 : : static void
97 : 15786 : genericize_try_block (tree *stmt_p)
98 : : {
99 : 15786 : tree body = TRY_STMTS (*stmt_p);
100 : 15786 : tree cleanup = TRY_HANDLERS (*stmt_p);
101 : :
102 : 15786 : *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
103 : 15786 : }
104 : :
105 : : /* Genericize a HANDLER by converting to a CATCH_EXPR. */
106 : :
107 : : static void
108 : 18564 : genericize_catch_block (tree *stmt_p)
109 : : {
110 : 18564 : tree type = HANDLER_TYPE (*stmt_p);
111 : 18564 : tree body = HANDLER_BODY (*stmt_p);
112 : :
113 : : /* FIXME should the caught type go in TREE_TYPE? */
114 : 18564 : *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
115 : 18564 : }
116 : :
117 : : /* A terser interface for building a representation of an exception
118 : : specification. */
119 : :
120 : : static tree
121 : 5136 : build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
122 : : {
123 : 5136 : tree t;
124 : :
125 : : /* FIXME should the allowed types go in TREE_TYPE? */
126 : 5136 : t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
127 : 5136 : append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
128 : :
129 : 5136 : t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
130 : 5136 : append_to_statement_list (body, &TREE_OPERAND (t, 0));
131 : :
132 : 5136 : return t;
133 : : }
134 : :
135 : : /* Genericize an EH_SPEC_BLOCK by converting it to a
136 : : TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
137 : :
138 : : static void
139 : 5136 : genericize_eh_spec_block (tree *stmt_p)
140 : : {
141 : 5136 : tree body = EH_SPEC_STMTS (*stmt_p);
142 : 5136 : tree allowed = EH_SPEC_RAISES (*stmt_p);
143 : 5136 : tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
144 : :
145 : 5136 : *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
146 : 5136 : suppress_warning (*stmt_p);
147 : 5136 : suppress_warning (TREE_OPERAND (*stmt_p, 1));
148 : 5136 : }
149 : :
150 : : /* Return the first non-compound statement in STMT. */
151 : :
152 : : tree
153 : 11334090 : first_stmt (tree stmt)
154 : : {
155 : 18177980 : switch (TREE_CODE (stmt))
156 : : {
157 : 4250747 : case STATEMENT_LIST:
158 : 4250747 : if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt))
159 : 3278880 : return first_stmt (p->stmt);
160 : 971867 : return void_node;
161 : :
162 : 3565010 : case BIND_EXPR:
163 : 3565010 : return first_stmt (BIND_EXPR_BODY (stmt));
164 : :
165 : : default:
166 : : return stmt;
167 : : }
168 : : }
169 : :
170 : : /* Genericize an IF_STMT by turning it into a COND_EXPR. */
171 : :
172 : : static void
173 : 16418554 : genericize_if_stmt (tree *stmt_p)
174 : : {
175 : 16418554 : tree stmt, cond, then_, else_;
176 : 16418554 : location_t locus = EXPR_LOCATION (*stmt_p);
177 : :
178 : 16418554 : stmt = *stmt_p;
179 : 16418554 : cond = IF_COND (stmt);
180 : 16418554 : then_ = THEN_CLAUSE (stmt);
181 : 16418554 : else_ = ELSE_CLAUSE (stmt);
182 : :
183 : 16418554 : if (then_ && else_)
184 : : {
185 : 5667045 : tree ft = first_stmt (then_);
186 : 5667045 : tree fe = first_stmt (else_);
187 : 5667045 : br_predictor pr;
188 : 5667045 : if (TREE_CODE (ft) == PREDICT_EXPR
189 : 39140 : && TREE_CODE (fe) == PREDICT_EXPR
190 : 36 : && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe)
191 : 5667072 : && (pr == PRED_HOT_LABEL || pr == PRED_COLD_LABEL))
192 : : {
193 : 3 : gcc_rich_location richloc (EXPR_LOC_OR_LOC (ft, locus));
194 : 3 : richloc.add_range (EXPR_LOC_OR_LOC (fe, locus));
195 : 3 : warning_at (&richloc, OPT_Wattributes,
196 : : "both branches of %<if%> statement marked as %qs",
197 : : pr == PRED_HOT_LABEL ? "likely" : "unlikely");
198 : 3 : }
199 : : }
200 : :
201 : 16418554 : if (!then_)
202 : 115 : then_ = build_empty_stmt (locus);
203 : 16418554 : if (!else_)
204 : 10751434 : else_ = build_empty_stmt (locus);
205 : :
206 : : /* consteval if has been verified not to have the then_/else_ blocks
207 : : entered by gotos/case labels from elsewhere, and as then_ block
208 : : can contain unfolded immediate function calls, we have to discard
209 : : the then_ block regardless of whether else_ has side-effects or not. */
210 : 16418554 : if (IF_STMT_CONSTEVAL_P (stmt))
211 : : {
212 : 6779 : if (block_may_fallthru (then_))
213 : 2430 : stmt = build3 (COND_EXPR, void_type_node, boolean_false_node,
214 : : void_node, else_);
215 : : else
216 : : stmt = else_;
217 : : }
218 : 16411775 : else if (IF_STMT_CONSTEXPR_P (stmt))
219 : 2187615 : stmt = integer_nonzerop (cond) ? then_ : else_;
220 : : /* ??? This optimization doesn't seem to belong here, but removing it
221 : : causes -Wreturn-type regressions (e.g. 107310). */
222 : 14224160 : else if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
223 : : stmt = then_;
224 : 14178933 : else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
225 : : stmt = else_;
226 : : else
227 : 14145807 : stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
228 : 16418554 : protected_set_expr_location_if_unset (stmt, locus);
229 : 16418554 : *stmt_p = stmt;
230 : 16418554 : }
231 : :
232 : : /* Hook into the middle of gimplifying an OMP_FOR node. */
233 : :
234 : : static enum gimplify_status
235 : 44590 : cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
236 : : {
237 : 44590 : tree for_stmt = *expr_p;
238 : 44590 : gimple_seq seq = NULL;
239 : :
240 : : /* Protect ourselves from recursion. */
241 : 44590 : if (OMP_FOR_GIMPLIFYING_P (for_stmt))
242 : : return GS_UNHANDLED;
243 : 20710 : OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
244 : :
245 : 20710 : gimplify_and_add (for_stmt, &seq);
246 : 20710 : gimple_seq_add_seq (pre_p, seq);
247 : :
248 : 20710 : OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
249 : :
250 : 20710 : return GS_ALL_DONE;
251 : : }
252 : :
253 : : /* Gimplify an EXPR_STMT node. */
254 : :
255 : : static void
256 : 3871562 : gimplify_expr_stmt (tree *stmt_p)
257 : : {
258 : 3871562 : tree stmt = EXPR_STMT_EXPR (*stmt_p);
259 : :
260 : 3871562 : if (stmt == error_mark_node)
261 : : stmt = NULL;
262 : :
263 : : /* Gimplification of a statement expression will nullify the
264 : : statement if all its side effects are moved to *PRE_P and *POST_P.
265 : :
266 : : In this case we will not want to emit the gimplified statement.
267 : : However, we may still want to emit a warning, so we do that before
268 : : gimplification. */
269 : 3867861 : if (stmt && warn_unused_value)
270 : : {
271 : 304897 : if (!TREE_SIDE_EFFECTS (stmt))
272 : : {
273 : 0 : if (!IS_EMPTY_STMT (stmt)
274 : 7158 : && !VOID_TYPE_P (TREE_TYPE (stmt))
275 : 7158 : && !warning_suppressed_p (stmt, OPT_Wunused_value))
276 : 0 : warning (OPT_Wunused_value, "statement with no effect");
277 : : }
278 : : else
279 : 297739 : warn_if_unused_value (stmt, input_location);
280 : : }
281 : :
282 : 3871562 : if (stmt == NULL_TREE)
283 : 3701 : stmt = alloc_stmt_list ();
284 : :
285 : 3871562 : *stmt_p = stmt;
286 : 3871562 : }
287 : :
288 : : /* Gimplify initialization from an AGGR_INIT_EXPR. */
289 : :
290 : : static void
291 : 10243126 : cp_gimplify_init_expr (tree *expr_p)
292 : : {
293 : 10243126 : tree from = TREE_OPERAND (*expr_p, 1);
294 : 10243126 : tree to = TREE_OPERAND (*expr_p, 0);
295 : 10243126 : tree t;
296 : :
297 : 10243126 : if (TREE_CODE (from) == TARGET_EXPR)
298 : 159614 : if (tree init = TARGET_EXPR_INITIAL (from))
299 : : {
300 : : /* Make sure that we expected to elide this temporary. But also allow
301 : : gimplify_modify_expr_rhs to elide temporaries of trivial type. */
302 : 159614 : gcc_checking_assert (TARGET_EXPR_ELIDING_P (from)
303 : : || !TREE_ADDRESSABLE (TREE_TYPE (from)));
304 : 159614 : if (target_expr_needs_replace (from))
305 : : {
306 : : /* If this was changed by cp_genericize_target_expr, we need to
307 : : walk into it to replace uses of the slot. */
308 : 25 : replace_decl (&init, TARGET_EXPR_SLOT (from), to);
309 : 25 : *expr_p = init;
310 : 25 : return;
311 : : }
312 : : else
313 : : from = init;
314 : : }
315 : :
316 : : /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
317 : : inside the TARGET_EXPR. */
318 : 10303921 : for (t = from; t; )
319 : : {
320 : 10303921 : tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
321 : :
322 : : /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
323 : : replace the slot operand with our target.
324 : :
325 : : Should we add a target parm to gimplify_expr instead? No, as in this
326 : : case we want to replace the INIT_EXPR. */
327 : 10303921 : if (TREE_CODE (sub) == AGGR_INIT_EXPR
328 : 10303921 : || TREE_CODE (sub) == VEC_INIT_EXPR)
329 : : {
330 : 93324 : if (TREE_CODE (sub) == AGGR_INIT_EXPR)
331 : 93324 : AGGR_INIT_EXPR_SLOT (sub) = to;
332 : : else
333 : 0 : VEC_INIT_EXPR_SLOT (sub) = to;
334 : 93324 : *expr_p = from;
335 : :
336 : : /* The initialization is now a side-effect, so the container can
337 : : become void. */
338 : 93324 : if (from != sub)
339 : 70 : TREE_TYPE (from) = void_type_node;
340 : : }
341 : :
342 : : /* Handle aggregate NSDMI. */
343 : 10303921 : replace_placeholders (sub, to);
344 : :
345 : 10303921 : if (t == sub)
346 : : break;
347 : : else
348 : 60820 : t = TREE_OPERAND (t, 1);
349 : : }
350 : :
351 : : }
352 : :
353 : : /* Gimplify a MUST_NOT_THROW_EXPR. */
354 : :
355 : : static enum gimplify_status
356 : 519943 : gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
357 : : {
358 : 519943 : tree stmt = *expr_p;
359 : 519943 : tree temp = voidify_wrapper_expr (stmt, NULL);
360 : 519943 : tree body = TREE_OPERAND (stmt, 0);
361 : 519943 : gimple_seq try_ = NULL;
362 : 519943 : gimple_seq catch_ = NULL;
363 : 519943 : gimple *mnt;
364 : :
365 : 519943 : gimplify_and_add (body, &try_);
366 : 519943 : mnt = gimple_build_eh_must_not_throw (call_terminate_fn);
367 : 519943 : gimple_seq_add_stmt_without_update (&catch_, mnt);
368 : 519943 : mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
369 : :
370 : 519943 : gimple_seq_add_stmt_without_update (pre_p, mnt);
371 : 519943 : if (temp)
372 : : {
373 : 33 : *expr_p = temp;
374 : 33 : return GS_OK;
375 : : }
376 : :
377 : 519910 : *expr_p = NULL;
378 : 519910 : return GS_ALL_DONE;
379 : : }
380 : :
381 : : /* Return TRUE if an operand (OP) of a given TYPE being copied is
382 : : really just an empty class copy.
383 : :
384 : : Check that the operand has a simple form so that TARGET_EXPRs and
385 : : non-empty CONSTRUCTORs get reduced properly, and we leave the
386 : : return slot optimization alone because it isn't a copy. */
387 : :
388 : : bool
389 : 16696006 : simple_empty_class_p (tree type, tree op, tree_code code)
390 : : {
391 : 19505366 : if (TREE_CODE (op) == COMPOUND_EXPR)
392 : 131873 : return simple_empty_class_p (type, TREE_OPERAND (op, 1), code);
393 : 3068289 : if (SIMPLE_TARGET_EXPR_P (op)
394 : 22054767 : && TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
395 : : /* The TARGET_EXPR is itself a simple copy, look through it. */
396 : 2677487 : return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
397 : :
398 : 16696006 : if (TREE_CODE (op) == PARM_DECL
399 : 16696006 : && TREE_ADDRESSABLE (TREE_TYPE (op)))
400 : : {
401 : 4 : tree fn = DECL_CONTEXT (op);
402 : 4 : if (DECL_THUNK_P (fn)
403 : 8 : || lambda_static_thunk_p (fn))
404 : : /* In a thunk, we pass through invisible reference parms, so this isn't
405 : : actually a copy. */
406 : 3 : return false;
407 : : }
408 : :
409 : 16696003 : return
410 : 16696003 : (TREE_CODE (op) == EMPTY_CLASS_EXPR
411 : 16695973 : || code == MODIFY_EXPR
412 : 13952116 : || is_gimple_lvalue (op)
413 : 10858806 : || INDIRECT_REF_P (op)
414 : 10510905 : || (TREE_CODE (op) == CONSTRUCTOR
415 : 2265233 : && CONSTRUCTOR_NELTS (op) == 0)
416 : 8413100 : || (TREE_CODE (op) == CALL_EXPR
417 : 2342250 : && !CALL_EXPR_RETURN_SLOT_OPT (op)))
418 : 10554105 : && !TREE_CLOBBER_P (op)
419 : 26623970 : && is_really_empty_class (type, /*ignore_vptr*/true);
420 : : }
421 : :
422 : : /* Returns true if evaluating E as an lvalue has side-effects;
423 : : specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
424 : : have side-effects until there is a read or write through it. */
425 : :
426 : : static bool
427 : 2322189 : lvalue_has_side_effects (tree e)
428 : : {
429 : 2322189 : if (!TREE_SIDE_EFFECTS (e))
430 : : return false;
431 : 51353 : while (handled_component_p (e))
432 : : {
433 : 2367 : if (TREE_CODE (e) == ARRAY_REF
434 : 2367 : && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
435 : : return true;
436 : 1156 : e = TREE_OPERAND (e, 0);
437 : : }
438 : 48986 : if (DECL_P (e))
439 : : /* Just naming a variable has no side-effects. */
440 : : return false;
441 : 32893 : else if (INDIRECT_REF_P (e))
442 : : /* Similarly, indirection has no side-effects. */
443 : 32801 : return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
444 : : else
445 : : /* For anything else, trust TREE_SIDE_EFFECTS. */
446 : 92 : return TREE_SIDE_EFFECTS (e);
447 : : }
448 : :
449 : : /* Return true if FN is an immediate-escalating function. */
450 : :
451 : : static bool
452 : 49465561 : immediate_escalating_function_p (tree fn)
453 : : {
454 : 49465561 : if (!fn || !flag_immediate_escalation)
455 : : return false;
456 : :
457 : 49384268 : gcc_checking_assert (TREE_CODE (fn) == FUNCTION_DECL);
458 : :
459 : 49384268 : if (DECL_IMMEDIATE_FUNCTION_P (fn))
460 : : return false;
461 : :
462 : : /* An immediate-escalating function is
463 : : -- the call operator of a lambda that is not declared with the consteval
464 : : specifier */
465 : 50946832 : if (LAMBDA_FUNCTION_P (fn))
466 : : return true;
467 : : /* -- a defaulted special member function that is not declared with the
468 : : consteval specifier */
469 : 48279860 : special_function_kind sfk = special_memfn_p (fn);
470 : 48279860 : if (sfk != sfk_none && DECL_DEFAULTED_FN (fn))
471 : : return true;
472 : : /* -- a function that results from the instantiation of a templated entity
473 : : defined with the constexpr specifier. */
474 : 47786759 : return is_instantiation_of_constexpr (fn);
475 : : }
476 : :
477 : : /* Return true if FN is an immediate-escalating function that has not been
478 : : checked for escalating expressions.. */
479 : :
480 : : static bool
481 : 49464962 : unchecked_immediate_escalating_function_p (tree fn)
482 : : {
483 : 49464962 : return (immediate_escalating_function_p (fn)
484 : 49464962 : && !DECL_ESCALATION_CHECKED_P (fn));
485 : : }
486 : :
487 : : /* Promote FN to an immediate function, including its clones. */
488 : :
489 : : static void
490 : 183 : promote_function_to_consteval (tree fn)
491 : : {
492 : 183 : SET_DECL_IMMEDIATE_FUNCTION_P (fn);
493 : 183 : DECL_ESCALATION_CHECKED_P (fn) = true;
494 : 183 : tree clone;
495 : 219 : FOR_EACH_CLONE (clone, fn)
496 : : {
497 : 36 : SET_DECL_IMMEDIATE_FUNCTION_P (clone);
498 : 36 : DECL_ESCALATION_CHECKED_P (clone) = true;
499 : : }
500 : 183 : }
501 : :
502 : : /* A wrapper around cp_fold_immediate_r. Return a non-null tree if
503 : : we found a non-constant immediate function, or taking the address
504 : : of an immediate function. */
505 : :
506 : : tree
507 : 3466661 : cp_fold_immediate (tree *tp, mce_value manifestly_const_eval,
508 : : tree decl /*= current_function_decl*/)
509 : : {
510 : 3466661 : if (cxx_dialect <= cxx17)
511 : : return NULL_TREE;
512 : :
513 : 3036386 : temp_override<tree> cfd (current_function_decl, decl);
514 : :
515 : 3036386 : fold_flags_t flags = ff_none;
516 : 3036386 : if (manifestly_const_eval == mce_false)
517 : 1756468 : flags |= ff_mce_false;
518 : :
519 : 3036386 : cp_fold_data data (flags);
520 : 3036386 : int save_errorcount = errorcount;
521 : 3036386 : tree r = cp_walk_tree_without_duplicates (tp, cp_fold_immediate_r, &data);
522 : 3036386 : if (errorcount > save_errorcount)
523 : 49 : return integer_one_node;
524 : : return r;
525 : 3036386 : }
526 : :
527 : : /* Maybe say that FN (a function decl with DECL_IMMEDIATE_FUNCTION_P set)
528 : : was initially not an immediate function, but was promoted to one because
529 : : its body contained an immediate-escalating expression or conversion. */
530 : :
531 : : static void
532 : 326 : maybe_explain_promoted_consteval (location_t loc, tree fn)
533 : : {
534 : 326 : if (DECL_ESCALATION_CHECKED_P (fn))
535 : : {
536 : : /* See if we can figure out what made the function consteval. */
537 : 126 : tree x = cp_fold_immediate (&DECL_SAVED_TREE (fn), mce_unknown, NULL_TREE);
538 : 126 : if (x)
539 : 102 : inform (cp_expr_loc_or_loc (x, loc),
540 : : "%qD was promoted to an immediate function because its "
541 : : "body contains an immediate-escalating expression %qE", fn, x);
542 : : else
543 : 24 : inform (loc, "%qD was promoted to an immediate function", fn);
544 : : }
545 : 326 : }
546 : :
547 : : /* Gimplify *EXPR_P as rvalue into an expression that can't be modified
548 : : by expressions with side-effects in other operands. */
549 : :
550 : : static enum gimplify_status
551 : 28094 : gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
552 : : bool (*gimple_test_f) (tree))
553 : : {
554 : 28094 : enum gimplify_status t
555 : 28094 : = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
556 : 28094 : if (t == GS_ERROR)
557 : : return GS_ERROR;
558 : 28091 : else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
559 : 2782 : *expr_p = get_initialized_tmp_var (*expr_p, pre_p);
560 : : return t;
561 : : }
562 : :
563 : : /* Like gimplify_arg, but if ORDERED is set (which should be set if
564 : : any of the arguments this argument is sequenced before has
565 : : TREE_SIDE_EFFECTS set, make sure expressions with is_gimple_reg_type type
566 : : are gimplified into SSA_NAME or a fresh temporary and for
567 : : non-is_gimple_reg_type we don't optimize away TARGET_EXPRs. */
568 : :
569 : : static enum gimplify_status
570 : 3579982 : cp_gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
571 : : bool ordered)
572 : : {
573 : 3579982 : enum gimplify_status t;
574 : 3579982 : if (ordered
575 : 341086 : && !is_gimple_reg_type (TREE_TYPE (*arg_p))
576 : 3581675 : && TREE_CODE (*arg_p) == TARGET_EXPR)
577 : : {
578 : : /* gimplify_arg would strip away the TARGET_EXPR, but
579 : : that can mean we don't copy the argument and some following
580 : : argument with side-effect could modify it. */
581 : 1545 : protected_set_expr_location (*arg_p, call_location);
582 : 1545 : return gimplify_expr (arg_p, pre_p, NULL, is_gimple_lvalue, fb_either);
583 : : }
584 : : else
585 : : {
586 : 3578437 : t = gimplify_arg (arg_p, pre_p, call_location);
587 : 3578437 : if (t == GS_ERROR)
588 : : return GS_ERROR;
589 : 3578437 : else if (ordered
590 : 339541 : && is_gimple_reg_type (TREE_TYPE (*arg_p))
591 : 339393 : && is_gimple_variable (*arg_p)
592 : 193101 : && TREE_CODE (*arg_p) != SSA_NAME
593 : : /* No need to force references into register, references
594 : : can't be modified. */
595 : 116752 : && !TYPE_REF_P (TREE_TYPE (*arg_p))
596 : : /* And this can't be modified either. */
597 : 3664506 : && *arg_p != current_class_ptr)
598 : 9642 : *arg_p = get_initialized_tmp_var (*arg_p, pre_p);
599 : 3578437 : return t;
600 : : }
601 : :
602 : : }
603 : :
604 : : /* Do C++-specific gimplification. Args are as for gimplify_expr. */
605 : :
606 : : int
607 : 153307973 : cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
608 : : {
609 : 153307973 : int saved_stmts_are_full_exprs_p = 0;
610 : 153307973 : location_t loc = cp_expr_loc_or_input_loc (*expr_p);
611 : 153307973 : enum tree_code code = TREE_CODE (*expr_p);
612 : 153307973 : enum gimplify_status ret;
613 : :
614 : 153307973 : if (STATEMENT_CODE_P (code))
615 : : {
616 : 3911048 : saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
617 : 7822096 : current_stmt_tree ()->stmts_are_full_exprs_p
618 : 3911048 : = STMT_IS_FULL_EXPR_P (*expr_p);
619 : : }
620 : :
621 : 153307973 : switch (code)
622 : : {
623 : 306899 : case AGGR_INIT_EXPR:
624 : 306899 : simplify_aggr_init_expr (expr_p);
625 : 306899 : ret = GS_OK;
626 : 306899 : break;
627 : :
628 : 0 : case VEC_INIT_EXPR:
629 : 0 : {
630 : 0 : *expr_p = expand_vec_init_expr (NULL_TREE, *expr_p,
631 : : tf_warning_or_error);
632 : :
633 : 0 : cp_fold_data data (ff_genericize | ff_mce_false);
634 : 0 : cp_walk_tree (expr_p, cp_fold_r, &data, NULL);
635 : 0 : cp_genericize_tree (expr_p, false);
636 : 0 : copy_if_shared (expr_p);
637 : 0 : ret = GS_OK;
638 : 0 : }
639 : 0 : break;
640 : :
641 : 17477 : case THROW_EXPR:
642 : : /* FIXME communicate throw type to back end, probably by moving
643 : : THROW_EXPR into ../tree.def. */
644 : 17477 : *expr_p = TREE_OPERAND (*expr_p, 0);
645 : 17477 : ret = GS_OK;
646 : 17477 : break;
647 : :
648 : 519943 : case MUST_NOT_THROW_EXPR:
649 : 519943 : ret = gimplify_must_not_throw_expr (expr_p, pre_p);
650 : 519943 : break;
651 : :
652 : : /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
653 : : LHS of an assignment might also be involved in the RHS, as in bug
654 : : 25979. */
655 : 10243126 : case INIT_EXPR:
656 : 10243126 : cp_gimplify_init_expr (expr_p);
657 : 10243126 : if (TREE_CODE (*expr_p) != INIT_EXPR)
658 : : return GS_OK;
659 : : /* Fall through. */
660 : 13871331 : case MODIFY_EXPR:
661 : 10149777 : modify_expr_case:
662 : 13871331 : {
663 : : /* If the back end isn't clever enough to know that the lhs and rhs
664 : : types are the same, add an explicit conversion. */
665 : 13871331 : tree op0 = TREE_OPERAND (*expr_p, 0);
666 : 13871331 : tree op1 = TREE_OPERAND (*expr_p, 1);
667 : :
668 : 13871331 : if (!error_operand_p (op0)
669 : 13871331 : && !error_operand_p (op1)
670 : 13871292 : && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
671 : 13868595 : || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
672 : 13874031 : && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
673 : 9 : TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
674 : 9 : TREE_TYPE (op0), op1);
675 : :
676 : 13871322 : else if (simple_empty_class_p (TREE_TYPE (op0), op1, code))
677 : : {
678 : 122562 : while (TREE_CODE (op1) == TARGET_EXPR)
679 : : /* We're disconnecting the initializer from its target,
680 : : don't create a temporary. */
681 : 6060 : op1 = TARGET_EXPR_INITIAL (op1);
682 : :
683 : : /* Remove any copies of empty classes. Also drop volatile
684 : : variables on the RHS to avoid infinite recursion from
685 : : gimplify_expr trying to load the value. */
686 : 116502 : if (TREE_SIDE_EFFECTS (op1))
687 : : {
688 : 10772 : if (TREE_THIS_VOLATILE (op1)
689 : 0 : && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
690 : 0 : op1 = build_fold_addr_expr (op1);
691 : :
692 : 10772 : gimplify_and_add (op1, pre_p);
693 : : }
694 : 116502 : gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
695 : : is_gimple_lvalue, fb_lvalue);
696 : 116502 : *expr_p = TREE_OPERAND (*expr_p, 0);
697 : 116502 : if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p))
698 : : /* Avoid 'return *<retval>;' */
699 : 4 : *expr_p = TREE_OPERAND (*expr_p, 0);
700 : : }
701 : : /* P0145 says that the RHS is sequenced before the LHS.
702 : : gimplify_modify_expr gimplifies the RHS before the LHS, but that
703 : : isn't quite strong enough in two cases:
704 : :
705 : : 1) gimplify.cc wants to leave a CALL_EXPR on the RHS, which would
706 : : mean it's evaluated after the LHS.
707 : :
708 : : 2) the value calculation of the RHS is also sequenced before the
709 : : LHS, so for scalar assignment we need to preevaluate if the
710 : : RHS could be affected by LHS side-effects even if it has no
711 : : side-effects of its own. We don't need this for classes because
712 : : class assignment takes its RHS by reference. */
713 : 13754820 : else if (flag_strong_eval_order > 1
714 : 11816594 : && TREE_CODE (*expr_p) == MODIFY_EXPR
715 : 2322189 : && lvalue_has_side_effects (op0)
716 : 13788817 : && (TREE_CODE (op1) == CALL_EXPR
717 : 27356 : || (SCALAR_TYPE_P (TREE_TYPE (op1))
718 : 23040 : && !TREE_CONSTANT (op1))))
719 : 19740 : TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);
720 : : }
721 : : ret = GS_OK;
722 : : break;
723 : :
724 : 62170 : case EMPTY_CLASS_EXPR:
725 : : /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
726 : 62170 : *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
727 : 62170 : ret = GS_OK;
728 : 62170 : break;
729 : :
730 : 0 : case BASELINK:
731 : 0 : *expr_p = BASELINK_FUNCTIONS (*expr_p);
732 : 0 : ret = GS_OK;
733 : 0 : break;
734 : :
735 : 15786 : case TRY_BLOCK:
736 : 15786 : genericize_try_block (expr_p);
737 : 15786 : ret = GS_OK;
738 : 15786 : break;
739 : :
740 : 18564 : case HANDLER:
741 : 18564 : genericize_catch_block (expr_p);
742 : 18564 : ret = GS_OK;
743 : 18564 : break;
744 : :
745 : 5136 : case EH_SPEC_BLOCK:
746 : 5136 : genericize_eh_spec_block (expr_p);
747 : 5136 : ret = GS_OK;
748 : 5136 : break;
749 : :
750 : 0 : case USING_STMT:
751 : 0 : gcc_unreachable ();
752 : :
753 : 0 : case FOR_STMT:
754 : 0 : case WHILE_STMT:
755 : 0 : case DO_STMT:
756 : 0 : case SWITCH_STMT:
757 : 0 : case CONTINUE_STMT:
758 : 0 : case BREAK_STMT:
759 : 0 : gcc_unreachable ();
760 : :
761 : 44590 : case OMP_FOR:
762 : 44590 : case OMP_SIMD:
763 : 44590 : case OMP_DISTRIBUTE:
764 : 44590 : case OMP_LOOP:
765 : 44590 : case OMP_TASKLOOP:
766 : 44590 : case OMP_TILE:
767 : 44590 : case OMP_UNROLL:
768 : 44590 : ret = cp_gimplify_omp_for (expr_p, pre_p);
769 : 44590 : break;
770 : :
771 : 3871562 : case EXPR_STMT:
772 : 3871562 : gimplify_expr_stmt (expr_p);
773 : 3871562 : ret = GS_OK;
774 : 3871562 : break;
775 : :
776 : 0 : case UNARY_PLUS_EXPR:
777 : 0 : {
778 : 0 : tree arg = TREE_OPERAND (*expr_p, 0);
779 : 0 : tree type = TREE_TYPE (*expr_p);
780 : 0 : *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
781 : : : arg;
782 : 0 : ret = GS_OK;
783 : : }
784 : 0 : break;
785 : :
786 : 7252014 : case CALL_EXPR:
787 : 7252014 : ret = GS_OK;
788 : 7252014 : if (flag_strong_eval_order == 2
789 : 6323182 : && CALL_EXPR_FN (*expr_p)
790 : 6142879 : && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)
791 : 12807461 : && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
792 : : {
793 : 28094 : tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
794 : 28094 : enum gimplify_status t
795 : 28094 : = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
796 : : is_gimple_call_addr);
797 : 28094 : if (t == GS_ERROR)
798 : : ret = GS_ERROR;
799 : : /* GIMPLE considers most pointer conversion useless, but for
800 : : calls we actually care about the exact function pointer type. */
801 : 28091 : else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
802 : 2204 : CALL_EXPR_FN (*expr_p)
803 : 4408 : = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
804 : : }
805 : 7252014 : if (!CALL_EXPR_FN (*expr_p))
806 : : /* Internal function call. */;
807 : 7050980 : else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
808 : : {
809 : : /* This is a call to a (compound) assignment operator that used
810 : : the operator syntax; gimplify the RHS first. */
811 : 42940 : gcc_assert (call_expr_nargs (*expr_p) == 2);
812 : 42940 : gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
813 : 42940 : enum gimplify_status t
814 : 42940 : = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc,
815 : 42940 : TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, 0)));
816 : 42940 : if (t == GS_ERROR)
817 : : ret = GS_ERROR;
818 : : }
819 : 7008040 : else if (CALL_EXPR_ORDERED_ARGS (*expr_p))
820 : : {
821 : : /* Leave the last argument for gimplify_call_expr, to avoid problems
822 : : with __builtin_va_arg_pack(). */
823 : 167935 : int nargs = call_expr_nargs (*expr_p) - 1;
824 : 167935 : int last_side_effects_arg = -1;
825 : 324367 : for (int i = nargs; i > 0; --i)
826 : 174502 : if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
827 : : {
828 : : last_side_effects_arg = i;
829 : : break;
830 : : }
831 : 350991 : for (int i = 0; i < nargs; ++i)
832 : : {
833 : 183056 : enum gimplify_status t
834 : 183056 : = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc,
835 : : i < last_side_effects_arg);
836 : 183056 : if (t == GS_ERROR)
837 : 0 : ret = GS_ERROR;
838 : : }
839 : : }
840 : 6840105 : else if (flag_strong_eval_order
841 : 6840105 : && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
842 : : {
843 : : /* If flag_strong_eval_order, evaluate the object argument first. */
844 : 6407151 : tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
845 : 6407151 : if (INDIRECT_TYPE_P (fntype))
846 : 6407148 : fntype = TREE_TYPE (fntype);
847 : 6407151 : if (TREE_CODE (fntype) == METHOD_TYPE)
848 : : {
849 : 3353986 : int nargs = call_expr_nargs (*expr_p);
850 : 3353986 : bool side_effects = false;
851 : 4614587 : for (int i = 1; i < nargs; ++i)
852 : 1570225 : if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
853 : : {
854 : : side_effects = true;
855 : : break;
856 : : }
857 : 3353986 : enum gimplify_status t
858 : 3353986 : = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc,
859 : : side_effects);
860 : 3353986 : if (t == GS_ERROR)
861 : : ret = GS_ERROR;
862 : : }
863 : : }
864 : 7252014 : if (ret != GS_ERROR)
865 : : {
866 : 7252011 : tree decl = cp_get_callee_fndecl_nofold (*expr_p);
867 : 7252011 : if (!decl)
868 : : break;
869 : 7009310 : if (fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
870 : 0 : switch (DECL_FE_FUNCTION_CODE (decl))
871 : : {
872 : 0 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
873 : 0 : *expr_p = boolean_false_node;
874 : 0 : break;
875 : 0 : case CP_BUILT_IN_SOURCE_LOCATION:
876 : 0 : *expr_p
877 : 0 : = fold_builtin_source_location (*expr_p);
878 : 0 : break;
879 : 0 : case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
880 : 0 : *expr_p
881 : 0 : = fold_builtin_is_corresponding_member
882 : 0 : (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
883 : : &CALL_EXPR_ARG (*expr_p, 0));
884 : 0 : break;
885 : 0 : case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
886 : 0 : *expr_p
887 : 0 : = fold_builtin_is_pointer_inverconvertible_with_class
888 : 0 : (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
889 : : &CALL_EXPR_ARG (*expr_p, 0));
890 : 0 : break;
891 : : default:
892 : : break;
893 : : }
894 : 7009310 : else if (fndecl_built_in_p (decl, BUILT_IN_CLZG, BUILT_IN_CTZG))
895 : 27 : ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p,
896 : : post_p);
897 : : else
898 : : /* All consteval functions should have been processed by now. */
899 : 7009283 : gcc_checking_assert (!immediate_invocation_p (decl));
900 : : }
901 : : break;
902 : :
903 : 488652 : case TARGET_EXPR:
904 : : /* A TARGET_EXPR that expresses direct-initialization should have been
905 : : elided by cp_gimplify_init_expr. */
906 : 488652 : gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
907 : : /* Likewise, but allow extra temps of trivial type so that
908 : : gimplify_init_ctor_preeval can materialize subobjects of a CONSTRUCTOR
909 : : on the rhs of an assignment, as in constexpr-aggr1.C. */
910 : 488652 : gcc_checking_assert (!TARGET_EXPR_ELIDING_P (*expr_p)
911 : : || !TREE_ADDRESSABLE (TREE_TYPE (*expr_p)));
912 : : ret = GS_UNHANDLED;
913 : : break;
914 : :
915 : 3 : case PTRMEM_CST:
916 : 3 : *expr_p = cplus_expand_constant (*expr_p);
917 : 3 : if (TREE_CODE (*expr_p) == PTRMEM_CST)
918 : : ret = GS_ERROR;
919 : : else
920 : 18168928 : ret = GS_OK;
921 : : break;
922 : :
923 : 1031326 : case RETURN_EXPR:
924 : 1031326 : if (TREE_OPERAND (*expr_p, 0)
925 : 1031326 : && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
926 : 11036 : || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
927 : : {
928 : 977697 : expr_p = &TREE_OPERAND (*expr_p, 0);
929 : : /* Avoid going through the INIT_EXPR case, which can
930 : : degrade INIT_EXPRs into AGGR_INIT_EXPRs. */
931 : 977697 : goto modify_expr_case;
932 : : }
933 : : /* Fall through. */
934 : :
935 : 126740497 : default:
936 : 126740497 : ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
937 : 126740497 : break;
938 : : }
939 : :
940 : : /* Restore saved state. */
941 : 153214624 : if (STATEMENT_CODE_P (code))
942 : 3911048 : current_stmt_tree ()->stmts_are_full_exprs_p
943 : 3911048 : = saved_stmts_are_full_exprs_p;
944 : :
945 : : return ret;
946 : : }
947 : :
948 : : static inline bool
949 : 1562346021 : is_invisiref_parm (const_tree t)
950 : : {
951 : 1465310099 : return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
952 : 1595885776 : && DECL_BY_REFERENCE (t));
953 : : }
954 : :
955 : : /* A stable comparison routine for use with splay trees and DECLs. */
956 : :
957 : : static int
958 : 59046 : splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
959 : : {
960 : 59046 : tree a = (tree) xa;
961 : 59046 : tree b = (tree) xb;
962 : :
963 : 59046 : return DECL_UID (a) - DECL_UID (b);
964 : : }
965 : :
966 : : /* OpenMP context during genericization. */
967 : :
968 : : struct cp_genericize_omp_taskreg
969 : : {
970 : : bool is_parallel;
971 : : bool default_shared;
972 : : struct cp_genericize_omp_taskreg *outer;
973 : : splay_tree variables;
974 : : };
975 : :
976 : : /* Return true if genericization should try to determine if
977 : : DECL is firstprivate or shared within task regions. */
978 : :
979 : : static bool
980 : 114412 : omp_var_to_track (tree decl)
981 : : {
982 : 114412 : tree type = TREE_TYPE (decl);
983 : 114412 : if (is_invisiref_parm (decl))
984 : 537 : type = TREE_TYPE (type);
985 : 113875 : else if (TYPE_REF_P (type))
986 : 5151 : type = TREE_TYPE (type);
987 : 139331 : while (TREE_CODE (type) == ARRAY_TYPE)
988 : 24919 : type = TREE_TYPE (type);
989 : 114412 : if (type == error_mark_node || !CLASS_TYPE_P (type))
990 : : return false;
991 : 12979 : if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
992 : : return false;
993 : 12976 : if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
994 : : return false;
995 : : return true;
996 : : }
997 : :
998 : : /* Note DECL use in OpenMP region OMP_CTX during genericization. */
999 : :
1000 : : static void
1001 : 13298 : omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
1002 : : {
1003 : 13298 : splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
1004 : : (splay_tree_key) decl);
1005 : 13298 : if (n == NULL)
1006 : : {
1007 : 4164 : int flags = OMP_CLAUSE_DEFAULT_SHARED;
1008 : 4164 : if (omp_ctx->outer)
1009 : 1257 : omp_cxx_notice_variable (omp_ctx->outer, decl);
1010 : 4164 : if (!omp_ctx->default_shared)
1011 : : {
1012 : 948 : struct cp_genericize_omp_taskreg *octx;
1013 : :
1014 : 1065 : for (octx = omp_ctx->outer; octx; octx = octx->outer)
1015 : : {
1016 : 902 : n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
1017 : 902 : if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
1018 : : {
1019 : : flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
1020 : : break;
1021 : : }
1022 : 859 : if (octx->is_parallel)
1023 : : break;
1024 : : }
1025 : 948 : if (octx == NULL
1026 : 948 : && (TREE_CODE (decl) == PARM_DECL
1027 : 120 : || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1028 : 44 : && DECL_CONTEXT (decl) == current_function_decl)))
1029 : : flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
1030 : 861 : if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
1031 : : {
1032 : : /* DECL is implicitly determined firstprivate in
1033 : : the current task construct. Ensure copy ctor and
1034 : : dtor are instantiated, because during gimplification
1035 : : it will be already too late. */
1036 : 130 : tree type = TREE_TYPE (decl);
1037 : 130 : if (is_invisiref_parm (decl))
1038 : 2 : type = TREE_TYPE (type);
1039 : 128 : else if (TYPE_REF_P (type))
1040 : 55 : type = TREE_TYPE (type);
1041 : 180 : while (TREE_CODE (type) == ARRAY_TYPE)
1042 : 50 : type = TREE_TYPE (type);
1043 : 130 : get_copy_ctor (type, tf_none);
1044 : 130 : get_dtor (type, tf_none);
1045 : : }
1046 : : }
1047 : 4164 : splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
1048 : : }
1049 : 13298 : }
1050 : :
1051 : : /* True if any of the element initializers in CTOR are TARGET_EXPRs that are
1052 : : not expected to elide, e.g. because unsafe_copy_elision_p is true. */
1053 : :
1054 : : static bool
1055 : 45373 : any_non_eliding_target_exprs (tree ctor)
1056 : : {
1057 : 115549 : for (const constructor_elt &e : *CONSTRUCTOR_ELTS (ctor))
1058 : : {
1059 : 70179 : if (TREE_CODE (e.value) == TARGET_EXPR
1060 : 70179 : && !TARGET_EXPR_ELIDING_P (e.value))
1061 : : return true;
1062 : : }
1063 : : return false;
1064 : : }
1065 : :
1066 : : /* If we might need to clean up a partially constructed object, break down the
1067 : : CONSTRUCTOR with split_nonconstant_init. Also expand VEC_INIT_EXPR at this
1068 : : point. If initializing TO with FROM is non-trivial, overwrite *REPLACE with
1069 : : the result. */
1070 : :
1071 : : static void
1072 : 60299660 : cp_genericize_init (tree *replace, tree from, tree to, vec<tree,va_gc>** flags)
1073 : : {
1074 : 60299660 : tree init = NULL_TREE;
1075 : 60299660 : if (TREE_CODE (from) == VEC_INIT_EXPR)
1076 : 983 : init = expand_vec_init_expr (to, from, tf_warning_or_error, flags);
1077 : 60298677 : else if (TREE_CODE (from) == CONSTRUCTOR
1078 : 2305478 : && TREE_SIDE_EFFECTS (from)
1079 : 60344348 : && ((flag_exceptions
1080 : 45643 : && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (from)))
1081 : 45373 : || any_non_eliding_target_exprs (from)))
1082 : : {
1083 : 301 : to = cp_stabilize_reference (to);
1084 : 301 : replace_placeholders (from, to);
1085 : 301 : init = split_nonconstant_init (to, from);
1086 : : }
1087 : :
1088 : 1284 : if (init)
1089 : : {
1090 : 1284 : if (*replace == from)
1091 : : /* Make cp_gimplify_init_expr call replace_decl on this
1092 : : TARGET_EXPR_INITIAL. */
1093 : 310 : init = fold_convert (void_type_node, init);
1094 : 1284 : *replace = init;
1095 : : }
1096 : 60299660 : }
1097 : :
1098 : : /* For an INIT_EXPR, replace the INIT_EXPR itself. */
1099 : :
1100 : : static void
1101 : 46934234 : cp_genericize_init_expr (tree *stmt_p)
1102 : : {
1103 : 46934234 : iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
1104 : 46934234 : tree to = TREE_OPERAND (*stmt_p, 0);
1105 : 46934234 : tree from = TREE_OPERAND (*stmt_p, 1);
1106 : 4935362 : if (SIMPLE_TARGET_EXPR_P (from)
1107 : : /* Return gets confused if we clobber its INIT_EXPR this soon. */
1108 : 50481103 : && TREE_CODE (to) != RESULT_DECL)
1109 : 50153 : from = TARGET_EXPR_INITIAL (from);
1110 : 46934234 : cp_genericize_init (stmt_p, from, to, nullptr);
1111 : 46934234 : }
1112 : :
1113 : : /* For a TARGET_EXPR, change the TARGET_EXPR_INITIAL. We will need to use
1114 : : replace_decl later when we know what we're initializing. */
1115 : :
1116 : : static void
1117 : 13365426 : cp_genericize_target_expr (tree *stmt_p)
1118 : : {
1119 : 13365426 : iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
1120 : 13365426 : tree slot = TARGET_EXPR_SLOT (*stmt_p);
1121 : 13365426 : vec<tree, va_gc> *flags = make_tree_vector ();
1122 : 13365426 : cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p),
1123 : 13365426 : TARGET_EXPR_INITIAL (*stmt_p), slot, &flags);
1124 : 13365426 : gcc_assert (!DECL_INITIAL (slot));
1125 : 40096303 : for (tree f : flags)
1126 : : {
1127 : : /* Once initialization is complete TARGET_EXPR_CLEANUP becomes active, so
1128 : : disable any subobject cleanups. */
1129 : 25 : tree d = build_disable_temp_cleanup (f);
1130 : 25 : auto &r = TARGET_EXPR_INITIAL (*stmt_p);
1131 : 25 : r = add_stmt_to_compound (r, d);
1132 : : }
1133 : 13365426 : release_tree_vector (flags);
1134 : 13365426 : }
1135 : :
1136 : : /* Similar to if (target_expr_needs_replace) replace_decl, but TP is the
1137 : : TARGET_EXPR_INITIAL, and this also updates *_SLOT. We need this extra
1138 : : replacement when cp_folding TARGET_EXPR to preserve the invariant that
1139 : : AGGR_INIT_EXPR_SLOT agrees with the enclosing TARGET_EXPR_SLOT. */
1140 : :
1141 : : static bool
1142 : 99966 : maybe_replace_decl (tree *tp, tree decl, tree replacement)
1143 : : {
1144 : 99966 : if (!*tp || !VOID_TYPE_P (TREE_TYPE (*tp)))
1145 : : return false;
1146 : : tree t = *tp;
1147 : 54 : while (TREE_CODE (t) == COMPOUND_EXPR)
1148 : 0 : t = TREE_OPERAND (t, 1);
1149 : 54 : if (TREE_CODE (t) == AGGR_INIT_EXPR)
1150 : 54 : replace_decl (&AGGR_INIT_EXPR_SLOT (t), decl, replacement);
1151 : 0 : else if (TREE_CODE (t) == VEC_INIT_EXPR)
1152 : 0 : replace_decl (&VEC_INIT_EXPR_SLOT (t), decl, replacement);
1153 : : else
1154 : 0 : replace_decl (tp, decl, replacement);
1155 : : return true;
1156 : : }
1157 : :
1158 : : /* Genericization context. */
1159 : :
1160 : 39174475 : struct cp_genericize_data
1161 : : {
1162 : : hash_set<tree> *p_set;
1163 : : auto_vec<tree> bind_expr_stack;
1164 : : struct cp_genericize_omp_taskreg *omp_ctx;
1165 : : tree try_block;
1166 : : bool no_sanitize_p;
1167 : : bool handle_invisiref_parm_p;
1168 : : };
1169 : :
1170 : : /* Emit an error about taking the address of an immediate function.
1171 : : EXPR is the whole expression; DECL is the immediate function. */
1172 : :
1173 : : static void
1174 : 63 : taking_address_of_imm_fn_error (tree expr, tree decl)
1175 : : {
1176 : 63 : auto_diagnostic_group d;
1177 : 63 : const location_t loc = (TREE_CODE (expr) == PTRMEM_CST
1178 : 63 : ? PTRMEM_CST_LOCATION (expr)
1179 : 54 : : EXPR_LOCATION (expr));
1180 : 63 : error_at (loc, "taking address of an immediate function %qD", decl);
1181 : 63 : maybe_explain_promoted_consteval (loc, decl);
1182 : 63 : }
1183 : :
1184 : : /* A subroutine of cp_fold_r to handle immediate functions. */
1185 : :
1186 : : static tree
1187 : 740356294 : cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_)
1188 : : {
1189 : 740356294 : auto data = static_cast<cp_fold_data *>(data_);
1190 : 740356294 : tree stmt = *stmt_p;
1191 : : /* The purpose of this is not to emit errors for mce_unknown. */
1192 : 740356294 : const tsubst_flags_t complain = (data->flags & ff_mce_false
1193 : 740356294 : ? tf_error : tf_none);
1194 : 740356294 : const tree_code code = TREE_CODE (stmt);
1195 : :
1196 : : /* No need to look into types or unevaluated operands.
1197 : : NB: This affects cp_fold_r as well. */
1198 : 740356294 : if (TYPE_P (stmt)
1199 : 740225615 : || unevaluated_p (code)
1200 : : /* We do not use in_immediate_context here because it checks
1201 : : more than is desirable, e.g., sk_template_parms. */
1202 : 740153694 : || cp_unevaluated_operand
1203 : 1480509872 : || (current_function_decl
1204 : 1442782348 : && DECL_IMMEDIATE_FUNCTION_P (current_function_decl)))
1205 : : {
1206 : 207194 : *walk_subtrees = 0;
1207 : 207194 : return NULL_TREE;
1208 : : }
1209 : :
1210 : 740149100 : tree decl = NULL_TREE;
1211 : 740149100 : bool call_p = false;
1212 : :
1213 : : /* We are looking for &fn or fn(). */
1214 : 740149100 : switch (code)
1215 : : {
1216 : 38051659 : case CALL_EXPR:
1217 : 38051659 : case AGGR_INIT_EXPR:
1218 : 38051659 : if (tree fn = cp_get_callee (stmt))
1219 : 37848535 : if (TREE_CODE (fn) != ADDR_EXPR || ADDR_EXPR_DENOTES_CALL_P (fn))
1220 : 36822811 : decl = cp_get_fndecl_from_callee (fn, /*fold*/false);
1221 : 36822811 : call_p = true;
1222 : 36822811 : break;
1223 : 7911 : case PTRMEM_CST:
1224 : 7911 : decl = PTRMEM_CST_MEMBER (stmt);
1225 : 7911 : break;
1226 : 60717436 : case ADDR_EXPR:
1227 : 60717436 : if (!ADDR_EXPR_DENOTES_CALL_P (stmt))
1228 : 24630844 : decl = TREE_OPERAND (stmt, 0);
1229 : : break;
1230 : : default:
1231 : : return NULL_TREE;
1232 : : }
1233 : :
1234 : 61461566 : if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
1235 : 61118239 : return NULL_TREE;
1236 : :
1237 : : /* Fully escalate once all templates have been instantiated. What we're
1238 : : calling is not a consteval function but it may become one. This
1239 : : requires recursing; DECL may be promoted to consteval because it
1240 : : contains an escalating expression E, but E itself may have to be
1241 : : promoted first, etc. */
1242 : 37658767 : if (at_eof > 1 && unchecked_immediate_escalating_function_p (decl))
1243 : : {
1244 : : /* Set before the actual walk to avoid endless recursion. */
1245 : 1078175 : DECL_ESCALATION_CHECKED_P (decl) = true;
1246 : : /* We're only looking for the first escalating expression. Let us not
1247 : : walk more trees than necessary, hence mce_unknown. */
1248 : 1078175 : cp_fold_immediate (&DECL_SAVED_TREE (decl), mce_unknown, decl);
1249 : : }
1250 : :
1251 : : /* [expr.const]p16 "An expression or conversion is immediate-escalating if
1252 : : it is not initially in an immediate function context and it is either
1253 : : -- an immediate invocation that is not a constant expression and is not
1254 : : a subexpression of an immediate invocation."
1255 : :
1256 : : If we are in an immediate-escalating function, the immediate-escalating
1257 : : expression or conversion makes it an immediate function. So STMT does
1258 : : not need to produce a constant expression. */
1259 : 75317534 : if (DECL_IMMEDIATE_FUNCTION_P (decl))
1260 : : {
1261 : 101423 : tree e = cxx_constant_value (stmt, tf_none);
1262 : 101423 : if (e == error_mark_node)
1263 : : {
1264 : : /* This takes care of, e.g.,
1265 : : template <typename T>
1266 : : constexpr int f(T t)
1267 : : {
1268 : : return id(t);
1269 : : }
1270 : : where id (consteval) causes f<int> to be promoted. */
1271 : 599 : if (immediate_escalating_function_p (current_function_decl))
1272 : 183 : promote_function_to_consteval (current_function_decl);
1273 : 416 : else if (complain & tf_error)
1274 : : {
1275 : 314 : if (call_p)
1276 : : {
1277 : 263 : auto_diagnostic_group d;
1278 : 263 : location_t loc = cp_expr_loc_or_input_loc (stmt);
1279 : 263 : error_at (loc, "call to consteval function %qE is "
1280 : : "not a constant expression", stmt);
1281 : : /* Explain why it's not a constant expression. */
1282 : 263 : *stmt_p = cxx_constant_value (stmt, complain);
1283 : 263 : maybe_explain_promoted_consteval (loc, decl);
1284 : 263 : }
1285 : 51 : else if (!data->pset.add (stmt))
1286 : : {
1287 : 51 : taking_address_of_imm_fn_error (stmt, decl);
1288 : 51 : *stmt_p = build_zero_cst (TREE_TYPE (stmt));
1289 : : }
1290 : : /* If we're giving hard errors, continue the walk rather than
1291 : : bailing out after the first error. */
1292 : 314 : return NULL_TREE;
1293 : : }
1294 : 285 : *walk_subtrees = 0;
1295 : 285 : return stmt;
1296 : : }
1297 : : /* We've evaluated the consteval function call. */
1298 : 100824 : if (call_p)
1299 : 100824 : *stmt_p = e;
1300 : : }
1301 : : /* We've encountered a function call that may turn out to be consteval
1302 : : later. Store its caller so that we can ensure that the call is
1303 : : a constant expression. */
1304 : 37557344 : else if (unchecked_immediate_escalating_function_p (decl))
1305 : : {
1306 : : /* Make sure we're not inserting new elements while walking
1307 : : the deferred_escalating_exprs hash table; if we are, it's
1308 : : likely that a function wasn't properly marked checked for
1309 : : i-e expressions. */
1310 : 4384788 : gcc_checking_assert (at_eof <= 1);
1311 : 4384788 : if (current_function_decl)
1312 : 4384612 : remember_escalating_expr (current_function_decl);
1313 : : /* auto p = &f<int>; in the global scope won't be ensconced in
1314 : : a function we could store for later at this point. (If there's
1315 : : no c_f_d at this point and we're dealing with a call, we should
1316 : : see the call when cp_fold_function __static_i_and_d.) */
1317 : 176 : else if (!call_p)
1318 : 77 : remember_escalating_expr (stmt);
1319 : : }
1320 : :
1321 : : return NULL_TREE;
1322 : : }
1323 : :
1324 : : /* Perform any pre-gimplification folding of C++ front end trees to
1325 : : GENERIC.
1326 : : Note: The folding of non-omp cases is something to move into
1327 : : the middle-end. As for now we have most foldings only on GENERIC
1328 : : in fold-const, we need to perform this before transformation to
1329 : : GIMPLE-form.
1330 : :
1331 : : ??? This is algorithmically weird because walk_tree works in pre-order, so
1332 : : we see outer expressions before inner expressions. This isn't as much of an
1333 : : issue because cp_fold recurses into subexpressions in many cases, but then
1334 : : walk_tree walks back into those subexpressions again. We avoid the
1335 : : resulting complexity problem by caching the result of cp_fold, but it's
1336 : : inelegant. */
1337 : :
1338 : : static tree
1339 : 1745106443 : cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
1340 : : {
1341 : 1745106443 : cp_fold_data *data = (cp_fold_data*)data_;
1342 : 1745106443 : tree stmt = *stmt_p;
1343 : 1745106443 : enum tree_code code = TREE_CODE (stmt);
1344 : :
1345 : 1745106443 : if (cxx_dialect >= cxx20)
1346 : : {
1347 : : /* Unfortunately we must handle code like
1348 : : false ? bar () : 42
1349 : : where we have to check bar too. The cp_fold call below could
1350 : : fold the ?: into a constant before we've checked it. */
1351 : 567036661 : if (code == COND_EXPR)
1352 : : {
1353 : 921271 : auto then_fn = cp_fold_r, else_fn = cp_fold_r;
1354 : : /* See if we can figure out if either of the branches is dead. If it
1355 : : is, we don't need to do everything that cp_fold_r does. */
1356 : 921271 : cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_fold_r, data, nullptr);
1357 : 921271 : if (integer_zerop (TREE_OPERAND (stmt, 0)))
1358 : : then_fn = cp_fold_immediate_r;
1359 : 895950 : else if (integer_nonzerop (TREE_OPERAND (stmt, 0)))
1360 : 17386 : else_fn = cp_fold_immediate_r;
1361 : :
1362 : 921271 : if (TREE_OPERAND (stmt, 1))
1363 : 921271 : cp_walk_tree (&TREE_OPERAND (stmt, 1), then_fn, data,
1364 : : nullptr);
1365 : 921271 : if (TREE_OPERAND (stmt, 2))
1366 : 921264 : cp_walk_tree (&TREE_OPERAND (stmt, 2), else_fn, data,
1367 : : nullptr);
1368 : 921271 : *walk_subtrees = 0;
1369 : : /* Don't return yet, still need the cp_fold below. */
1370 : : }
1371 : : else
1372 : 566115390 : cp_fold_immediate_r (stmt_p, walk_subtrees, data);
1373 : : }
1374 : :
1375 : 1745106443 : *stmt_p = stmt = cp_fold (*stmt_p, data->flags);
1376 : :
1377 : : /* For certain trees, like +foo(), the cp_fold above will remove the +,
1378 : : and the subsequent tree walk would go straight down to the CALL_EXPR's
1379 : : operands, meaning that cp_fold_immediate_r would never see the
1380 : : CALL_EXPR. Ew :(. */
1381 : 1745106443 : if (TREE_CODE (stmt) == CALL_EXPR && code != CALL_EXPR)
1382 : 105706 : cp_fold_immediate_r (stmt_p, walk_subtrees, data);
1383 : :
1384 : 1745106443 : if (data->pset.add (stmt))
1385 : : {
1386 : : /* Don't walk subtrees of stmts we've already walked once, otherwise
1387 : : we can have exponential complexity with e.g. lots of nested
1388 : : SAVE_EXPRs or TARGET_EXPRs. cp_fold uses a cache and will return
1389 : : always the same tree, which the first time cp_fold_r has been
1390 : : called on it had the subtrees walked. */
1391 : 268163350 : *walk_subtrees = 0;
1392 : 268163350 : return NULL_TREE;
1393 : : }
1394 : :
1395 : 1476943093 : code = TREE_CODE (stmt);
1396 : 1476943093 : switch (code)
1397 : : {
1398 : 24643 : tree x;
1399 : 24643 : int i, n;
1400 : 24643 : case OMP_FOR:
1401 : 24643 : case OMP_SIMD:
1402 : 24643 : case OMP_DISTRIBUTE:
1403 : 24643 : case OMP_LOOP:
1404 : 24643 : case OMP_TASKLOOP:
1405 : 24643 : case OMP_TILE:
1406 : 24643 : case OMP_UNROLL:
1407 : 24643 : case OACC_LOOP:
1408 : 24643 : cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
1409 : 24643 : cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
1410 : 24643 : cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
1411 : 24643 : x = OMP_FOR_COND (stmt);
1412 : 24643 : if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison)
1413 : : {
1414 : 0 : cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL);
1415 : 0 : cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL);
1416 : : }
1417 : 17876 : else if (x && TREE_CODE (x) == TREE_VEC)
1418 : : {
1419 : 17876 : n = TREE_VEC_LENGTH (x);
1420 : 41359 : for (i = 0; i < n; i++)
1421 : : {
1422 : 23483 : tree o = TREE_VEC_ELT (x, i);
1423 : 23483 : if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
1424 : 22570 : cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
1425 : : }
1426 : : }
1427 : 24643 : x = OMP_FOR_INCR (stmt);
1428 : 24643 : if (x && TREE_CODE (x) == TREE_VEC)
1429 : : {
1430 : 17876 : n = TREE_VEC_LENGTH (x);
1431 : 41359 : for (i = 0; i < n; i++)
1432 : : {
1433 : 23483 : tree o = TREE_VEC_ELT (x, i);
1434 : 23483 : if (o && TREE_CODE (o) == MODIFY_EXPR)
1435 : 5950 : o = TREE_OPERAND (o, 1);
1436 : 22570 : if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
1437 : 18007 : || TREE_CODE (o) == POINTER_PLUS_EXPR))
1438 : : {
1439 : 5950 : cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL);
1440 : 5950 : cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
1441 : : }
1442 : : }
1443 : : }
1444 : 24643 : cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
1445 : 24643 : *walk_subtrees = 0;
1446 : 24643 : return NULL_TREE;
1447 : :
1448 : 16417887 : case IF_STMT:
1449 : 16417887 : if (IF_STMT_CONSTEVAL_P (stmt))
1450 : : {
1451 : : /* Don't walk THEN_CLAUSE (stmt) for consteval if. IF_COND is always
1452 : : boolean_false_node. */
1453 : 6791 : cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL);
1454 : 6791 : cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL);
1455 : 6791 : *walk_subtrees = 0;
1456 : 6791 : return NULL_TREE;
1457 : : }
1458 : : break;
1459 : :
1460 : : /* cp_genericize_{init,target}_expr are only for genericize time; they're
1461 : : here rather than in cp_genericize to avoid problems with the invisible
1462 : : reference transition. */
1463 : 46942628 : case INIT_EXPR:
1464 : 46942628 : if (data->flags & ff_genericize)
1465 : 46934234 : cp_genericize_init_expr (stmt_p);
1466 : : break;
1467 : :
1468 : 13782516 : case TARGET_EXPR:
1469 : 13782516 : if (data->flags & ff_genericize)
1470 : 13365426 : cp_genericize_target_expr (stmt_p);
1471 : :
1472 : : /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in
1473 : : that case, strip it in favor of this one. */
1474 : 13782516 : if (tree &init = TARGET_EXPR_INITIAL (stmt))
1475 : : {
1476 : 13782516 : cp_walk_tree (&init, cp_fold_r, data, NULL);
1477 : 13782516 : cp_walk_tree (&TARGET_EXPR_CLEANUP (stmt), cp_fold_r, data, NULL);
1478 : 13782516 : *walk_subtrees = 0;
1479 : 13782516 : if (TREE_CODE (init) == TARGET_EXPR)
1480 : : {
1481 : 99966 : tree sub = TARGET_EXPR_INITIAL (init);
1482 : 99966 : maybe_replace_decl (&sub, TARGET_EXPR_SLOT (init),
1483 : 99966 : TARGET_EXPR_SLOT (stmt));
1484 : 99966 : init = sub;
1485 : : }
1486 : : }
1487 : : break;
1488 : :
1489 : : default:
1490 : : break;
1491 : : }
1492 : :
1493 : : return NULL_TREE;
1494 : : }
1495 : :
1496 : : /* Fold ALL the trees! FIXME we should be able to remove this, but
1497 : : apparently that still causes optimization regressions. */
1498 : :
1499 : : void
1500 : 52204432 : cp_fold_function (tree fndecl)
1501 : : {
1502 : : /* By now all manifestly-constant-evaluated expressions will have
1503 : : been constant-evaluated already if possible, so we can safely
1504 : : pass ff_mce_false. */
1505 : 52204432 : cp_fold_data data (ff_genericize | ff_mce_false);
1506 : 52204432 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
1507 : :
1508 : : /* This is merely an optimization: if FNDECL has no i-e expressions,
1509 : : we'll not save c_f_d, and we can safely say that FNDECL will not
1510 : : be promoted to consteval. */
1511 : 52204432 : if (deferred_escalating_exprs
1512 : 52204432 : && !deferred_escalating_exprs->contains (current_function_decl))
1513 : 12374239 : DECL_ESCALATION_CHECKED_P (fndecl) = true;
1514 : 52204432 : }
1515 : :
1516 : : /* We've stashed immediate-escalating functions. Now see if they indeed
1517 : : ought to be promoted to consteval. */
1518 : :
1519 : : void
1520 : 90704 : process_and_check_pending_immediate_escalating_fns ()
1521 : : {
1522 : : /* This will be null for -fno-immediate-escalation. */
1523 : 90704 : if (!deferred_escalating_exprs)
1524 : : return;
1525 : :
1526 : 5045996 : for (auto e : *deferred_escalating_exprs)
1527 : 2520374 : if (TREE_CODE (e) == FUNCTION_DECL && !DECL_ESCALATION_CHECKED_P (e))
1528 : 1754371 : cp_fold_immediate (&DECL_SAVED_TREE (e), mce_false, e);
1529 : :
1530 : : /* We've escalated every function that could have been promoted to
1531 : : consteval. Check that we are not taking the address of a consteval
1532 : : function. */
1533 : 5046073 : for (auto e : *deferred_escalating_exprs)
1534 : : {
1535 : 2520374 : if (TREE_CODE (e) == FUNCTION_DECL)
1536 : 2520297 : continue;
1537 : 77 : tree decl = (TREE_CODE (e) == PTRMEM_CST
1538 : 154 : ? PTRMEM_CST_MEMBER (e)
1539 : 77 : : TREE_OPERAND (e, 0));
1540 : 154 : if (DECL_IMMEDIATE_FUNCTION_P (decl))
1541 : 12 : taking_address_of_imm_fn_error (e, decl);
1542 : : }
1543 : :
1544 : 5325 : deferred_escalating_exprs = nullptr;
1545 : : }
1546 : :
1547 : : /* Turn SPACESHIP_EXPR EXPR into GENERIC. */
1548 : :
1549 : 55659 : static tree genericize_spaceship (tree expr)
1550 : : {
1551 : 55659 : iloc_sentinel s (cp_expr_location (expr));
1552 : 55659 : tree type = TREE_TYPE (expr);
1553 : 55659 : tree op0 = TREE_OPERAND (expr, 0);
1554 : 55659 : tree op1 = TREE_OPERAND (expr, 1);
1555 : 55659 : return genericize_spaceship (input_location, type, op0, op1);
1556 : 55659 : }
1557 : :
1558 : : /* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
1559 : : to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
1560 : : the middle-end (c++/88256). If EXPR is a DECL, use add_stmt and return
1561 : : NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR. */
1562 : :
1563 : : tree
1564 : 107398538 : predeclare_vla (tree expr)
1565 : : {
1566 : 107398538 : tree type = TREE_TYPE (expr);
1567 : 107398538 : if (type == error_mark_node)
1568 : : return expr;
1569 : 107398473 : if (is_typedef_decl (expr))
1570 : 107398473 : type = DECL_ORIGINAL_TYPE (expr);
1571 : :
1572 : : /* We need to strip pointers for gimplify_type_sizes. */
1573 : 107398473 : tree vla = type;
1574 : 160199694 : while (POINTER_TYPE_P (vla))
1575 : : {
1576 : 54632676 : if (TYPE_NAME (vla))
1577 : : return expr;
1578 : 52801221 : vla = TREE_TYPE (vla);
1579 : : }
1580 : 51320848 : if (vla == type || TYPE_NAME (vla)
1581 : 106043067 : || !variably_modified_type_p (vla, NULL_TREE))
1582 : 105566879 : return expr;
1583 : :
1584 : 139 : tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
1585 : 139 : DECL_ARTIFICIAL (decl) = 1;
1586 : 139 : TYPE_NAME (vla) = decl;
1587 : 139 : tree dexp = build_stmt (input_location, DECL_EXPR, decl);
1588 : 139 : if (DECL_P (expr))
1589 : : {
1590 : 5 : add_stmt (dexp);
1591 : 5 : return NULL_TREE;
1592 : : }
1593 : : else
1594 : : {
1595 : 134 : expr = build2 (COMPOUND_EXPR, type, dexp, expr);
1596 : 134 : return expr;
1597 : : }
1598 : : }
1599 : :
1600 : : /* Perform any pre-gimplification lowering of C++ front end trees to
1601 : : GENERIC. */
1602 : :
1603 : : static tree
1604 : 1418831779 : cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
1605 : : {
1606 : 1435251079 : tree stmt = *stmt_p;
1607 : 1435251079 : struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
1608 : 1435251079 : hash_set<tree> *p_set = wtd->p_set;
1609 : :
1610 : : /* If in an OpenMP context, note var uses. */
1611 : 1435251079 : if (UNLIKELY (wtd->omp_ctx != NULL)
1612 : 559105 : && (VAR_P (stmt)
1613 : : || TREE_CODE (stmt) == PARM_DECL
1614 : : || TREE_CODE (stmt) == RESULT_DECL)
1615 : 1435354612 : && omp_var_to_track (stmt))
1616 : 11538 : omp_cxx_notice_variable (wtd->omp_ctx, stmt);
1617 : :
1618 : : /* Don't dereference parms in a thunk, pass the references through. */
1619 : 60117310 : if ((TREE_CODE (stmt) == CALL_EXPR && call_from_lambda_thunk_p (stmt))
1620 : 1495339202 : || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
1621 : : {
1622 : 29336 : *walk_subtrees = 0;
1623 : 29336 : return NULL;
1624 : : }
1625 : :
1626 : : /* Dereference invisible reference parms. */
1627 : 1435221743 : if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
1628 : : {
1629 : 1105624 : *stmt_p = convert_from_reference (stmt);
1630 : 1105624 : p_set->add (*stmt_p);
1631 : 1105624 : *walk_subtrees = 0;
1632 : 1105624 : return NULL;
1633 : : }
1634 : :
1635 : : /* Map block scope extern declarations to visible declarations with the
1636 : : same name and type in outer scopes if any. */
1637 : 1434116119 : if (VAR_OR_FUNCTION_DECL_P (stmt) && DECL_LOCAL_DECL_P (stmt))
1638 : 19763 : if (tree alias = DECL_LOCAL_DECL_ALIAS (stmt))
1639 : : {
1640 : 19763 : if (alias != error_mark_node)
1641 : : {
1642 : 19760 : *stmt_p = alias;
1643 : 19760 : TREE_USED (alias) |= TREE_USED (stmt);
1644 : : }
1645 : 19763 : *walk_subtrees = 0;
1646 : 19763 : return NULL;
1647 : : }
1648 : :
1649 : 1434096356 : if (TREE_CODE (stmt) == INTEGER_CST
1650 : 174168001 : && TYPE_REF_P (TREE_TYPE (stmt))
1651 : 146 : && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1652 : 1434096357 : && !wtd->no_sanitize_p)
1653 : : {
1654 : 1 : ubsan_maybe_instrument_reference (stmt_p);
1655 : 1 : if (*stmt_p != stmt)
1656 : : {
1657 : 1 : *walk_subtrees = 0;
1658 : 1 : return NULL_TREE;
1659 : : }
1660 : : }
1661 : :
1662 : : /* Other than invisiref parms, don't walk the same tree twice. */
1663 : 1434096355 : if (p_set->contains (stmt))
1664 : : {
1665 : 264144392 : *walk_subtrees = 0;
1666 : 264144392 : return NULL_TREE;
1667 : : }
1668 : :
1669 : 1169951963 : switch (TREE_CODE (stmt))
1670 : : {
1671 : 93149238 : case ADDR_EXPR:
1672 : 93149238 : if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
1673 : : {
1674 : : /* If in an OpenMP context, note var uses. */
1675 : 505771 : if (UNLIKELY (wtd->omp_ctx != NULL)
1676 : 505771 : && omp_var_to_track (TREE_OPERAND (stmt, 0)))
1677 : 412 : omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
1678 : 505771 : *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
1679 : 505771 : *walk_subtrees = 0;
1680 : : }
1681 : : break;
1682 : :
1683 : 33603383 : case RETURN_EXPR:
1684 : 33603383 : if (TREE_OPERAND (stmt, 0))
1685 : : {
1686 : 33003173 : if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
1687 : : /* Don't dereference an invisiref RESULT_DECL inside a
1688 : : RETURN_EXPR. */
1689 : 1428 : *walk_subtrees = 0;
1690 : 33003173 : if (RETURN_EXPR_LOCAL_ADDR_P (stmt))
1691 : : {
1692 : : /* Don't return the address of a local variable. */
1693 : 165 : tree *p = &TREE_OPERAND (stmt, 0);
1694 : 330 : while (TREE_CODE (*p) == COMPOUND_EXPR)
1695 : 0 : p = &TREE_OPERAND (*p, 0);
1696 : 165 : if (TREE_CODE (*p) == INIT_EXPR)
1697 : : {
1698 : 165 : tree op = TREE_OPERAND (*p, 1);
1699 : 165 : tree new_op = build2 (COMPOUND_EXPR, TREE_TYPE (op), op,
1700 : 165 : build_zero_cst (TREE_TYPE (op)));
1701 : 165 : TREE_OPERAND (*p, 1) = new_op;
1702 : : }
1703 : : }
1704 : : }
1705 : : break;
1706 : :
1707 : 78054 : case OMP_CLAUSE:
1708 : 78054 : switch (OMP_CLAUSE_CODE (stmt))
1709 : : {
1710 : 2581 : case OMP_CLAUSE_LASTPRIVATE:
1711 : : /* Don't dereference an invisiref in OpenMP clauses. */
1712 : 2581 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1713 : : {
1714 : 53 : *walk_subtrees = 0;
1715 : 53 : if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
1716 : 48 : cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
1717 : : cp_genericize_r, data, NULL);
1718 : : }
1719 : : break;
1720 : 2027 : case OMP_CLAUSE_PRIVATE:
1721 : : /* Don't dereference an invisiref in OpenMP clauses. */
1722 : 2027 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1723 : 8 : *walk_subtrees = 0;
1724 : 2019 : else if (wtd->omp_ctx != NULL)
1725 : : {
1726 : : /* Private clause doesn't cause any references to the
1727 : : var in outer contexts, avoid calling
1728 : : omp_cxx_notice_variable for it. */
1729 : 583 : struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
1730 : 583 : wtd->omp_ctx = NULL;
1731 : 583 : cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
1732 : : data, NULL);
1733 : 583 : wtd->omp_ctx = old;
1734 : 583 : *walk_subtrees = 0;
1735 : : }
1736 : : break;
1737 : 5967 : case OMP_CLAUSE_SHARED:
1738 : 5967 : case OMP_CLAUSE_FIRSTPRIVATE:
1739 : 5967 : case OMP_CLAUSE_COPYIN:
1740 : 5967 : case OMP_CLAUSE_COPYPRIVATE:
1741 : 5967 : case OMP_CLAUSE_INCLUSIVE:
1742 : 5967 : case OMP_CLAUSE_EXCLUSIVE:
1743 : : /* Don't dereference an invisiref in OpenMP clauses. */
1744 : 5967 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1745 : 87 : *walk_subtrees = 0;
1746 : : break;
1747 : 7796 : case OMP_CLAUSE_REDUCTION:
1748 : 7796 : case OMP_CLAUSE_IN_REDUCTION:
1749 : 7796 : case OMP_CLAUSE_TASK_REDUCTION:
1750 : : /* Don't dereference an invisiref in reduction clause's
1751 : : OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
1752 : : still needs to be genericized. */
1753 : 7796 : if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1754 : : {
1755 : 38 : *walk_subtrees = 0;
1756 : 38 : if (OMP_CLAUSE_REDUCTION_INIT (stmt))
1757 : 38 : cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
1758 : : cp_genericize_r, data, NULL);
1759 : 38 : if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
1760 : 38 : cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
1761 : : cp_genericize_r, data, NULL);
1762 : : }
1763 : : break;
1764 : : default:
1765 : : break;
1766 : : }
1767 : : break;
1768 : :
1769 : : /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1770 : : to lower this construct before scanning it, so we need to lower these
1771 : : before doing anything else. */
1772 : 5037284 : case CLEANUP_STMT:
1773 : 5037284 : *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1774 : 5037284 : CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1775 : : : TRY_FINALLY_EXPR,
1776 : : void_type_node,
1777 : 5037284 : CLEANUP_BODY (stmt),
1778 : 5037284 : CLEANUP_EXPR (stmt));
1779 : 5037284 : break;
1780 : :
1781 : 16418554 : case IF_STMT:
1782 : 16418554 : genericize_if_stmt (stmt_p);
1783 : : /* *stmt_p has changed, tail recurse to handle it again. */
1784 : 16418554 : return cp_genericize_r (stmt_p, walk_subtrees, data);
1785 : :
1786 : : /* COND_EXPR might have incompatible types in branches if one or both
1787 : : arms are bitfields. Fix it up now. */
1788 : 15999809 : case COND_EXPR:
1789 : 15999809 : {
1790 : 15999809 : tree type_left
1791 : 15999809 : = (TREE_OPERAND (stmt, 1)
1792 : 15999809 : ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1793 : 15999809 : : NULL_TREE);
1794 : 15999809 : tree type_right
1795 : 15999809 : = (TREE_OPERAND (stmt, 2)
1796 : 15999809 : ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1797 : 15999809 : : NULL_TREE);
1798 : 15999809 : if (type_left
1799 : 15999842 : && !useless_type_conversion_p (TREE_TYPE (stmt),
1800 : 33 : TREE_TYPE (TREE_OPERAND (stmt, 1))))
1801 : : {
1802 : 30 : TREE_OPERAND (stmt, 1)
1803 : 30 : = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1804 : 30 : gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1805 : : type_left));
1806 : : }
1807 : 15999809 : if (type_right
1808 : 15999826 : && !useless_type_conversion_p (TREE_TYPE (stmt),
1809 : 17 : TREE_TYPE (TREE_OPERAND (stmt, 2))))
1810 : : {
1811 : 17 : TREE_OPERAND (stmt, 2)
1812 : 17 : = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1813 : 17 : gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1814 : : type_right));
1815 : : }
1816 : : }
1817 : : break;
1818 : :
1819 : 20684414 : case BIND_EXPR:
1820 : 20684414 : if (UNLIKELY (wtd->omp_ctx != NULL))
1821 : : {
1822 : 25702 : tree decl;
1823 : 31484 : for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1824 : 5782 : if (VAR_P (decl)
1825 : 5734 : && !DECL_EXTERNAL (decl)
1826 : 11516 : && omp_var_to_track (decl))
1827 : : {
1828 : 453 : splay_tree_node n
1829 : 453 : = splay_tree_lookup (wtd->omp_ctx->variables,
1830 : : (splay_tree_key) decl);
1831 : 453 : if (n == NULL)
1832 : 453 : splay_tree_insert (wtd->omp_ctx->variables,
1833 : : (splay_tree_key) decl,
1834 : 453 : TREE_STATIC (decl)
1835 : : ? OMP_CLAUSE_DEFAULT_SHARED
1836 : : : OMP_CLAUSE_DEFAULT_PRIVATE);
1837 : : }
1838 : : }
1839 : 20684414 : if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1840 : : {
1841 : : /* The point here is to not sanitize static initializers. */
1842 : 2894 : bool no_sanitize_p = wtd->no_sanitize_p;
1843 : 2894 : wtd->no_sanitize_p = true;
1844 : 2894 : for (tree decl = BIND_EXPR_VARS (stmt);
1845 : 5658 : decl;
1846 : 2764 : decl = DECL_CHAIN (decl))
1847 : 2764 : if (VAR_P (decl)
1848 : 2764 : && TREE_STATIC (decl)
1849 : 2764 : && DECL_INITIAL (decl))
1850 : 8 : cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
1851 : 2894 : wtd->no_sanitize_p = no_sanitize_p;
1852 : : }
1853 : 20684414 : wtd->bind_expr_stack.safe_push (stmt);
1854 : 20684414 : cp_walk_tree (&BIND_EXPR_BODY (stmt),
1855 : : cp_genericize_r, data, NULL);
1856 : 20684414 : wtd->bind_expr_stack.pop ();
1857 : 20684414 : break;
1858 : :
1859 : 746 : case ASSERTION_STMT:
1860 : 746 : case PRECONDITION_STMT:
1861 : 746 : case POSTCONDITION_STMT:
1862 : 746 : {
1863 : 746 : if (tree check = build_contract_check (stmt))
1864 : : {
1865 : 746 : *stmt_p = check;
1866 : 746 : return cp_genericize_r (stmt_p, walk_subtrees, data);
1867 : : }
1868 : :
1869 : : /* If we didn't build a check, replace it with void_node so we don't
1870 : : leak contracts into GENERIC. */
1871 : 0 : *stmt_p = void_node;
1872 : 0 : *walk_subtrees = 0;
1873 : : }
1874 : 0 : break;
1875 : :
1876 : 28753 : case USING_STMT:
1877 : 28753 : {
1878 : 28753 : tree block = NULL_TREE;
1879 : :
1880 : : /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1881 : : BLOCK, and append an IMPORTED_DECL to its
1882 : : BLOCK_VARS chained list. */
1883 : 28753 : if (wtd->bind_expr_stack.exists ())
1884 : : {
1885 : 28753 : int i;
1886 : 28753 : for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1887 : 28753 : if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1888 : : break;
1889 : : }
1890 : 28753 : if (block)
1891 : : {
1892 : 28753 : tree decl = TREE_OPERAND (stmt, 0);
1893 : 28753 : gcc_assert (decl);
1894 : :
1895 : 28753 : if (undeduced_auto_decl (decl))
1896 : : /* Omit from the GENERIC, the back-end can't handle it. */;
1897 : : else
1898 : : {
1899 : 28750 : tree using_directive = make_node (IMPORTED_DECL);
1900 : 28750 : TREE_TYPE (using_directive) = void_type_node;
1901 : 28750 : DECL_CONTEXT (using_directive) = current_function_decl;
1902 : 57500 : DECL_SOURCE_LOCATION (using_directive)
1903 : 28750 : = cp_expr_loc_or_input_loc (stmt);
1904 : :
1905 : 28750 : IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
1906 : 28750 : DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1907 : 28750 : BLOCK_VARS (block) = using_directive;
1908 : : }
1909 : : }
1910 : : /* The USING_STMT won't appear in GENERIC. */
1911 : 28753 : *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1912 : 28753 : *walk_subtrees = 0;
1913 : : }
1914 : 28753 : break;
1915 : :
1916 : 22142943 : case DECL_EXPR:
1917 : 22142943 : if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1918 : : {
1919 : : /* Using decls inside DECL_EXPRs are just dropped on the floor. */
1920 : 11703 : *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1921 : 11703 : *walk_subtrees = 0;
1922 : : }
1923 : : else
1924 : : {
1925 : 22131240 : tree d = DECL_EXPR_DECL (stmt);
1926 : 22131240 : if (VAR_P (d))
1927 : 44261363 : gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
1928 : : }
1929 : : break;
1930 : :
1931 : 11262 : case OMP_PARALLEL:
1932 : 11262 : case OMP_TASK:
1933 : 11262 : case OMP_TASKLOOP:
1934 : 11262 : {
1935 : 11262 : struct cp_genericize_omp_taskreg omp_ctx;
1936 : 11262 : tree c, decl;
1937 : 11262 : splay_tree_node n;
1938 : :
1939 : 11262 : *walk_subtrees = 0;
1940 : 11262 : cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1941 : 11262 : omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1942 : 11262 : omp_ctx.default_shared = omp_ctx.is_parallel;
1943 : 11262 : omp_ctx.outer = wtd->omp_ctx;
1944 : 11262 : omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1945 : 11262 : wtd->omp_ctx = &omp_ctx;
1946 : 27066 : for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1947 : 15804 : switch (OMP_CLAUSE_CODE (c))
1948 : : {
1949 : 4733 : case OMP_CLAUSE_SHARED:
1950 : 4733 : case OMP_CLAUSE_PRIVATE:
1951 : 4733 : case OMP_CLAUSE_FIRSTPRIVATE:
1952 : 4733 : case OMP_CLAUSE_LASTPRIVATE:
1953 : 4733 : decl = OMP_CLAUSE_DECL (c);
1954 : 4733 : if (decl == error_mark_node || !omp_var_to_track (decl))
1955 : : break;
1956 : 519 : n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1957 : 519 : if (n != NULL)
1958 : : break;
1959 : 1020 : splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1960 : 510 : OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1961 : : ? OMP_CLAUSE_DEFAULT_SHARED
1962 : : : OMP_CLAUSE_DEFAULT_PRIVATE);
1963 : 510 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
1964 : 91 : omp_cxx_notice_variable (omp_ctx.outer, decl);
1965 : : break;
1966 : 1644 : case OMP_CLAUSE_DEFAULT:
1967 : 1644 : if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1968 : 728 : omp_ctx.default_shared = true;
1969 : : default:
1970 : : break;
1971 : : }
1972 : 11262 : if (TREE_CODE (stmt) == OMP_TASKLOOP)
1973 : 990 : c_genericize_control_stmt (stmt_p, walk_subtrees, data,
1974 : : cp_genericize_r, cp_walk_subtrees);
1975 : : else
1976 : 10272 : cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1977 : 11262 : wtd->omp_ctx = omp_ctx.outer;
1978 : 11262 : splay_tree_delete (omp_ctx.variables);
1979 : : }
1980 : 11262 : break;
1981 : :
1982 : 6210 : case OMP_TARGET:
1983 : 6210 : cfun->has_omp_target = true;
1984 : 6210 : break;
1985 : :
1986 : 126017 : case TRY_BLOCK:
1987 : 126017 : {
1988 : 126017 : *walk_subtrees = 0;
1989 : 126017 : tree try_block = wtd->try_block;
1990 : 126017 : wtd->try_block = stmt;
1991 : 126017 : cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
1992 : 126017 : wtd->try_block = try_block;
1993 : 126017 : cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
1994 : : }
1995 : 126017 : break;
1996 : :
1997 : 17447889 : case MUST_NOT_THROW_EXPR:
1998 : : /* MUST_NOT_THROW_COND might be something else with TM. */
1999 : 17447889 : if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
2000 : : {
2001 : 17447871 : *walk_subtrees = 0;
2002 : 17447871 : tree try_block = wtd->try_block;
2003 : 17447871 : wtd->try_block = stmt;
2004 : 17447871 : cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
2005 : 17447871 : wtd->try_block = try_block;
2006 : : }
2007 : : break;
2008 : :
2009 : 120522 : case THROW_EXPR:
2010 : 120522 : {
2011 : 120522 : location_t loc = location_of (stmt);
2012 : 120522 : if (warning_suppressed_p (stmt /* What warning? */))
2013 : : /* Never mind. */;
2014 : 28561 : else if (wtd->try_block)
2015 : : {
2016 : 791 : if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
2017 : : {
2018 : 18 : auto_diagnostic_group d;
2019 : 18 : if (warning_at (loc, OPT_Wterminate,
2020 : : "%<throw%> will always call %<terminate%>")
2021 : 10 : && cxx_dialect >= cxx11
2022 : 36 : && DECL_DESTRUCTOR_P (current_function_decl))
2023 : 5 : inform (loc, "in C++11 destructors default to %<noexcept%>");
2024 : 18 : }
2025 : : }
2026 : : else
2027 : : {
2028 : 102 : if (warn_cxx11_compat && cxx_dialect < cxx11
2029 : 204 : && DECL_DESTRUCTOR_P (current_function_decl)
2030 : 1 : && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
2031 : : == NULL_TREE)
2032 : 27771 : && (get_defaulted_eh_spec (current_function_decl)
2033 : 1 : == empty_except_spec))
2034 : 1 : warning_at (loc, OPT_Wc__11_compat,
2035 : : "in C++11 this %<throw%> will call %<terminate%> "
2036 : : "because destructors default to %<noexcept%>");
2037 : : }
2038 : : }
2039 : : break;
2040 : :
2041 : 34491521 : case CONVERT_EXPR:
2042 : 34491521 : gcc_checking_assert (!AGGREGATE_TYPE_P (TREE_TYPE (stmt)));
2043 : 34491521 : gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
2044 : : break;
2045 : :
2046 : 55659 : case SPACESHIP_EXPR:
2047 : 55659 : *stmt_p = genericize_spaceship (*stmt_p);
2048 : 55659 : break;
2049 : :
2050 : 32054 : case PTRMEM_CST:
2051 : : /* By the time we get here we're handing off to the back end, so we don't
2052 : : need or want to preserve PTRMEM_CST anymore. */
2053 : 32054 : *stmt_p = cplus_expand_constant (stmt);
2054 : 32054 : *walk_subtrees = 0;
2055 : 32054 : break;
2056 : :
2057 : 72626 : case MEM_REF:
2058 : : /* For MEM_REF, make sure not to sanitize the second operand even
2059 : : if it has reference type. It is just an offset with a type
2060 : : holding other information. There is no other processing we
2061 : : need to do for INTEGER_CSTs, so just ignore the second argument
2062 : : unconditionally. */
2063 : 72626 : cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
2064 : 72626 : *walk_subtrees = 0;
2065 : 72626 : break;
2066 : :
2067 : 86872330 : case NOP_EXPR:
2068 : 86872330 : *stmt_p = predeclare_vla (*stmt_p);
2069 : :
2070 : : /* Warn of new allocations that are not big enough for the target
2071 : : type. */
2072 : 86872330 : if (warn_alloc_size
2073 : 928865 : && TREE_CODE (TREE_OPERAND (stmt, 0)) == CALL_EXPR
2074 : 86931329 : && POINTER_TYPE_P (TREE_TYPE (stmt)))
2075 : : {
2076 : 20275 : if (tree fndecl = get_callee_fndecl (TREE_OPERAND (stmt, 0)))
2077 : 20261 : if (DECL_IS_MALLOC (fndecl))
2078 : : {
2079 : 1208 : tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
2080 : 1208 : tree alloc_size = lookup_attribute ("alloc_size", attrs);
2081 : 1208 : if (alloc_size)
2082 : 1206 : warn_for_alloc_size (EXPR_LOCATION (stmt),
2083 : 1206 : TREE_TYPE (TREE_TYPE (stmt)),
2084 : 1206 : TREE_OPERAND (stmt, 0), alloc_size);
2085 : : }
2086 : : }
2087 : :
2088 : 86872330 : if (!wtd->no_sanitize_p
2089 : 86872327 : && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
2090 : 86884764 : && TYPE_REF_P (TREE_TYPE (stmt)))
2091 : 1967 : ubsan_maybe_instrument_reference (stmt_p);
2092 : : break;
2093 : :
2094 : 60087493 : case CALL_EXPR:
2095 : 60087493 : if (!wtd->no_sanitize_p
2096 : 60087493 : && sanitize_flags_p ((SANITIZE_NULL
2097 : : | SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
2098 : : {
2099 : 13550 : tree fn = CALL_EXPR_FN (stmt);
2100 : 13550 : if (fn != NULL_TREE
2101 : 8556 : && !error_operand_p (fn)
2102 : 8556 : && INDIRECT_TYPE_P (TREE_TYPE (fn))
2103 : 22106 : && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
2104 : : {
2105 : 4711 : bool is_ctor
2106 : 4711 : = TREE_CODE (fn) == ADDR_EXPR
2107 : 4596 : && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
2108 : 13903 : && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
2109 : 4711 : if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
2110 : 4096 : ubsan_maybe_instrument_member_call (stmt, is_ctor);
2111 : 4711 : if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
2112 : 3963 : cp_ubsan_maybe_instrument_member_call (stmt);
2113 : : }
2114 : 8839 : else if (fn == NULL_TREE
2115 : 4994 : && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
2116 : 4068 : && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
2117 : 8845 : && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
2118 : 6 : *walk_subtrees = 0;
2119 : : }
2120 : : /* Fall through. */
2121 : 63928682 : case AGGR_INIT_EXPR:
2122 : : /* For calls to a multi-versioned function, overload resolution
2123 : : returns the function with the highest target priority, that is,
2124 : : the version that will checked for dispatching first. If this
2125 : : version is inlinable, a direct call to this version can be made
2126 : : otherwise the call should go through the dispatcher. */
2127 : 63928682 : {
2128 : 63928682 : tree fn = cp_get_callee_fndecl_nofold (stmt);
2129 : 62838427 : if (fn && DECL_FUNCTION_VERSIONED (fn)
2130 : 63928799 : && (current_function_decl == NULL
2131 : 117 : || !targetm.target_option.can_inline_p (current_function_decl,
2132 : : fn)))
2133 : 105 : if (tree dis = get_function_version_dispatcher (fn))
2134 : : {
2135 : 105 : mark_versions_used (dis);
2136 : 105 : dis = build_address (dis);
2137 : 105 : if (TREE_CODE (stmt) == CALL_EXPR)
2138 : 102 : CALL_EXPR_FN (stmt) = dis;
2139 : : else
2140 : 3 : AGGR_INIT_EXPR_FN (stmt) = dis;
2141 : : }
2142 : : }
2143 : : break;
2144 : :
2145 : 12328966 : case TARGET_EXPR:
2146 : 12328966 : if (TARGET_EXPR_INITIAL (stmt)
2147 : 12328966 : && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
2148 : 14128314 : && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
2149 : 166 : TARGET_EXPR_NO_ELIDE (stmt) = 1;
2150 : : break;
2151 : :
2152 : 80 : case TEMPLATE_ID_EXPR:
2153 : 80 : gcc_assert (concept_check_p (stmt));
2154 : : /* Emit the value of the concept check. */
2155 : 80 : *stmt_p = evaluate_concept_check (stmt);
2156 : 80 : walk_subtrees = 0;
2157 : 80 : break;
2158 : :
2159 : 4177 : case OMP_DISTRIBUTE:
2160 : : /* Need to explicitly instantiate copy ctors on class iterators of
2161 : : composite distribute parallel for. */
2162 : 4177 : if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
2163 : : {
2164 : 3702 : tree *data[4] = { NULL, NULL, NULL, NULL };
2165 : 3702 : tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
2166 : : find_combined_omp_for, data, NULL);
2167 : 3702 : if (inner != NULL_TREE
2168 : 3668 : && TREE_CODE (inner) == OMP_FOR)
2169 : : {
2170 : 4470 : for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
2171 : 2815 : if (TREE_VEC_ELT (OMP_FOR_INIT (inner), i)
2172 : 2799 : && OMP_FOR_ORIG_DECLS (inner)
2173 : 2799 : && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
2174 : : i)) == TREE_LIST
2175 : 2839 : && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
2176 : : i)))
2177 : : {
2178 : 12 : tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
2179 : : /* Class iterators aren't allowed on OMP_SIMD, so the only
2180 : : case we need to solve is distribute parallel for. */
2181 : 12 : gcc_assert (TREE_CODE (inner) == OMP_FOR
2182 : : && data[1]);
2183 : 12 : tree orig_decl = TREE_PURPOSE (orig);
2184 : 12 : tree c, cl = NULL_TREE;
2185 : 12 : for (c = OMP_FOR_CLAUSES (inner);
2186 : 16 : c; c = OMP_CLAUSE_CHAIN (c))
2187 : 12 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
2188 : 5 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2189 : 13 : && OMP_CLAUSE_DECL (c) == orig_decl)
2190 : : {
2191 : : cl = c;
2192 : : break;
2193 : : }
2194 : 12 : if (cl == NULL_TREE)
2195 : : {
2196 : 4 : for (c = OMP_PARALLEL_CLAUSES (*data[1]);
2197 : 4 : c; c = OMP_CLAUSE_CHAIN (c))
2198 : 1 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
2199 : 1 : && OMP_CLAUSE_DECL (c) == orig_decl)
2200 : : {
2201 : : cl = c;
2202 : : break;
2203 : : }
2204 : : }
2205 : 4 : if (cl)
2206 : : {
2207 : 9 : orig_decl = require_complete_type (orig_decl);
2208 : 9 : tree inner_type = TREE_TYPE (orig_decl);
2209 : 9 : if (orig_decl == error_mark_node)
2210 : 0 : continue;
2211 : 9 : if (TYPE_REF_P (TREE_TYPE (orig_decl)))
2212 : 0 : inner_type = TREE_TYPE (inner_type);
2213 : :
2214 : 9 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
2215 : 0 : inner_type = TREE_TYPE (inner_type);
2216 : 9 : get_copy_ctor (inner_type, tf_warning_or_error);
2217 : : }
2218 : : }
2219 : : }
2220 : : }
2221 : : /* FALLTHRU */
2222 : :
2223 : 51062323 : case FOR_STMT:
2224 : 51062323 : case WHILE_STMT:
2225 : 51062323 : case DO_STMT:
2226 : 51062323 : case SWITCH_STMT:
2227 : 51062323 : case CONTINUE_STMT:
2228 : 51062323 : case BREAK_STMT:
2229 : 51062323 : case OMP_FOR:
2230 : 51062323 : case OMP_SIMD:
2231 : 51062323 : case OMP_LOOP:
2232 : 51062323 : case OMP_TILE:
2233 : 51062323 : case OMP_UNROLL:
2234 : 51062323 : case OACC_LOOP:
2235 : 51062323 : case STATEMENT_LIST:
2236 : : /* These cases are handled by shared code. */
2237 : 51062323 : c_genericize_control_stmt (stmt_p, walk_subtrees, data,
2238 : : cp_genericize_r, cp_walk_subtrees);
2239 : 51062323 : break;
2240 : :
2241 : 404 : case BIT_CAST_EXPR:
2242 : 404 : *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
2243 : 404 : TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
2244 : 404 : break;
2245 : :
2246 : 696252240 : default:
2247 : 696252240 : if (IS_TYPE_OR_DECL_P (stmt))
2248 : 200633720 : *walk_subtrees = 0;
2249 : : break;
2250 : : }
2251 : :
2252 : 1153532663 : p_set->add (*stmt_p);
2253 : :
2254 : 1153532663 : return NULL;
2255 : : }
2256 : :
2257 : : /* Lower C++ front end trees to GENERIC in T_P. */
2258 : :
2259 : : static void
2260 : 39174475 : cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
2261 : : {
2262 : 39174475 : struct cp_genericize_data wtd;
2263 : :
2264 : 39174475 : wtd.p_set = new hash_set<tree>;
2265 : 39174475 : wtd.bind_expr_stack.create (0);
2266 : 39174475 : wtd.omp_ctx = NULL;
2267 : 39174475 : wtd.try_block = NULL_TREE;
2268 : 39174475 : wtd.no_sanitize_p = false;
2269 : 39174475 : wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
2270 : 39174475 : cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
2271 : 78348950 : delete wtd.p_set;
2272 : 39174475 : if (sanitize_flags_p (SANITIZE_VPTR))
2273 : 4828 : cp_ubsan_instrument_member_accesses (t_p);
2274 : 39174475 : }
2275 : :
2276 : : /* If a function that should end with a return in non-void
2277 : : function doesn't obviously end with return, add ubsan
2278 : : instrumentation code to verify it at runtime. If -fsanitize=return
2279 : : is not enabled, instrument __builtin_unreachable. */
2280 : :
2281 : : static void
2282 : 39174475 : cp_maybe_instrument_return (tree fndecl)
2283 : : {
2284 : 39174475 : if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
2285 : 55637194 : || DECL_CONSTRUCTOR_P (fndecl)
2286 : 27818597 : || DECL_DESTRUCTOR_P (fndecl)
2287 : 66993072 : || !targetm.warn_func_return (fndecl))
2288 : 11355890 : return;
2289 : :
2290 : 27818585 : if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
2291 : : /* Don't add __builtin_unreachable () if not optimizing, it will not
2292 : : improve any optimizations in that case, just break UB code.
2293 : : Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
2294 : : UBSan covers this with ubsan_instrument_return above where sufficient
2295 : : information is provided, while the __builtin_unreachable () below
2296 : : if return sanitization is disabled will just result in hard to
2297 : : understand runtime error without location. */
2298 : 27818585 : && ((!optimize && !flag_unreachable_traps)
2299 : 27815373 : || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
2300 : 30 : return;
2301 : :
2302 : 27818555 : tree t = DECL_SAVED_TREE (fndecl);
2303 : 50400900 : while (t)
2304 : : {
2305 : 50400896 : switch (TREE_CODE (t))
2306 : : {
2307 : 3889928 : case BIND_EXPR:
2308 : 3889928 : t = BIND_EXPR_BODY (t);
2309 : 3889928 : continue;
2310 : 7555544 : case TRY_FINALLY_EXPR:
2311 : 7555544 : case CLEANUP_POINT_EXPR:
2312 : 7555544 : t = TREE_OPERAND (t, 0);
2313 : 7555544 : continue;
2314 : 11139442 : case STATEMENT_LIST:
2315 : 11139442 : {
2316 : 11139442 : tree_stmt_iterator i = tsi_last (t);
2317 : 11143892 : while (!tsi_end_p (i))
2318 : : {
2319 : 11141323 : tree p = tsi_stmt (i);
2320 : 11141323 : if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
2321 : : break;
2322 : 4450 : tsi_prev (&i);
2323 : : }
2324 : 11139442 : if (!tsi_end_p (i))
2325 : : {
2326 : 11136873 : t = tsi_stmt (i);
2327 : 11136873 : continue;
2328 : : }
2329 : : }
2330 : 2569 : break;
2331 : : case RETURN_EXPR:
2332 : : return;
2333 : : default:
2334 : : break;
2335 : 11445472 : }
2336 : : break;
2337 : : }
2338 : 13699964 : if (t == NULL_TREE)
2339 : : return;
2340 : 13699960 : tree *p = &DECL_SAVED_TREE (fndecl);
2341 : 13699960 : if (TREE_CODE (*p) == BIND_EXPR)
2342 : 904529 : p = &BIND_EXPR_BODY (*p);
2343 : :
2344 : 13699960 : location_t loc = DECL_SOURCE_LOCATION (fndecl);
2345 : 13699960 : if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
2346 : 1303 : t = ubsan_instrument_return (loc);
2347 : : else
2348 : 13698657 : t = build_builtin_unreachable (BUILTINS_LOCATION);
2349 : :
2350 : 13699960 : append_to_statement_list (t, p);
2351 : : }
2352 : :
2353 : : void
2354 : 52204282 : cp_genericize (tree fndecl)
2355 : : {
2356 : 52204282 : tree t;
2357 : :
2358 : : /* Fix up the types of parms passed by invisible reference. */
2359 : 137777826 : for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
2360 : 85573544 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
2361 : : {
2362 : : /* If a function's arguments are copied to create a thunk,
2363 : : then DECL_BY_REFERENCE will be set -- but the type of the
2364 : : argument will be a pointer type, so we will never get
2365 : : here. */
2366 : 120839 : gcc_assert (!DECL_BY_REFERENCE (t));
2367 : 120839 : gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
2368 : 120839 : TREE_TYPE (t) = DECL_ARG_TYPE (t);
2369 : 120839 : DECL_BY_REFERENCE (t) = 1;
2370 : 120839 : TREE_ADDRESSABLE (t) = 0;
2371 : 120839 : relayout_decl (t);
2372 : : }
2373 : :
2374 : : /* Do the same for the return value. */
2375 : 52204282 : if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
2376 : : {
2377 : 987240 : t = DECL_RESULT (fndecl);
2378 : 987240 : TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
2379 : 987240 : DECL_BY_REFERENCE (t) = 1;
2380 : 987240 : TREE_ADDRESSABLE (t) = 0;
2381 : 987240 : relayout_decl (t);
2382 : 987240 : if (DECL_NAME (t))
2383 : : {
2384 : : /* Adjust DECL_VALUE_EXPR of the original var. */
2385 : 121709 : tree outer = outer_curly_brace_block (current_function_decl);
2386 : 121709 : tree var;
2387 : :
2388 : 121709 : if (outer)
2389 : 280220 : for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
2390 : 279796 : if (VAR_P (var)
2391 : 270024 : && DECL_NAME (t) == DECL_NAME (var)
2392 : 121285 : && DECL_HAS_VALUE_EXPR_P (var)
2393 : 401081 : && DECL_VALUE_EXPR (var) == t)
2394 : : {
2395 : 121285 : tree val = convert_from_reference (t);
2396 : 121285 : SET_DECL_VALUE_EXPR (var, val);
2397 : 121285 : break;
2398 : : }
2399 : : }
2400 : : }
2401 : :
2402 : : /* If we're a clone, the body is already GIMPLE. */
2403 : 52204282 : if (DECL_CLONED_FUNCTION_P (fndecl))
2404 : 13029807 : return;
2405 : :
2406 : : /* Allow cp_genericize calls to be nested. */
2407 : 39174475 : bc_state_t save_state;
2408 : 39174475 : save_bc_state (&save_state);
2409 : :
2410 : : /* We do want to see every occurrence of the parms, so we can't just use
2411 : : walk_tree's hash functionality. */
2412 : 39174475 : cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
2413 : :
2414 : 39174475 : cp_maybe_instrument_return (fndecl);
2415 : :
2416 : : /* Do everything else. */
2417 : 39174475 : c_genericize (fndecl);
2418 : 39174475 : restore_bc_state (&save_state);
2419 : : }
2420 : :
2421 : : /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
2422 : : NULL if there is in fact nothing to do. ARG2 may be null if FN
2423 : : actually only takes one argument. */
2424 : :
2425 : : static tree
2426 : 3661 : cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
2427 : : {
2428 : 3661 : tree defparm, parm, t;
2429 : 3661 : int i = 0;
2430 : 3661 : int nargs;
2431 : 3661 : tree *argarray;
2432 : :
2433 : 3661 : if (fn == NULL)
2434 : : return NULL;
2435 : :
2436 : 2827 : nargs = list_length (DECL_ARGUMENTS (fn));
2437 : 2827 : argarray = XALLOCAVEC (tree, nargs);
2438 : :
2439 : 2827 : defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
2440 : 2827 : if (arg2)
2441 : 944 : defparm = TREE_CHAIN (defparm);
2442 : :
2443 : 2827 : bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
2444 : 2827 : if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
2445 : : {
2446 : 27 : tree inner_type = TREE_TYPE (arg1);
2447 : 27 : tree start1, end1, p1;
2448 : 27 : tree start2 = NULL, p2 = NULL;
2449 : 27 : tree ret = NULL, lab;
2450 : :
2451 : 27 : start1 = arg1;
2452 : 27 : start2 = arg2;
2453 : 27 : do
2454 : : {
2455 : 27 : inner_type = TREE_TYPE (inner_type);
2456 : 27 : start1 = build4 (ARRAY_REF, inner_type, start1,
2457 : : size_zero_node, NULL, NULL);
2458 : 27 : if (arg2)
2459 : 9 : start2 = build4 (ARRAY_REF, inner_type, start2,
2460 : : size_zero_node, NULL, NULL);
2461 : : }
2462 : 27 : while (TREE_CODE (inner_type) == ARRAY_TYPE);
2463 : 27 : start1 = build_fold_addr_expr_loc (input_location, start1);
2464 : 27 : if (arg2)
2465 : 9 : start2 = build_fold_addr_expr_loc (input_location, start2);
2466 : :
2467 : 27 : end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
2468 : 27 : end1 = fold_build_pointer_plus (start1, end1);
2469 : :
2470 : 27 : p1 = create_tmp_var (TREE_TYPE (start1));
2471 : 27 : t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
2472 : 27 : append_to_statement_list (t, &ret);
2473 : :
2474 : 27 : if (arg2)
2475 : : {
2476 : 9 : p2 = create_tmp_var (TREE_TYPE (start2));
2477 : 9 : t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
2478 : 9 : append_to_statement_list (t, &ret);
2479 : : }
2480 : :
2481 : 27 : lab = create_artificial_label (input_location);
2482 : 27 : t = build1 (LABEL_EXPR, void_type_node, lab);
2483 : 27 : append_to_statement_list (t, &ret);
2484 : :
2485 : 27 : argarray[i++] = p1;
2486 : 27 : if (arg2)
2487 : 9 : argarray[i++] = p2;
2488 : : /* Handle default arguments. */
2489 : 27 : for (parm = defparm; parm && parm != void_list_node;
2490 : 0 : parm = TREE_CHAIN (parm), i++)
2491 : 0 : argarray[i] = convert_default_arg (TREE_VALUE (parm),
2492 : 0 : TREE_PURPOSE (parm), fn,
2493 : : i - is_method, tf_warning_or_error);
2494 : 27 : t = build_call_a (fn, i, argarray);
2495 : 27 : if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
2496 : 0 : t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
2497 : 27 : t = fold_convert (void_type_node, t);
2498 : 27 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
2499 : 27 : append_to_statement_list (t, &ret);
2500 : :
2501 : 27 : t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
2502 : 27 : t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
2503 : 27 : append_to_statement_list (t, &ret);
2504 : :
2505 : 27 : if (arg2)
2506 : : {
2507 : 9 : t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
2508 : 9 : t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
2509 : 9 : append_to_statement_list (t, &ret);
2510 : : }
2511 : :
2512 : 27 : t = build2 (NE_EXPR, boolean_type_node, p1, end1);
2513 : 27 : t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
2514 : 27 : append_to_statement_list (t, &ret);
2515 : :
2516 : 27 : return ret;
2517 : : }
2518 : : else
2519 : : {
2520 : 2800 : argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
2521 : 2800 : if (arg2)
2522 : 935 : argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
2523 : : /* Handle default arguments. */
2524 : 2805 : for (parm = defparm; parm && parm != void_list_node;
2525 : 5 : parm = TREE_CHAIN (parm), i++)
2526 : 10 : argarray[i] = convert_default_arg (TREE_VALUE (parm),
2527 : 5 : TREE_PURPOSE (parm), fn,
2528 : : i - is_method, tf_warning_or_error);
2529 : 2800 : t = build_call_a (fn, i, argarray);
2530 : 2800 : if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
2531 : 1 : t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
2532 : 2800 : t = fold_convert (void_type_node, t);
2533 : 2800 : return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
2534 : : }
2535 : : }
2536 : :
2537 : : /* Return code to initialize DECL with its default constructor, or
2538 : : NULL if there's nothing to do. */
2539 : :
2540 : : tree
2541 : 41340 : cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
2542 : : {
2543 : 41340 : tree info = CP_OMP_CLAUSE_INFO (clause);
2544 : 41340 : tree ret = NULL;
2545 : :
2546 : 41340 : if (info)
2547 : 1389 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
2548 : :
2549 : 41340 : return ret;
2550 : : }
2551 : :
2552 : : /* Return code to initialize DST with a copy constructor from SRC. */
2553 : :
2554 : : tree
2555 : 12046 : cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
2556 : : {
2557 : 12046 : tree info = CP_OMP_CLAUSE_INFO (clause);
2558 : 12046 : tree ret = NULL;
2559 : :
2560 : 12046 : if (info)
2561 : 285 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
2562 : 285 : if (ret == NULL)
2563 : 11828 : ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
2564 : :
2565 : 12046 : return ret;
2566 : : }
2567 : :
2568 : : /* Similarly, except use an assignment operator instead. */
2569 : :
2570 : : tree
2571 : 12665 : cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
2572 : : {
2573 : 12665 : tree info = CP_OMP_CLAUSE_INFO (clause);
2574 : 12665 : tree ret = NULL;
2575 : :
2576 : 12665 : if (info)
2577 : 748 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
2578 : 748 : if (ret == NULL)
2579 : 11939 : ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
2580 : :
2581 : 12665 : return ret;
2582 : : }
2583 : :
2584 : : /* Return code to destroy DECL. */
2585 : :
2586 : : tree
2587 : 60922 : cxx_omp_clause_dtor (tree clause, tree decl)
2588 : : {
2589 : 60922 : tree info = CP_OMP_CLAUSE_INFO (clause);
2590 : 60922 : tree ret = NULL;
2591 : :
2592 : 60922 : if (info)
2593 : 1239 : ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
2594 : :
2595 : 60922 : return ret;
2596 : : }
2597 : :
2598 : : /* True if OpenMP should privatize what this DECL points to rather
2599 : : than the DECL itself. */
2600 : :
2601 : : bool
2602 : 862246 : cxx_omp_privatize_by_reference (const_tree decl)
2603 : : {
2604 : 862246 : return (TYPE_REF_P (TREE_TYPE (decl))
2605 : 862246 : || is_invisiref_parm (decl));
2606 : : }
2607 : :
2608 : : /* Return true if DECL is const qualified var having no mutable member. */
2609 : : bool
2610 : 14546 : cxx_omp_const_qual_no_mutable (tree decl)
2611 : : {
2612 : 14546 : tree type = TREE_TYPE (decl);
2613 : 14546 : if (TYPE_REF_P (type))
2614 : : {
2615 : 847 : if (!is_invisiref_parm (decl))
2616 : : return false;
2617 : 0 : type = TREE_TYPE (type);
2618 : :
2619 : 0 : if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
2620 : : {
2621 : : /* NVR doesn't preserve const qualification of the
2622 : : variable's type. */
2623 : 0 : tree outer = outer_curly_brace_block (current_function_decl);
2624 : 0 : tree var;
2625 : :
2626 : 0 : if (outer)
2627 : 0 : for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
2628 : 0 : if (VAR_P (var)
2629 : 0 : && DECL_NAME (decl) == DECL_NAME (var)
2630 : 0 : && (TYPE_MAIN_VARIANT (type)
2631 : 0 : == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
2632 : : {
2633 : 0 : if (TYPE_READONLY (TREE_TYPE (var)))
2634 : 0 : type = TREE_TYPE (var);
2635 : : break;
2636 : : }
2637 : : }
2638 : : }
2639 : :
2640 : 13699 : if (type == error_mark_node)
2641 : : return false;
2642 : :
2643 : : /* Variables with const-qualified type having no mutable member
2644 : : are predetermined shared. */
2645 : 13684 : if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
2646 : : return true;
2647 : :
2648 : : return false;
2649 : : }
2650 : :
2651 : : /* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
2652 : : of DECL is predetermined. */
2653 : :
2654 : : enum omp_clause_default_kind
2655 : 51985 : cxx_omp_predetermined_sharing_1 (tree decl)
2656 : : {
2657 : : /* Static data members are predetermined shared. */
2658 : 51985 : if (TREE_STATIC (decl))
2659 : : {
2660 : 15068 : tree ctx = CP_DECL_CONTEXT (decl);
2661 : 15068 : if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
2662 : : return OMP_CLAUSE_DEFAULT_SHARED;
2663 : :
2664 : 14962 : if (c_omp_predefined_variable (decl))
2665 : : return OMP_CLAUSE_DEFAULT_SHARED;
2666 : : }
2667 : :
2668 : : /* this may not be specified in data-sharing clauses, still we need
2669 : : to predetermined it firstprivate. */
2670 : 51834 : if (decl == current_class_ptr)
2671 : 110 : return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
2672 : :
2673 : : return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
2674 : : }
2675 : :
2676 : : /* Likewise, but also include the artificial vars. We don't want to
2677 : : disallow the artificial vars being mentioned in explicit clauses,
2678 : : as we use artificial vars e.g. for loop constructs with random
2679 : : access iterators other than pointers, but during gimplification
2680 : : we want to treat them as predetermined. */
2681 : :
2682 : : enum omp_clause_default_kind
2683 : 32328 : cxx_omp_predetermined_sharing (tree decl)
2684 : : {
2685 : 32328 : enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
2686 : 32328 : if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
2687 : : return ret;
2688 : :
2689 : : /* Predetermine artificial variables holding integral values, those
2690 : : are usually result of gimplify_one_sizepos or SAVE_EXPR
2691 : : gimplification. */
2692 : 32114 : if (VAR_P (decl)
2693 : 21025 : && DECL_ARTIFICIAL (decl)
2694 : 6129 : && INTEGRAL_TYPE_P (TREE_TYPE (decl))
2695 : 32632 : && !(DECL_LANG_SPECIFIC (decl)
2696 : 2 : && DECL_OMP_PRIVATIZED_MEMBER (decl)))
2697 : : return OMP_CLAUSE_DEFAULT_SHARED;
2698 : :
2699 : : /* Similarly for typeinfo symbols. */
2700 : 31598 : if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl))
2701 : : return OMP_CLAUSE_DEFAULT_SHARED;
2702 : :
2703 : : return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
2704 : : }
2705 : :
2706 : : enum omp_clause_defaultmap_kind
2707 : 6262 : cxx_omp_predetermined_mapping (tree decl)
2708 : : {
2709 : : /* Predetermine artificial variables holding integral values, those
2710 : : are usually result of gimplify_one_sizepos or SAVE_EXPR
2711 : : gimplification. */
2712 : 6262 : if (VAR_P (decl)
2713 : 1278 : && DECL_ARTIFICIAL (decl)
2714 : 78 : && INTEGRAL_TYPE_P (TREE_TYPE (decl))
2715 : 6328 : && !(DECL_LANG_SPECIFIC (decl)
2716 : 6 : && DECL_OMP_PRIVATIZED_MEMBER (decl)))
2717 : : return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
2718 : :
2719 : 6196 : if (c_omp_predefined_variable (decl))
2720 : 0 : return OMP_CLAUSE_DEFAULTMAP_TO;
2721 : :
2722 : : return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
2723 : : }
2724 : :
2725 : : /* Finalize an implicitly determined clause. */
2726 : :
2727 : : void
2728 : 61527 : cxx_omp_finish_clause (tree c, gimple_seq *, bool /* openacc */)
2729 : : {
2730 : 61527 : tree decl, inner_type;
2731 : 61527 : bool make_shared = false;
2732 : :
2733 : 61527 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
2734 : 54446 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
2735 : 90487 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
2736 : 4746 : || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
2737 : : return;
2738 : :
2739 : 32582 : decl = OMP_CLAUSE_DECL (c);
2740 : 32582 : decl = require_complete_type (decl);
2741 : 32582 : inner_type = TREE_TYPE (decl);
2742 : 32582 : if (decl == error_mark_node)
2743 : 32582 : make_shared = true;
2744 : 32582 : else if (TYPE_REF_P (TREE_TYPE (decl)))
2745 : 89 : inner_type = TREE_TYPE (inner_type);
2746 : :
2747 : : /* We're interested in the base element, not arrays. */
2748 : 32835 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
2749 : 253 : inner_type = TREE_TYPE (inner_type);
2750 : :
2751 : : /* Check for special function availability by building a call to one.
2752 : : Save the results, because later we won't be in the right context
2753 : : for making these queries. */
2754 : 32582 : bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
2755 : 32582 : bool last = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE;
2756 : 32582 : if (!make_shared
2757 : 32582 : && CLASS_TYPE_P (inner_type)
2758 : 32806 : && cxx_omp_create_clause_info (c, inner_type, !first, first, last,
2759 : : true))
2760 : : make_shared = true;
2761 : :
2762 : 32576 : if (make_shared)
2763 : : {
2764 : 6 : OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
2765 : 6 : OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
2766 : 6 : OMP_CLAUSE_SHARED_READONLY (c) = 0;
2767 : : }
2768 : : }
2769 : :
2770 : : /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
2771 : : disregarded in OpenMP construct, because it is going to be
2772 : : remapped during OpenMP lowering. SHARED is true if DECL
2773 : : is going to be shared, false if it is going to be privatized. */
2774 : :
2775 : : bool
2776 : 555543 : cxx_omp_disregard_value_expr (tree decl, bool shared)
2777 : : {
2778 : 555543 : if (shared)
2779 : : return false;
2780 : 388675 : if (VAR_P (decl)
2781 : 367065 : && DECL_HAS_VALUE_EXPR_P (decl)
2782 : 9349 : && DECL_ARTIFICIAL (decl)
2783 : 8849 : && DECL_LANG_SPECIFIC (decl)
2784 : 396478 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
2785 : : return true;
2786 : 383337 : if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
2787 : : return true;
2788 : : return false;
2789 : : }
2790 : :
2791 : : /* Fold expression X which is used as an rvalue if RVAL is true. */
2792 : :
2793 : : static tree
2794 : 1425196317 : cp_fold_maybe_rvalue (tree x, bool rval, fold_flags_t flags)
2795 : : {
2796 : 1451884193 : while (true)
2797 : : {
2798 : 1438540255 : x = cp_fold (x, flags);
2799 : 1438540255 : if (rval)
2800 : 1032962570 : x = mark_rvalue_use (x);
2801 : 1032962570 : if (rval && DECL_P (x)
2802 : 261786326 : && !TYPE_REF_P (TREE_TYPE (x)))
2803 : : {
2804 : 226956700 : tree v = decl_constant_value (x);
2805 : 226956700 : if (v != x && v != error_mark_node)
2806 : : {
2807 : 13343938 : x = v;
2808 : 13343938 : continue;
2809 : : }
2810 : : }
2811 : 1425196317 : break;
2812 : 13343938 : }
2813 : 1425196317 : return x;
2814 : : }
2815 : :
2816 : : tree
2817 : 58591773 : cp_fold_maybe_rvalue (tree x, bool rval)
2818 : : {
2819 : 58591773 : return cp_fold_maybe_rvalue (x, rval, ff_none);
2820 : : }
2821 : :
2822 : : /* Fold expression X which is used as an rvalue. */
2823 : :
2824 : : static tree
2825 : 476457855 : cp_fold_rvalue (tree x, fold_flags_t flags)
2826 : : {
2827 : 297989320 : return cp_fold_maybe_rvalue (x, true, flags);
2828 : : }
2829 : :
2830 : : tree
2831 : 306222 : cp_fold_rvalue (tree x)
2832 : : {
2833 : 306222 : return cp_fold_rvalue (x, ff_none);
2834 : : }
2835 : :
2836 : : /* Perform folding on expression X. */
2837 : :
2838 : : static tree
2839 : 192263280 : cp_fully_fold (tree x, mce_value manifestly_const_eval)
2840 : : {
2841 : 192263280 : if (processing_template_decl)
2842 : : return x;
2843 : : /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
2844 : : have to call both. */
2845 : 178162313 : if (cxx_dialect >= cxx11)
2846 : : {
2847 : 177090378 : x = maybe_constant_value (x, /*decl=*/NULL_TREE, manifestly_const_eval);
2848 : : /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
2849 : : a TARGET_EXPR; undo that here. */
2850 : 177090378 : if (TREE_CODE (x) == TARGET_EXPR)
2851 : 603248 : x = TARGET_EXPR_INITIAL (x);
2852 : 176487130 : else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
2853 : 24331402 : && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
2854 : 176487317 : && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
2855 : 187 : x = TREE_OPERAND (x, 0);
2856 : : }
2857 : 178162313 : fold_flags_t flags = ff_none;
2858 : 178162313 : if (manifestly_const_eval == mce_false)
2859 : 28907148 : flags |= ff_mce_false;
2860 : 178162313 : return cp_fold_rvalue (x, flags);
2861 : : }
2862 : :
2863 : : tree
2864 : 163356132 : cp_fully_fold (tree x)
2865 : : {
2866 : 163356132 : return cp_fully_fold (x, mce_unknown);
2867 : : }
2868 : :
2869 : : /* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
2870 : : in some cases. */
2871 : :
2872 : : tree
2873 : 30409225 : cp_fully_fold_init (tree x)
2874 : : {
2875 : 30409225 : if (processing_template_decl)
2876 : 1502077 : return x;
2877 : 28907148 : x = cp_fully_fold (x, mce_false);
2878 : 28907148 : cp_fold_data data (ff_mce_false);
2879 : 28907148 : cp_walk_tree (&x, cp_fold_r, &data, NULL);
2880 : 28907148 : return x;
2881 : 28907148 : }
2882 : :
2883 : : /* c-common interface to cp_fold. If IN_INIT, this is in a static initializer
2884 : : and certain changes are made to the folding done. Or should be (FIXME). We
2885 : : never touch maybe_const, as it is only used for the C front-end
2886 : : C_MAYBE_CONST_EXPR. */
2887 : :
2888 : : tree
2889 : 58591773 : c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
2890 : : {
2891 : 58591773 : return cp_fold_maybe_rvalue (x, !lval);
2892 : : }
2893 : :
2894 : : static GTY((deletable)) hash_map<tree, tree> *fold_caches[2];
2895 : :
2896 : : /* Subroutine of cp_fold. Returns which fold cache to use according
2897 : : to the given flags. We need multiple caches since the result of
2898 : : folding may depend on which flags are used. */
2899 : :
2900 : : static hash_map<tree, tree> *&
2901 : 2098629395 : get_fold_cache (fold_flags_t flags)
2902 : : {
2903 : 0 : if (flags & ff_mce_false)
2904 : : return fold_caches[1];
2905 : : else
2906 : 314973580 : return fold_caches[0];
2907 : : }
2908 : :
2909 : : /* Dispose of the whole FOLD_CACHE. */
2910 : :
2911 : : void
2912 : 22394646 : clear_fold_cache (void)
2913 : : {
2914 : 67183938 : for (auto& fold_cache : fold_caches)
2915 : 44789292 : if (fold_cache != NULL)
2916 : 55061687 : fold_cache->empty ();
2917 : 22394646 : }
2918 : :
2919 : : /* This function tries to fold an expression X.
2920 : : To avoid combinatorial explosion, folding results are kept in fold_cache.
2921 : : If X is invalid, we don't fold at all.
2922 : : For performance reasons we don't cache expressions representing a
2923 : : declaration or constant.
2924 : : Function returns X or its folded variant. */
2925 : :
2926 : : static tree
2927 : 3422489652 : cp_fold (tree x, fold_flags_t flags)
2928 : : {
2929 : 3422489652 : tree op0, op1, op2, op3;
2930 : 3422489652 : tree org_x = x, r = NULL_TREE;
2931 : 3422489652 : enum tree_code code;
2932 : 3422489652 : location_t loc;
2933 : 3422489652 : bool rval_ops = true;
2934 : :
2935 : 3422489652 : if (!x || x == error_mark_node)
2936 : : return x;
2937 : :
2938 : 3419205045 : if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
2939 : : return x;
2940 : :
2941 : : /* Don't bother to cache DECLs or constants. */
2942 : 3419080530 : if (DECL_P (x) || CONSTANT_CLASS_P (x))
2943 : : return x;
2944 : :
2945 : 2098629395 : auto& fold_cache = get_fold_cache (flags);
2946 : 2098629395 : if (fold_cache == NULL)
2947 : 303282 : fold_cache = hash_map<tree, tree>::create_ggc (101);
2948 : :
2949 : 2098629395 : if (tree *cached = fold_cache->get (x))
2950 : : {
2951 : : /* unshare_expr doesn't recurse into SAVE_EXPRs. If SAVE_EXPR's
2952 : : argument has been folded into a tree invariant, make sure it is
2953 : : unshared. See PR112727. */
2954 : 418264492 : if (TREE_CODE (x) == SAVE_EXPR && *cached != x)
2955 : 77 : return unshare_expr (*cached);
2956 : 418264415 : return *cached;
2957 : : }
2958 : :
2959 : 1680364903 : uid_sensitive_constexpr_evaluation_checker c;
2960 : :
2961 : 1680364903 : code = TREE_CODE (x);
2962 : 1680364903 : switch (code)
2963 : : {
2964 : 90761783 : case CLEANUP_POINT_EXPR:
2965 : : /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
2966 : : effects. */
2967 : 90761783 : r = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
2968 : 90761783 : if (!TREE_SIDE_EFFECTS (r))
2969 : 1257594 : x = r;
2970 : : break;
2971 : :
2972 : 1391262 : case SIZEOF_EXPR:
2973 : 1391262 : x = fold_sizeof_expr (x);
2974 : 1391262 : break;
2975 : :
2976 : 195585198 : case VIEW_CONVERT_EXPR:
2977 : 195585198 : rval_ops = false;
2978 : : /* FALLTHRU */
2979 : 516107633 : case NON_LVALUE_EXPR:
2980 : 516107633 : CASE_CONVERT:
2981 : :
2982 : 516107633 : if (VOID_TYPE_P (TREE_TYPE (x)))
2983 : : {
2984 : : /* This is just to make sure we don't end up with casts to
2985 : : void from error_mark_node. If we just return x, then
2986 : : cp_fold_r might fold the operand into error_mark_node and
2987 : : leave the conversion in the IR. STRIP_USELESS_TYPE_CONVERSION
2988 : : during gimplification doesn't like such casts.
2989 : : Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
2990 : : folding of the operand should be in the caches and if in cp_fold_r
2991 : : it will modify it in place. */
2992 : 36915303 : op0 = cp_fold (TREE_OPERAND (x, 0), flags);
2993 : 36915303 : if (op0 == error_mark_node)
2994 : 44 : x = error_mark_node;
2995 : : break;
2996 : : }
2997 : :
2998 : 479192330 : loc = EXPR_LOCATION (x);
2999 : 479192330 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3000 : :
3001 : 479192330 : if (code == CONVERT_EXPR
3002 : 37178808 : && SCALAR_TYPE_P (TREE_TYPE (x))
3003 : 516370391 : && op0 != void_node)
3004 : : /* During parsing we used convert_to_*_nofold; re-convert now using the
3005 : : folding variants, since fold() doesn't do those transformations. */
3006 : 33667917 : x = fold (convert (TREE_TYPE (x), op0));
3007 : 445524413 : else if (op0 != TREE_OPERAND (x, 0))
3008 : : {
3009 : 113921640 : if (op0 == error_mark_node)
3010 : 0 : x = error_mark_node;
3011 : : else
3012 : 113921640 : x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
3013 : : }
3014 : : else
3015 : 331602773 : x = fold (x);
3016 : :
3017 : : /* Conversion of an out-of-range value has implementation-defined
3018 : : behavior; the language considers it different from arithmetic
3019 : : overflow, which is undefined. */
3020 : 479192330 : if (TREE_CODE (op0) == INTEGER_CST
3021 : 479192330 : && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
3022 : 24 : TREE_OVERFLOW (x) = false;
3023 : :
3024 : : break;
3025 : :
3026 : 180 : case EXCESS_PRECISION_EXPR:
3027 : 180 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3028 : 180 : x = fold_convert_loc (EXPR_LOCATION (x), TREE_TYPE (x), op0);
3029 : 180 : break;
3030 : :
3031 : 56202935 : case INDIRECT_REF:
3032 : : /* We don't need the decltype(auto) obfuscation anymore. */
3033 : 56202935 : if (REF_PARENTHESIZED_P (x))
3034 : : {
3035 : 448 : tree p = maybe_undo_parenthesized_ref (x);
3036 : 448 : if (p != x)
3037 : 0 : return cp_fold (p, flags);
3038 : : }
3039 : 56202935 : goto unary;
3040 : :
3041 : 123301613 : case ADDR_EXPR:
3042 : 123301613 : loc = EXPR_LOCATION (x);
3043 : 123301613 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false, flags);
3044 : :
3045 : : /* Cope with user tricks that amount to offsetof. */
3046 : 123301613 : if (op0 != error_mark_node
3047 : 123301613 : && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0)))
3048 : : {
3049 : 47295882 : tree val = get_base_address (op0);
3050 : 47295882 : if (val
3051 : 47295882 : && INDIRECT_REF_P (val)
3052 : 19655594 : && COMPLETE_TYPE_P (TREE_TYPE (val))
3053 : 66951386 : && TREE_CONSTANT (TREE_OPERAND (val, 0)))
3054 : : {
3055 : 210 : val = TREE_OPERAND (val, 0);
3056 : 210 : STRIP_NOPS (val);
3057 : 210 : val = maybe_constant_value (val);
3058 : 210 : if (TREE_CODE (val) == INTEGER_CST)
3059 : 129 : return fold_offsetof (op0, TREE_TYPE (x));
3060 : : }
3061 : : }
3062 : 123301484 : goto finish_unary;
3063 : :
3064 : : case REALPART_EXPR:
3065 : : case IMAGPART_EXPR:
3066 : 84945372 : rval_ops = false;
3067 : : /* FALLTHRU */
3068 : 84945372 : case CONJ_EXPR:
3069 : 84945372 : case FIX_TRUNC_EXPR:
3070 : 84945372 : case FLOAT_EXPR:
3071 : 84945372 : case NEGATE_EXPR:
3072 : 84945372 : case ABS_EXPR:
3073 : 84945372 : case ABSU_EXPR:
3074 : 84945372 : case BIT_NOT_EXPR:
3075 : 84945372 : case TRUTH_NOT_EXPR:
3076 : 84945372 : case FIXED_CONVERT_EXPR:
3077 : 84945372 : unary:
3078 : :
3079 : 84945372 : loc = EXPR_LOCATION (x);
3080 : 84945372 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3081 : :
3082 : 208246856 : finish_unary:
3083 : 208246856 : if (op0 != TREE_OPERAND (x, 0))
3084 : : {
3085 : 28927045 : if (op0 == error_mark_node)
3086 : 0 : x = error_mark_node;
3087 : : else
3088 : : {
3089 : 28927045 : x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
3090 : 28927045 : if (code == INDIRECT_REF
3091 : 6873372 : && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
3092 : : {
3093 : 6873248 : TREE_READONLY (x) = TREE_READONLY (org_x);
3094 : 6873248 : TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
3095 : 6873248 : TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
3096 : : }
3097 : : }
3098 : : }
3099 : : else
3100 : 179319811 : x = fold (x);
3101 : :
3102 : 208246856 : gcc_assert (TREE_CODE (x) != COND_EXPR
3103 : : || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
3104 : : break;
3105 : :
3106 : 191771 : case UNARY_PLUS_EXPR:
3107 : 191771 : op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
3108 : 191771 : if (op0 == error_mark_node)
3109 : 0 : x = error_mark_node;
3110 : : else
3111 : 191771 : x = fold_convert (TREE_TYPE (x), op0);
3112 : : break;
3113 : :
3114 : 84974269 : case POSTDECREMENT_EXPR:
3115 : 84974269 : case POSTINCREMENT_EXPR:
3116 : 84974269 : case INIT_EXPR:
3117 : 84974269 : case PREDECREMENT_EXPR:
3118 : 84974269 : case PREINCREMENT_EXPR:
3119 : 84974269 : case COMPOUND_EXPR:
3120 : 84974269 : case MODIFY_EXPR:
3121 : 84974269 : rval_ops = false;
3122 : : /* FALLTHRU */
3123 : 202707194 : case POINTER_PLUS_EXPR:
3124 : 202707194 : case PLUS_EXPR:
3125 : 202707194 : case POINTER_DIFF_EXPR:
3126 : 202707194 : case MINUS_EXPR:
3127 : 202707194 : case MULT_EXPR:
3128 : 202707194 : case TRUNC_DIV_EXPR:
3129 : 202707194 : case CEIL_DIV_EXPR:
3130 : 202707194 : case FLOOR_DIV_EXPR:
3131 : 202707194 : case ROUND_DIV_EXPR:
3132 : 202707194 : case TRUNC_MOD_EXPR:
3133 : 202707194 : case CEIL_MOD_EXPR:
3134 : 202707194 : case ROUND_MOD_EXPR:
3135 : 202707194 : case RDIV_EXPR:
3136 : 202707194 : case EXACT_DIV_EXPR:
3137 : 202707194 : case MIN_EXPR:
3138 : 202707194 : case MAX_EXPR:
3139 : 202707194 : case LSHIFT_EXPR:
3140 : 202707194 : case RSHIFT_EXPR:
3141 : 202707194 : case LROTATE_EXPR:
3142 : 202707194 : case RROTATE_EXPR:
3143 : 202707194 : case BIT_AND_EXPR:
3144 : 202707194 : case BIT_IOR_EXPR:
3145 : 202707194 : case BIT_XOR_EXPR:
3146 : 202707194 : case TRUTH_AND_EXPR:
3147 : 202707194 : case TRUTH_ANDIF_EXPR:
3148 : 202707194 : case TRUTH_OR_EXPR:
3149 : 202707194 : case TRUTH_ORIF_EXPR:
3150 : 202707194 : case TRUTH_XOR_EXPR:
3151 : 202707194 : case LT_EXPR: case LE_EXPR:
3152 : 202707194 : case GT_EXPR: case GE_EXPR:
3153 : 202707194 : case EQ_EXPR: case NE_EXPR:
3154 : 202707194 : case UNORDERED_EXPR: case ORDERED_EXPR:
3155 : 202707194 : case UNLT_EXPR: case UNLE_EXPR:
3156 : 202707194 : case UNGT_EXPR: case UNGE_EXPR:
3157 : 202707194 : case UNEQ_EXPR: case LTGT_EXPR:
3158 : 202707194 : case RANGE_EXPR: case COMPLEX_EXPR:
3159 : :
3160 : 202707194 : loc = EXPR_LOCATION (x);
3161 : 202707194 : op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
3162 : 202707194 : op1 = cp_fold_rvalue (TREE_OPERAND (x, 1), flags);
3163 : :
3164 : : /* decltype(nullptr) has only one value, so optimize away all comparisons
3165 : : with that type right away, keeping them in the IL causes troubles for
3166 : : various optimizations. */
3167 : 202707194 : if (COMPARISON_CLASS_P (org_x)
3168 : 34251670 : && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
3169 : 202707224 : && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
3170 : : {
3171 : 30 : switch (code)
3172 : : {
3173 : 15 : case EQ_EXPR:
3174 : 15 : x = constant_boolean_node (true, TREE_TYPE (x));
3175 : 15 : break;
3176 : 15 : case NE_EXPR:
3177 : 15 : x = constant_boolean_node (false, TREE_TYPE (x));
3178 : 15 : break;
3179 : 0 : default:
3180 : 0 : gcc_unreachable ();
3181 : : }
3182 : 30 : return omit_two_operands_loc (loc, TREE_TYPE (x), x,
3183 : 30 : op0, op1);
3184 : : }
3185 : :
3186 : 202707164 : if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
3187 : : {
3188 : 139217930 : if (op0 == error_mark_node || op1 == error_mark_node)
3189 : 57 : x = error_mark_node;
3190 : : else
3191 : 139217873 : x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
3192 : : }
3193 : : else
3194 : 63489234 : x = fold (x);
3195 : :
3196 : : /* This is only needed for -Wnonnull-compare and only if
3197 : : TREE_NO_WARNING (org_x), but to avoid that option affecting code
3198 : : generation, we do it always. */
3199 : 202707164 : if (COMPARISON_CLASS_P (org_x))
3200 : : {
3201 : 34251640 : if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
3202 : : ;
3203 : 33110984 : else if (COMPARISON_CLASS_P (x))
3204 : : {
3205 : 32253464 : if (warn_nonnull_compare
3206 : 32253464 : && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
3207 : 111833 : suppress_warning (x, OPT_Wnonnull_compare);
3208 : : }
3209 : : /* Otherwise give up on optimizing these, let GIMPLE folders
3210 : : optimize those later on. */
3211 : 857520 : else if (op0 != TREE_OPERAND (org_x, 0)
3212 : 857520 : || op1 != TREE_OPERAND (org_x, 1))
3213 : : {
3214 : 856987 : x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
3215 : 856987 : if (warn_nonnull_compare
3216 : 856987 : && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
3217 : 16 : suppress_warning (x, OPT_Wnonnull_compare);
3218 : : }
3219 : : else
3220 : 533 : x = org_x;
3221 : : }
3222 : :
3223 : : break;
3224 : :
3225 : 4328572 : case VEC_COND_EXPR:
3226 : 4328572 : case COND_EXPR:
3227 : 4328572 : loc = EXPR_LOCATION (x);
3228 : 4328572 : op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
3229 : 4328572 : op1 = cp_fold (TREE_OPERAND (x, 1), flags);
3230 : 4328572 : op2 = cp_fold (TREE_OPERAND (x, 2), flags);
3231 : :
3232 : 4328572 : if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
3233 : : {
3234 : 20005 : warning_sentinel s (warn_int_in_bool_context);
3235 : 20005 : if (!VOID_TYPE_P (TREE_TYPE (op1)))
3236 : 20005 : op1 = cp_truthvalue_conversion (op1, tf_warning_or_error);
3237 : 20005 : if (!VOID_TYPE_P (TREE_TYPE (op2)))
3238 : 19984 : op2 = cp_truthvalue_conversion (op2, tf_warning_or_error);
3239 : 20005 : }
3240 : 4308567 : else if (VOID_TYPE_P (TREE_TYPE (x)))
3241 : : {
3242 : 1260726 : if (TREE_CODE (op0) == INTEGER_CST)
3243 : : {
3244 : : /* If the condition is constant, fold can fold away
3245 : : the COND_EXPR. If some statement-level uses of COND_EXPR
3246 : : have one of the branches NULL, avoid folding crash. */
3247 : 180954 : if (!op1)
3248 : 0 : op1 = build_empty_stmt (loc);
3249 : 180954 : if (!op2)
3250 : 0 : op2 = build_empty_stmt (loc);
3251 : : }
3252 : : else
3253 : : {
3254 : : /* Otherwise, don't bother folding a void condition, since
3255 : : it can't produce a constant value. */
3256 : 1079772 : if (op0 != TREE_OPERAND (x, 0)
3257 : 1072828 : || op1 != TREE_OPERAND (x, 1)
3258 : 2035938 : || op2 != TREE_OPERAND (x, 2))
3259 : 124220 : x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
3260 : : break;
3261 : : }
3262 : : }
3263 : :
3264 : 3248800 : if (op0 != TREE_OPERAND (x, 0)
3265 : 1221103 : || op1 != TREE_OPERAND (x, 1)
3266 : 4166035 : || op2 != TREE_OPERAND (x, 2))
3267 : : {
3268 : 2396794 : if (op0 == error_mark_node
3269 : 2396794 : || op1 == error_mark_node
3270 : 2396793 : || op2 == error_mark_node)
3271 : 46 : x = error_mark_node;
3272 : : else
3273 : 2396748 : x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
3274 : : }
3275 : : else
3276 : 852006 : x = fold (x);
3277 : :
3278 : : /* A COND_EXPR might have incompatible types in branches if one or both
3279 : : arms are bitfields. If folding exposed such a branch, fix it up. */
3280 : 3248800 : if (TREE_CODE (x) != code
3281 : 729074 : && x != error_mark_node
3282 : 3977828 : && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
3283 : 18231 : x = fold_convert (TREE_TYPE (org_x), x);
3284 : :
3285 : : break;
3286 : :
3287 : 109467763 : case CALL_EXPR:
3288 : 109467763 : {
3289 : 109467763 : tree callee = get_callee_fndecl (x);
3290 : :
3291 : : /* "Inline" calls to std::move/forward and other cast-like functions
3292 : : by simply folding them into a corresponding cast to their return
3293 : : type. This is cheaper than relying on the middle end to do so, and
3294 : : also means we avoid generating useless debug info for them at all.
3295 : :
3296 : : At this point the argument has already been converted into a
3297 : : reference, so it suffices to use a NOP_EXPR to express the
3298 : : cast. */
3299 : 109467763 : if ((OPTION_SET_P (flag_fold_simple_inlines)
3300 : 109467763 : ? flag_fold_simple_inlines
3301 : 109467689 : : !flag_no_inline)
3302 : 106337343 : && call_expr_nargs (x) == 1
3303 : 55803936 : && decl_in_std_namespace_p (callee)
3304 : 37089242 : && DECL_NAME (callee) != NULL_TREE
3305 : 146557005 : && (id_equal (DECL_NAME (callee), "move")
3306 : 36062876 : || id_equal (DECL_NAME (callee), "forward")
3307 : 35022047 : || id_equal (DECL_NAME (callee), "forward_like")
3308 : 35022045 : || id_equal (DECL_NAME (callee), "addressof")
3309 : : /* This addressof equivalent is used heavily in libstdc++. */
3310 : 34829393 : || id_equal (DECL_NAME (callee), "__addressof")
3311 : 34404645 : || id_equal (DECL_NAME (callee), "as_const")))
3312 : : {
3313 : 2684844 : r = CALL_EXPR_ARG (x, 0);
3314 : : /* Check that the return and argument types are sane before
3315 : : folding. */
3316 : 4752288 : if (INDIRECT_TYPE_P (TREE_TYPE (x))
3317 : 4752288 : && INDIRECT_TYPE_P (TREE_TYPE (r)))
3318 : : {
3319 : 2684844 : if (!same_type_p (TREE_TYPE (x), TREE_TYPE (r)))
3320 : 2434909 : r = build_nop (TREE_TYPE (x), r);
3321 : 2684844 : x = cp_fold (r, flags);
3322 : 2684844 : break;
3323 : : }
3324 : : }
3325 : :
3326 : 106782919 : int sv = optimize, nw = sv;
3327 : :
3328 : : /* Some built-in function calls will be evaluated at compile-time in
3329 : : fold (). Set optimize to 1 when folding __builtin_constant_p inside
3330 : : a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
3331 : 105453022 : if (callee && fndecl_built_in_p (callee) && !optimize
3332 : 614338 : && DECL_IS_BUILTIN_CONSTANT_P (callee)
3333 : 9253 : && current_function_decl
3334 : 106792150 : && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
3335 : : nw = 1;
3336 : :
3337 : 106782919 : if (callee && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
3338 : : {
3339 : 34274 : iloc_sentinel ils (EXPR_LOCATION (x));
3340 : 34274 : switch (DECL_FE_FUNCTION_CODE (callee))
3341 : : {
3342 : 33402 : case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
3343 : : /* Defer folding __builtin_is_constant_evaluated unless
3344 : : we know this isn't a manifestly constant-evaluated
3345 : : context. */
3346 : 33402 : if (flags & ff_mce_false)
3347 : 17076 : x = boolean_false_node;
3348 : : break;
3349 : 18 : case CP_BUILT_IN_SOURCE_LOCATION:
3350 : 18 : x = fold_builtin_source_location (x);
3351 : 18 : break;
3352 : 444 : case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
3353 : 888 : x = fold_builtin_is_corresponding_member
3354 : 444 : (EXPR_LOCATION (x), call_expr_nargs (x),
3355 : : &CALL_EXPR_ARG (x, 0));
3356 : 444 : break;
3357 : 410 : case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
3358 : 820 : x = fold_builtin_is_pointer_inverconvertible_with_class
3359 : 410 : (EXPR_LOCATION (x), call_expr_nargs (x),
3360 : : &CALL_EXPR_ARG (x, 0));
3361 : 410 : break;
3362 : : default:
3363 : : break;
3364 : : }
3365 : 34274 : break;
3366 : 34274 : }
3367 : :
3368 : 106748645 : if (callee
3369 : 106748645 : && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
3370 : : BUILT_IN_FRONTEND))
3371 : : {
3372 : 0 : x = fold_builtin_source_location (x);
3373 : 0 : break;
3374 : : }
3375 : :
3376 : 106748645 : bool changed = false;
3377 : 106748645 : int m = call_expr_nargs (x);
3378 : 265946577 : for (int i = 0; i < m; i++)
3379 : : {
3380 : 159197932 : r = cp_fold (CALL_EXPR_ARG (x, i), flags);
3381 : 159197932 : if (r != CALL_EXPR_ARG (x, i))
3382 : : {
3383 : 93646608 : if (r == error_mark_node)
3384 : : {
3385 : 0 : x = error_mark_node;
3386 : 0 : break;
3387 : : }
3388 : 93646608 : if (!changed)
3389 : 58710090 : x = copy_node (x);
3390 : 93646608 : CALL_EXPR_ARG (x, i) = r;
3391 : 93646608 : changed = true;
3392 : : }
3393 : : }
3394 : 106748645 : if (x == error_mark_node)
3395 : : break;
3396 : :
3397 : 106748645 : optimize = nw;
3398 : 106748645 : r = fold (x);
3399 : 106748645 : optimize = sv;
3400 : :
3401 : 106748645 : if (TREE_CODE (r) != CALL_EXPR)
3402 : : {
3403 : 2314927 : x = cp_fold (r, flags);
3404 : 2314927 : break;
3405 : : }
3406 : :
3407 : 104433718 : optimize = nw;
3408 : :
3409 : : /* Invoke maybe_constant_value for functions declared
3410 : : constexpr and not called with AGGR_INIT_EXPRs.
3411 : : TODO:
3412 : : Do constexpr expansion of expressions where the call itself is not
3413 : : constant, but the call followed by an INDIRECT_REF is. */
3414 : 103103821 : if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
3415 : 135344596 : && !flag_no_inline)
3416 : : {
3417 : 29904497 : mce_value manifestly_const_eval = mce_unknown;
3418 : 29904497 : if (flags & ff_mce_false)
3419 : : /* Allow folding __builtin_is_constant_evaluated to false during
3420 : : constexpr evaluation of this call. */
3421 : 22361959 : manifestly_const_eval = mce_false;
3422 : 29904497 : r = maybe_constant_value (x, /*decl=*/NULL_TREE,
3423 : : manifestly_const_eval);
3424 : : }
3425 : 104433718 : optimize = sv;
3426 : :
3427 : 104433718 : if (TREE_CODE (r) != CALL_EXPR)
3428 : : {
3429 : 6847974 : if (DECL_CONSTRUCTOR_P (callee))
3430 : : {
3431 : 64260 : loc = EXPR_LOCATION (x);
3432 : 64260 : tree a = CALL_EXPR_ARG (x, 0);
3433 : 64260 : bool return_this = targetm.cxx.cdtor_returns_this ();
3434 : 64260 : if (return_this)
3435 : 0 : a = cp_save_expr (a);
3436 : 64260 : tree s = build_fold_indirect_ref_loc (loc, a);
3437 : 64260 : r = cp_build_init_expr (s, r);
3438 : 64260 : if (return_this)
3439 : 0 : r = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (x), r,
3440 : 0 : fold_convert_loc (loc, TREE_TYPE (x), a));
3441 : : }
3442 : 3423987 : x = r;
3443 : 3423987 : break;
3444 : : }
3445 : :
3446 : : break;
3447 : : }
3448 : :
3449 : 18092309 : case CONSTRUCTOR:
3450 : 18092309 : {
3451 : 18092309 : unsigned i;
3452 : 18092309 : constructor_elt *p;
3453 : 18092309 : vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
3454 : 18092309 : vec<constructor_elt, va_gc> *nelts = NULL;
3455 : 39545152 : FOR_EACH_VEC_SAFE_ELT (elts, i, p)
3456 : : {
3457 : 21452843 : tree op = cp_fold (p->value, flags);
3458 : 21452843 : if (op != p->value)
3459 : : {
3460 : 937256 : if (op == error_mark_node)
3461 : : {
3462 : 0 : x = error_mark_node;
3463 : 0 : vec_free (nelts);
3464 : : break;
3465 : : }
3466 : 937256 : if (nelts == NULL)
3467 : 689709 : nelts = elts->copy ();
3468 : 937256 : (*nelts)[i].value = op;
3469 : : }
3470 : : }
3471 : 18092309 : if (nelts)
3472 : : {
3473 : 689709 : x = build_constructor (TREE_TYPE (x), nelts);
3474 : 689709 : CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
3475 : 689709 : = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
3476 : 689709 : CONSTRUCTOR_MUTABLE_POISON (x)
3477 : 1379418 : = CONSTRUCTOR_MUTABLE_POISON (org_x);
3478 : : }
3479 : 18092309 : if (VECTOR_TYPE_P (TREE_TYPE (x)))
3480 : 42588 : x = fold (x);
3481 : : break;
3482 : : }
3483 : 53226 : case TREE_VEC:
3484 : 53226 : {
3485 : 53226 : bool changed = false;
3486 : 53226 : int n = TREE_VEC_LENGTH (x);
3487 : :
3488 : 131591 : for (int i = 0; i < n; i++)
3489 : : {
3490 : 78365 : tree op = cp_fold (TREE_VEC_ELT (x, i), flags);
3491 : 78365 : if (op != TREE_VEC_ELT (x, i))
3492 : : {
3493 : 809 : if (!changed)
3494 : 774 : x = copy_node (x);
3495 : 809 : TREE_VEC_ELT (x, i) = op;
3496 : 809 : changed = true;
3497 : : }
3498 : : }
3499 : : }
3500 : :
3501 : : break;
3502 : :
3503 : 1634658 : case ARRAY_REF:
3504 : 1634658 : case ARRAY_RANGE_REF:
3505 : :
3506 : 1634658 : loc = EXPR_LOCATION (x);
3507 : 1634658 : op0 = cp_fold (TREE_OPERAND (x, 0), flags);
3508 : 1634658 : op1 = cp_fold (TREE_OPERAND (x, 1), flags);
3509 : 1634658 : op2 = cp_fold (TREE_OPERAND (x, 2), flags);
3510 : 1634658 : op3 = cp_fold (TREE_OPERAND (x, 3), flags);
3511 : :
3512 : 1634658 : if (op0 != TREE_OPERAND (x, 0)
3513 : 721419 : || op1 != TREE_OPERAND (x, 1)
3514 : 367978 : || op2 != TREE_OPERAND (x, 2)
3515 : 2002636 : || op3 != TREE_OPERAND (x, 3))
3516 : : {
3517 : 1266680 : if (op0 == error_mark_node
3518 : 1266680 : || op1 == error_mark_node
3519 : 1266680 : || op2 == error_mark_node
3520 : 1266680 : || op3 == error_mark_node)
3521 : 0 : x = error_mark_node;
3522 : : else
3523 : : {
3524 : 1266680 : x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
3525 : 1266680 : TREE_READONLY (x) = TREE_READONLY (org_x);
3526 : 1266680 : TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
3527 : 1266680 : TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
3528 : : }
3529 : : }
3530 : :
3531 : 1634658 : x = fold (x);
3532 : 1634658 : break;
3533 : :
3534 : 1002964 : case SAVE_EXPR:
3535 : : /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
3536 : : folding, evaluates to an invariant. In that case no need to wrap
3537 : : this folded tree with a SAVE_EXPR. */
3538 : 1002964 : r = cp_fold (TREE_OPERAND (x, 0), flags);
3539 : 1002964 : if (tree_invariant_p (r))
3540 : 48 : x = r;
3541 : : break;
3542 : :
3543 : 8 : case REQUIRES_EXPR:
3544 : 8 : x = evaluate_requires_expr (x);
3545 : 8 : break;
3546 : :
3547 : : default:
3548 : : return org_x;
3549 : : }
3550 : :
3551 : 1153986149 : if (EXPR_P (x) && TREE_CODE (x) == code)
3552 : : {
3553 : 804102776 : TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
3554 : 804102776 : copy_warning (x, org_x);
3555 : : }
3556 : :
3557 : 1153986149 : if (!c.evaluation_restricted_p ())
3558 : : {
3559 : 1151827840 : fold_cache->put (org_x, x);
3560 : : /* Prevent that we try to fold an already folded result again. */
3561 : 1151827840 : if (x != org_x)
3562 : 625179715 : fold_cache->put (x, x);
3563 : : }
3564 : :
3565 : : return x;
3566 : : }
3567 : :
3568 : : /* Look up "hot", "cold", "likely" or "unlikely" in attribute list LIST. */
3569 : :
3570 : : tree
3571 : 230034676 : lookup_hotness_attribute (tree list)
3572 : : {
3573 : 230050189 : for (; list; list = TREE_CHAIN (list))
3574 : : {
3575 : 410660 : tree name = get_attribute_name (list);
3576 : 410660 : if ((is_attribute_p ("hot", name)
3577 : 410660 : || is_attribute_p ("cold", name)
3578 : 410657 : || is_attribute_p ("likely", name)
3579 : 288706 : || is_attribute_p ("unlikely", name))
3580 : 805816 : && is_attribute_namespace_p ("", list))
3581 : : break;
3582 : : }
3583 : 230034676 : return list;
3584 : : }
3585 : :
3586 : : /* Remove "hot", "cold", "likely" and "unlikely" attributes from LIST. */
3587 : :
3588 : : static tree
3589 : 395138 : remove_hotness_attribute (tree list)
3590 : : {
3591 : 790294 : for (tree *p = &list; *p; )
3592 : : {
3593 : 395156 : tree l = *p;
3594 : 395156 : tree name = get_attribute_name (l);
3595 : 395156 : if ((is_attribute_p ("hot", name)
3596 : 395156 : || is_attribute_p ("cold", name)
3597 : 395153 : || is_attribute_p ("likely", name)
3598 : 273202 : || is_attribute_p ("unlikely", name))
3599 : 790312 : && is_attribute_namespace_p ("", l))
3600 : : {
3601 : 395147 : *p = TREE_CHAIN (l);
3602 : 395147 : continue;
3603 : : }
3604 : 9 : p = &TREE_CHAIN (l);
3605 : : }
3606 : 395138 : return list;
3607 : : }
3608 : :
3609 : : /* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
3610 : : PREDICT_EXPR. */
3611 : :
3612 : : tree
3613 : 229639556 : process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc)
3614 : : {
3615 : 229639556 : if (std_attrs == error_mark_node)
3616 : : return std_attrs;
3617 : 229639538 : if (tree attr = lookup_hotness_attribute (std_attrs))
3618 : : {
3619 : 395138 : tree name = get_attribute_name (attr);
3620 : 395138 : bool hot = (is_attribute_p ("hot", name)
3621 : 395138 : || is_attribute_p ("likely", name));
3622 : 395138 : tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL,
3623 : : hot ? TAKEN : NOT_TAKEN);
3624 : 395138 : SET_EXPR_LOCATION (pred, attrs_loc);
3625 : 395138 : add_stmt (pred);
3626 : 395138 : if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
3627 : 9 : warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
3628 : : get_attribute_name (other), name);
3629 : 395138 : std_attrs = remove_hotness_attribute (std_attrs);
3630 : : }
3631 : : return std_attrs;
3632 : : }
3633 : :
3634 : : /* Build IFN_ASSUME internal call for assume condition ARG. */
3635 : :
3636 : : tree
3637 : 10744 : build_assume_call (location_t loc, tree arg)
3638 : : {
3639 : 10744 : if (!processing_template_decl)
3640 : 10699 : arg = fold_build_cleanup_point_expr (TREE_TYPE (arg), arg);
3641 : 10744 : return build_call_expr_internal_loc (loc, IFN_ASSUME, void_type_node,
3642 : 10744 : 1, arg);
3643 : : }
3644 : :
3645 : : /* If [[assume (cond)]] appears on this statement, handle it. */
3646 : :
3647 : : tree
3648 : 187142880 : process_stmt_assume_attribute (tree std_attrs, tree statement,
3649 : : location_t attrs_loc)
3650 : : {
3651 : 187142880 : if (std_attrs == error_mark_node)
3652 : : return std_attrs;
3653 : 187142862 : tree attr = lookup_attribute ("gnu", "assume", std_attrs);
3654 : 187142862 : if (!attr)
3655 : : return std_attrs;
3656 : : /* The next token after the assume attribute is not ';'. */
3657 : 10661 : if (statement)
3658 : : {
3659 : 12 : warning_at (attrs_loc, OPT_Wattributes,
3660 : : "%<assume%> attribute not followed by %<;%>");
3661 : 12 : attr = NULL_TREE;
3662 : : }
3663 : 21346 : for (; attr; attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
3664 : : {
3665 : 10685 : tree args = TREE_VALUE (attr);
3666 : 10685 : if (args && PACK_EXPANSION_P (args))
3667 : : {
3668 : 6 : auto_diagnostic_group d;
3669 : 6 : error_at (attrs_loc, "pack expansion of %qE attribute",
3670 : : get_attribute_name (attr));
3671 : 6 : if (cxx_dialect >= cxx17)
3672 : 4 : inform (attrs_loc, "use fold expression in the attribute "
3673 : : "argument instead");
3674 : 6 : continue;
3675 : 6 : }
3676 : 10679 : int nargs = list_length (args);
3677 : 10679 : if (nargs != 1)
3678 : : {
3679 : 36 : auto_diagnostic_group d;
3680 : 36 : error_at (attrs_loc, "wrong number of arguments specified for "
3681 : : "%qE attribute", get_attribute_name (attr));
3682 : 36 : inform (attrs_loc, "expected %i, found %i", 1, nargs);
3683 : 36 : }
3684 : : else
3685 : : {
3686 : 10643 : tree arg = TREE_VALUE (args);
3687 : 10643 : if (!type_dependent_expression_p (arg))
3688 : 10598 : arg = contextual_conv_bool (arg, tf_warning_or_error);
3689 : 10643 : if (error_operand_p (arg))
3690 : 18 : continue;
3691 : 10625 : finish_expr_stmt (build_assume_call (attrs_loc, arg));
3692 : : }
3693 : : }
3694 : 10661 : return remove_attribute ("gnu", "assume", std_attrs);
3695 : : }
3696 : :
3697 : : /* Return the type std::source_location::__impl after performing
3698 : : verification on it. */
3699 : :
3700 : : tree
3701 : 2029 : get_source_location_impl_type ()
3702 : : {
3703 : 2029 : tree name = get_identifier ("source_location");
3704 : 2029 : tree decl = lookup_qualified_name (std_node, name);
3705 : 2029 : if (TREE_CODE (decl) != TYPE_DECL)
3706 : : {
3707 : 6 : auto_diagnostic_group d;
3708 : 6 : if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
3709 : 3 : qualified_name_lookup_error (std_node, name, decl, input_location);
3710 : : else
3711 : 3 : error ("%qD is not a type", decl);
3712 : 6 : return error_mark_node;
3713 : 6 : }
3714 : 2023 : name = get_identifier ("__impl");
3715 : 2023 : tree type = TREE_TYPE (decl);
3716 : 2023 : decl = lookup_qualified_name (type, name);
3717 : 2023 : if (TREE_CODE (decl) != TYPE_DECL)
3718 : : {
3719 : 9 : auto_diagnostic_group d;
3720 : 9 : if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
3721 : 6 : qualified_name_lookup_error (type, name, decl, input_location);
3722 : : else
3723 : 3 : error ("%qD is not a type", decl);
3724 : 9 : return error_mark_node;
3725 : 9 : }
3726 : 2014 : type = TREE_TYPE (decl);
3727 : 2014 : if (TREE_CODE (type) != RECORD_TYPE)
3728 : : {
3729 : 3 : error ("%qD is not a class type", decl);
3730 : 3 : return error_mark_node;
3731 : : }
3732 : :
3733 : 2011 : int cnt = 0;
3734 : 2011 : for (tree field = TYPE_FIELDS (type);
3735 : 10016 : (field = next_aggregate_field (field)) != NULL_TREE;
3736 : 8005 : field = DECL_CHAIN (field))
3737 : : {
3738 : 8014 : if (DECL_NAME (field) != NULL_TREE)
3739 : : {
3740 : 8014 : const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
3741 : 8014 : if (strcmp (n, "_M_file_name") == 0
3742 : 6006 : || strcmp (n, "_M_function_name") == 0)
3743 : : {
3744 : 4013 : if (TREE_TYPE (field) != const_string_type_node)
3745 : : {
3746 : 3 : error ("%qD does not have %<const char *%> type", field);
3747 : 3 : return error_mark_node;
3748 : : }
3749 : 4010 : cnt++;
3750 : 4010 : continue;
3751 : : }
3752 : 4001 : else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0)
3753 : : {
3754 : 3998 : if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
3755 : : {
3756 : 3 : error ("%qD does not have integral type", field);
3757 : 3 : return error_mark_node;
3758 : : }
3759 : 3995 : cnt++;
3760 : 3995 : continue;
3761 : : }
3762 : : }
3763 : : cnt = 0;
3764 : : break;
3765 : : }
3766 : 2002 : if (cnt != 4)
3767 : : {
3768 : 9 : error ("%<std::source_location::__impl%> does not contain only "
3769 : : "non-static data members %<_M_file_name%>, "
3770 : : "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
3771 : 9 : return error_mark_node;
3772 : : }
3773 : 1996 : return build_qualified_type (type, TYPE_QUAL_CONST);
3774 : : }
3775 : :
3776 : : /* Type for source_location_table hash_set. */
3777 : : struct GTY((for_user)) source_location_table_entry {
3778 : : location_t loc;
3779 : : unsigned uid;
3780 : : tree var;
3781 : : };
3782 : :
3783 : : /* Traits class for function start hash maps below. */
3784 : :
3785 : : struct source_location_table_entry_hash
3786 : : : ggc_remove <source_location_table_entry>
3787 : : {
3788 : : typedef source_location_table_entry value_type;
3789 : : typedef source_location_table_entry compare_type;
3790 : :
3791 : : static hashval_t
3792 : 581 : hash (const source_location_table_entry &ref)
3793 : : {
3794 : 581 : inchash::hash hstate (0);
3795 : 581 : hstate.add_int (ref.loc);
3796 : 581 : hstate.add_int (ref.uid);
3797 : 581 : return hstate.end ();
3798 : : }
3799 : :
3800 : : static bool
3801 : 384 : equal (const source_location_table_entry &ref1,
3802 : : const source_location_table_entry &ref2)
3803 : : {
3804 : 384 : return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
3805 : : }
3806 : :
3807 : : static void
3808 : : mark_deleted (source_location_table_entry &ref)
3809 : : {
3810 : : ref.loc = UNKNOWN_LOCATION;
3811 : : ref.uid = -1U;
3812 : : ref.var = NULL_TREE;
3813 : : }
3814 : :
3815 : : static const bool empty_zero_p = true;
3816 : :
3817 : : static void
3818 : 0 : mark_empty (source_location_table_entry &ref)
3819 : : {
3820 : 0 : ref.loc = UNKNOWN_LOCATION;
3821 : 0 : ref.uid = 0;
3822 : 0 : ref.var = NULL_TREE;
3823 : : }
3824 : :
3825 : : static bool
3826 : 416 : is_deleted (const source_location_table_entry &ref)
3827 : : {
3828 : 416 : return (ref.loc == UNKNOWN_LOCATION
3829 : : && ref.uid == -1U
3830 : 416 : && ref.var == NULL_TREE);
3831 : : }
3832 : :
3833 : : static bool
3834 : 6686 : is_empty (const source_location_table_entry &ref)
3835 : : {
3836 : 6686 : return (ref.loc == UNKNOWN_LOCATION
3837 : 6686 : && ref.uid == 0
3838 : 6686 : && ref.var == NULL_TREE);
3839 : : }
3840 : :
3841 : : static void
3842 : 3 : pch_nx (source_location_table_entry &p)
3843 : : {
3844 : 3 : extern void gt_pch_nx (source_location_table_entry &);
3845 : 3 : gt_pch_nx (p);
3846 : 3 : }
3847 : :
3848 : : static void
3849 : 3 : pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
3850 : : {
3851 : 3 : extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
3852 : : void *);
3853 : 3 : gt_pch_nx (&p, op, cookie);
3854 : 3 : }
3855 : : };
3856 : :
3857 : : static GTY(()) hash_table <source_location_table_entry_hash>
3858 : : *source_location_table;
3859 : : static GTY(()) unsigned int source_location_id;
3860 : :
3861 : : /* Fold the __builtin_source_location () call T. */
3862 : :
3863 : : tree
3864 : 427 : fold_builtin_source_location (const_tree t)
3865 : : {
3866 : 427 : gcc_assert (TREE_CODE (t) == CALL_EXPR);
3867 : : /* TREE_TYPE (t) is const std::source_location::__impl* */
3868 : 427 : tree source_location_impl = TREE_TYPE (TREE_TYPE (t));
3869 : 427 : if (source_location_impl == error_mark_node)
3870 : 0 : return build_zero_cst (const_ptr_type_node);
3871 : 427 : gcc_assert (CLASS_TYPE_P (source_location_impl)
3872 : : && id_equal (TYPE_IDENTIFIER (source_location_impl), "__impl"));
3873 : :
3874 : 427 : location_t loc = EXPR_LOCATION (t);
3875 : 427 : if (source_location_table == NULL)
3876 : 40 : source_location_table
3877 : 40 : = hash_table <source_location_table_entry_hash>::create_ggc (64);
3878 : 427 : const line_map_ordinary *map;
3879 : 427 : source_location_table_entry entry;
3880 : 427 : entry.loc
3881 : 427 : = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
3882 : : &map);
3883 : 427 : entry.uid = current_function_decl ? DECL_UID (current_function_decl) : -1;
3884 : 427 : entry.var = error_mark_node;
3885 : 427 : source_location_table_entry *entryp
3886 : 427 : = source_location_table->find_slot (entry, INSERT);
3887 : 427 : tree var;
3888 : 427 : if (entryp->var)
3889 : : var = entryp->var;
3890 : : else
3891 : : {
3892 : 212 : char tmp_name[32];
3893 : 212 : ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lsrc_loc", source_location_id++);
3894 : 212 : var = build_decl (loc, VAR_DECL, get_identifier (tmp_name),
3895 : : source_location_impl);
3896 : 212 : TREE_STATIC (var) = 1;
3897 : 212 : TREE_PUBLIC (var) = 0;
3898 : 212 : DECL_ARTIFICIAL (var) = 1;
3899 : 212 : DECL_IGNORED_P (var) = 1;
3900 : 212 : DECL_EXTERNAL (var) = 0;
3901 : 212 : DECL_DECLARED_CONSTEXPR_P (var) = 1;
3902 : 212 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
3903 : 212 : layout_decl (var, 0);
3904 : :
3905 : 212 : vec<constructor_elt, va_gc> *v = NULL;
3906 : 212 : vec_alloc (v, 4);
3907 : 212 : for (tree field = TYPE_FIELDS (source_location_impl);
3908 : 1060 : (field = next_aggregate_field (field)) != NULL_TREE;
3909 : 848 : field = DECL_CHAIN (field))
3910 : : {
3911 : 848 : const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
3912 : 848 : tree val = NULL_TREE;
3913 : 848 : if (strcmp (n, "_M_file_name") == 0)
3914 : : {
3915 : 212 : if (const char *fname = LOCATION_FILE (loc))
3916 : : {
3917 : 211 : fname = remap_macro_filename (fname);
3918 : 211 : val = build_string_literal (fname);
3919 : : }
3920 : : else
3921 : 1 : val = build_string_literal ("");
3922 : : }
3923 : 636 : else if (strcmp (n, "_M_function_name") == 0)
3924 : : {
3925 : 212 : const char *name = "";
3926 : :
3927 : 212 : if (current_function_decl)
3928 : : {
3929 : : /* If this is a coroutine, we should get the name of the user
3930 : : function rather than the actor we generate. */
3931 : 167 : if (tree ramp = DECL_RAMP_FN (current_function_decl))
3932 : 3 : name = cxx_printable_name (ramp, 2);
3933 : : else
3934 : 164 : name = cxx_printable_name (current_function_decl, 2);
3935 : : }
3936 : :
3937 : 212 : val = build_string_literal (name);
3938 : : }
3939 : 424 : else if (strcmp (n, "_M_line") == 0)
3940 : 212 : val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
3941 : 212 : else if (strcmp (n, "_M_column") == 0)
3942 : 212 : val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
3943 : : else
3944 : 0 : gcc_unreachable ();
3945 : 848 : CONSTRUCTOR_APPEND_ELT (v, field, val);
3946 : : }
3947 : :
3948 : 212 : tree ctor = build_constructor (source_location_impl, v);
3949 : 212 : TREE_CONSTANT (ctor) = 1;
3950 : 212 : TREE_STATIC (ctor) = 1;
3951 : 212 : DECL_INITIAL (var) = ctor;
3952 : 212 : varpool_node::finalize_decl (var);
3953 : 212 : *entryp = entry;
3954 : 212 : entryp->var = var;
3955 : : }
3956 : :
3957 : 427 : return build_fold_addr_expr_with_type_loc (loc, var, TREE_TYPE (t));
3958 : : }
3959 : :
3960 : : #include "gt-cp-cp-gimplify.h"
|