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