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