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