1 /* C++-specific tree lowering bits; see also c-gimplify.cc and gimple.cc.
3 Copyright (C) 2002-2022 Free Software Foundation, Inc.
4 Contributed by Jason Merrill <jason@redhat.com>
6 This file is part of GCC.
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
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
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/>. */
24 #include "coretypes.h"
26 #include "basic-block.h"
30 #include "stor-layout.h"
31 #include "tree-iterator.h"
33 #include "c-family/c-ubsan.h"
34 #include "stringpool.h"
37 #include "gcc-rich-location.h"
41 #include "file-prefix-map.h"
43 #include "omp-general.h"
46 /* Forward declarations. */
48 static tree
cp_genericize_r (tree
*, int *, void *);
49 static tree
cp_fold_r (tree
*, int *, void *);
50 static void cp_genericize_tree (tree
*, bool);
51 static tree
cp_fold (tree
);
53 /* Genericize a TRY_BLOCK. */
56 genericize_try_block (tree
*stmt_p
)
58 tree body
= TRY_STMTS (*stmt_p
);
59 tree cleanup
= TRY_HANDLERS (*stmt_p
);
61 *stmt_p
= build2 (TRY_CATCH_EXPR
, void_type_node
, body
, cleanup
);
64 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
67 genericize_catch_block (tree
*stmt_p
)
69 tree type
= HANDLER_TYPE (*stmt_p
);
70 tree body
= HANDLER_BODY (*stmt_p
);
72 /* FIXME should the caught type go in TREE_TYPE? */
73 *stmt_p
= build2 (CATCH_EXPR
, void_type_node
, type
, body
);
76 /* A terser interface for building a representation of an exception
80 build_gimple_eh_filter_tree (tree body
, tree allowed
, tree failure
)
84 /* FIXME should the allowed types go in TREE_TYPE? */
85 t
= build2 (EH_FILTER_EXPR
, void_type_node
, allowed
, NULL_TREE
);
86 append_to_statement_list (failure
, &EH_FILTER_FAILURE (t
));
88 t
= build2 (TRY_CATCH_EXPR
, void_type_node
, NULL_TREE
, t
);
89 append_to_statement_list (body
, &TREE_OPERAND (t
, 0));
94 /* Genericize an EH_SPEC_BLOCK by converting it to a
95 TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
98 genericize_eh_spec_block (tree
*stmt_p
)
100 tree body
= EH_SPEC_STMTS (*stmt_p
);
101 tree allowed
= EH_SPEC_RAISES (*stmt_p
);
102 tree failure
= build_call_n (call_unexpected_fn
, 1, build_exc_ptr ());
104 *stmt_p
= build_gimple_eh_filter_tree (body
, allowed
, failure
);
105 suppress_warning (*stmt_p
);
106 suppress_warning (TREE_OPERAND (*stmt_p
, 1));
109 /* Return the first non-compound statement in STMT. */
112 first_stmt (tree stmt
)
114 switch (TREE_CODE (stmt
))
117 if (tree_statement_list_node
*p
= STATEMENT_LIST_HEAD (stmt
))
118 return first_stmt (p
->stmt
);
122 return first_stmt (BIND_EXPR_BODY (stmt
));
129 /* Genericize an IF_STMT by turning it into a COND_EXPR. */
132 genericize_if_stmt (tree
*stmt_p
)
134 tree stmt
, cond
, then_
, else_
;
135 location_t locus
= EXPR_LOCATION (*stmt_p
);
138 cond
= IF_COND (stmt
);
139 then_
= THEN_CLAUSE (stmt
);
140 else_
= ELSE_CLAUSE (stmt
);
144 tree ft
= first_stmt (then_
);
145 tree fe
= first_stmt (else_
);
147 if (TREE_CODE (ft
) == PREDICT_EXPR
148 && TREE_CODE (fe
) == PREDICT_EXPR
149 && (pr
= PREDICT_EXPR_PREDICTOR (ft
)) == PREDICT_EXPR_PREDICTOR (fe
)
150 && (pr
== PRED_HOT_LABEL
|| pr
== PRED_COLD_LABEL
))
152 gcc_rich_location
richloc (EXPR_LOC_OR_LOC (ft
, locus
));
153 richloc
.add_range (EXPR_LOC_OR_LOC (fe
, locus
));
154 warning_at (&richloc
, OPT_Wattributes
,
155 "both branches of %<if%> statement marked as %qs",
156 pr
== PRED_HOT_LABEL
? "likely" : "unlikely");
161 then_
= build_empty_stmt (locus
);
163 else_
= build_empty_stmt (locus
);
165 /* consteval if has been verified not to have the then_/else_ blocks
166 entered by gotos/case labels from elsewhere, and as then_ block
167 can contain unfolded immediate function calls, we have to discard
168 the then_ block regardless of whether else_ has side-effects or not. */
169 if (IF_STMT_CONSTEVAL_P (stmt
))
171 if (block_may_fallthru (then_
))
172 stmt
= build3 (COND_EXPR
, void_type_node
, boolean_false_node
,
177 else if (IF_STMT_CONSTEXPR_P (stmt
))
178 stmt
= integer_nonzerop (cond
) ? then_
: else_
;
180 stmt
= build3 (COND_EXPR
, void_type_node
, cond
, then_
, else_
);
181 protected_set_expr_location_if_unset (stmt
, locus
);
185 /* Hook into the middle of gimplifying an OMP_FOR node. */
187 static enum gimplify_status
188 cp_gimplify_omp_for (tree
*expr_p
, gimple_seq
*pre_p
)
190 tree for_stmt
= *expr_p
;
191 gimple_seq seq
= NULL
;
193 /* Protect ourselves from recursion. */
194 if (OMP_FOR_GIMPLIFYING_P (for_stmt
))
196 OMP_FOR_GIMPLIFYING_P (for_stmt
) = 1;
198 gimplify_and_add (for_stmt
, &seq
);
199 gimple_seq_add_seq (pre_p
, seq
);
201 OMP_FOR_GIMPLIFYING_P (for_stmt
) = 0;
206 /* Gimplify an EXPR_STMT node. */
209 gimplify_expr_stmt (tree
*stmt_p
)
211 tree stmt
= EXPR_STMT_EXPR (*stmt_p
);
213 if (stmt
== error_mark_node
)
216 /* Gimplification of a statement expression will nullify the
217 statement if all its side effects are moved to *PRE_P and *POST_P.
219 In this case we will not want to emit the gimplified statement.
220 However, we may still want to emit a warning, so we do that before
222 if (stmt
&& warn_unused_value
)
224 if (!TREE_SIDE_EFFECTS (stmt
))
226 if (!IS_EMPTY_STMT (stmt
)
227 && !VOID_TYPE_P (TREE_TYPE (stmt
))
228 && !warning_suppressed_p (stmt
, OPT_Wunused_value
))
229 warning (OPT_Wunused_value
, "statement with no effect");
232 warn_if_unused_value (stmt
, input_location
);
235 if (stmt
== NULL_TREE
)
236 stmt
= alloc_stmt_list ();
241 /* Gimplify initialization from an AGGR_INIT_EXPR. */
244 cp_gimplify_init_expr (tree
*expr_p
)
246 tree from
= TREE_OPERAND (*expr_p
, 1);
247 tree to
= TREE_OPERAND (*expr_p
, 0);
250 if (TREE_CODE (from
) == TARGET_EXPR
)
251 if (tree init
= TARGET_EXPR_INITIAL (from
))
253 if (target_expr_needs_replace (from
))
255 /* If this was changed by cp_genericize_target_expr, we need to
256 walk into it to replace uses of the slot. */
257 replace_decl (&init
, TARGET_EXPR_SLOT (from
), to
);
265 /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
266 inside the TARGET_EXPR. */
269 tree sub
= TREE_CODE (t
) == COMPOUND_EXPR
? TREE_OPERAND (t
, 0) : t
;
271 /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
272 replace the slot operand with our target.
274 Should we add a target parm to gimplify_expr instead? No, as in this
275 case we want to replace the INIT_EXPR. */
276 if (TREE_CODE (sub
) == AGGR_INIT_EXPR
277 || TREE_CODE (sub
) == VEC_INIT_EXPR
)
279 if (TREE_CODE (sub
) == AGGR_INIT_EXPR
)
280 AGGR_INIT_EXPR_SLOT (sub
) = to
;
282 VEC_INIT_EXPR_SLOT (sub
) = to
;
285 /* The initialization is now a side-effect, so the container can
288 TREE_TYPE (from
) = void_type_node
;
291 /* Handle aggregate NSDMI. */
292 replace_placeholders (sub
, to
);
297 t
= TREE_OPERAND (t
, 1);
302 /* Gimplify a MUST_NOT_THROW_EXPR. */
304 static enum gimplify_status
305 gimplify_must_not_throw_expr (tree
*expr_p
, gimple_seq
*pre_p
)
308 tree temp
= voidify_wrapper_expr (stmt
, NULL
);
309 tree body
= TREE_OPERAND (stmt
, 0);
310 gimple_seq try_
= NULL
;
311 gimple_seq catch_
= NULL
;
314 gimplify_and_add (body
, &try_
);
315 mnt
= gimple_build_eh_must_not_throw (terminate_fn
);
316 gimple_seq_add_stmt_without_update (&catch_
, mnt
);
317 mnt
= gimple_build_try (try_
, catch_
, GIMPLE_TRY_CATCH
);
319 gimple_seq_add_stmt_without_update (pre_p
, mnt
);
330 /* Return TRUE if an operand (OP) of a given TYPE being copied is
331 really just an empty class copy.
333 Check that the operand has a simple form so that TARGET_EXPRs and
334 non-empty CONSTRUCTORs get reduced properly, and we leave the
335 return slot optimization alone because it isn't a copy. */
338 simple_empty_class_p (tree type
, tree op
, tree_code code
)
340 if (TREE_CODE (op
) == COMPOUND_EXPR
)
341 return simple_empty_class_p (type
, TREE_OPERAND (op
, 1), code
);
342 if (SIMPLE_TARGET_EXPR_P (op
)
343 && TYPE_HAS_TRIVIAL_DESTRUCTOR (type
))
344 /* The TARGET_EXPR is itself a simple copy, look through it. */
345 return simple_empty_class_p (type
, TARGET_EXPR_INITIAL (op
), code
);
347 if (TREE_CODE (op
) == PARM_DECL
348 && TREE_ADDRESSABLE (TREE_TYPE (op
)))
350 tree fn
= DECL_CONTEXT (op
);
351 if (DECL_THUNK_P (fn
)
352 || lambda_static_thunk_p (fn
))
353 /* In a thunk, we pass through invisible reference parms, so this isn't
359 (TREE_CODE (op
) == EMPTY_CLASS_EXPR
360 || code
== MODIFY_EXPR
361 || is_gimple_lvalue (op
)
362 || INDIRECT_REF_P (op
)
363 || (TREE_CODE (op
) == CONSTRUCTOR
364 && CONSTRUCTOR_NELTS (op
) == 0)
365 || (TREE_CODE (op
) == CALL_EXPR
366 && !CALL_EXPR_RETURN_SLOT_OPT (op
)))
367 && !TREE_CLOBBER_P (op
)
368 && is_really_empty_class (type
, /*ignore_vptr*/true);
371 /* Returns true if evaluating E as an lvalue has side-effects;
372 specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
373 have side-effects until there is a read or write through it. */
376 lvalue_has_side_effects (tree e
)
378 if (!TREE_SIDE_EFFECTS (e
))
380 while (handled_component_p (e
))
382 if (TREE_CODE (e
) == ARRAY_REF
383 && TREE_SIDE_EFFECTS (TREE_OPERAND (e
, 1)))
385 e
= TREE_OPERAND (e
, 0);
388 /* Just naming a variable has no side-effects. */
390 else if (INDIRECT_REF_P (e
))
391 /* Similarly, indirection has no side-effects. */
392 return TREE_SIDE_EFFECTS (TREE_OPERAND (e
, 0));
394 /* For anything else, trust TREE_SIDE_EFFECTS. */
395 return TREE_SIDE_EFFECTS (e
);
398 /* Gimplify *EXPR_P as rvalue into an expression that can't be modified
399 by expressions with side-effects in other operands. */
401 static enum gimplify_status
402 gimplify_to_rvalue (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
,
403 bool (*gimple_test_f
) (tree
))
405 enum gimplify_status t
406 = gimplify_expr (expr_p
, pre_p
, post_p
, gimple_test_f
, fb_rvalue
);
409 else if (is_gimple_variable (*expr_p
) && TREE_CODE (*expr_p
) != SSA_NAME
)
410 *expr_p
= get_initialized_tmp_var (*expr_p
, pre_p
);
414 /* Like gimplify_arg, but if ORDERED is set (which should be set if
415 any of the arguments this argument is sequenced before has
416 TREE_SIDE_EFFECTS set, make sure expressions with is_gimple_reg_type type
417 are gimplified into SSA_NAME or a fresh temporary and for
418 non-is_gimple_reg_type we don't optimize away TARGET_EXPRs. */
420 static enum gimplify_status
421 cp_gimplify_arg (tree
*arg_p
, gimple_seq
*pre_p
, location_t call_location
,
424 enum gimplify_status t
;
426 && !is_gimple_reg_type (TREE_TYPE (*arg_p
))
427 && TREE_CODE (*arg_p
) == TARGET_EXPR
)
429 /* gimplify_arg would strip away the TARGET_EXPR, but
430 that can mean we don't copy the argument and some following
431 argument with side-effect could modify it. */
432 protected_set_expr_location (*arg_p
, call_location
);
433 return gimplify_expr (arg_p
, pre_p
, NULL
, is_gimple_lvalue
, fb_either
);
437 t
= gimplify_arg (arg_p
, pre_p
, call_location
);
441 && is_gimple_reg_type (TREE_TYPE (*arg_p
))
442 && is_gimple_variable (*arg_p
)
443 && TREE_CODE (*arg_p
) != SSA_NAME
444 /* No need to force references into register, references
445 can't be modified. */
446 && !TYPE_REF_P (TREE_TYPE (*arg_p
))
447 /* And this can't be modified either. */
448 && *arg_p
!= current_class_ptr
)
449 *arg_p
= get_initialized_tmp_var (*arg_p
, pre_p
);
455 /* Do C++-specific gimplification. Args are as for gimplify_expr. */
458 cp_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
460 int saved_stmts_are_full_exprs_p
= 0;
461 location_t loc
= cp_expr_loc_or_input_loc (*expr_p
);
462 enum tree_code code
= TREE_CODE (*expr_p
);
463 enum gimplify_status ret
;
465 if (STATEMENT_CODE_P (code
))
467 saved_stmts_are_full_exprs_p
= stmts_are_full_exprs_p ();
468 current_stmt_tree ()->stmts_are_full_exprs_p
469 = STMT_IS_FULL_EXPR_P (*expr_p
);
475 simplify_aggr_init_expr (expr_p
);
481 *expr_p
= expand_vec_init_expr (NULL_TREE
, *expr_p
,
482 tf_warning_or_error
);
485 cp_walk_tree (expr_p
, cp_fold_r
, &pset
, NULL
);
486 cp_genericize_tree (expr_p
, false);
487 copy_if_shared (expr_p
);
493 /* FIXME communicate throw type to back end, probably by moving
494 THROW_EXPR into ../tree.def. */
495 *expr_p
= TREE_OPERAND (*expr_p
, 0);
499 case MUST_NOT_THROW_EXPR
:
500 ret
= gimplify_must_not_throw_expr (expr_p
, pre_p
);
503 /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
504 LHS of an assignment might also be involved in the RHS, as in bug
507 cp_gimplify_init_expr (expr_p
);
508 if (TREE_CODE (*expr_p
) != INIT_EXPR
)
514 /* If the back end isn't clever enough to know that the lhs and rhs
515 types are the same, add an explicit conversion. */
516 tree op0
= TREE_OPERAND (*expr_p
, 0);
517 tree op1
= TREE_OPERAND (*expr_p
, 1);
519 if (!error_operand_p (op0
)
520 && !error_operand_p (op1
)
521 && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0
))
522 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1
)))
523 && !useless_type_conversion_p (TREE_TYPE (op1
), TREE_TYPE (op0
)))
524 TREE_OPERAND (*expr_p
, 1) = build1 (VIEW_CONVERT_EXPR
,
525 TREE_TYPE (op0
), op1
);
527 else if (simple_empty_class_p (TREE_TYPE (op0
), op1
, code
))
529 while (TREE_CODE (op1
) == TARGET_EXPR
)
530 /* We're disconnecting the initializer from its target,
531 don't create a temporary. */
532 op1
= TARGET_EXPR_INITIAL (op1
);
534 /* Remove any copies of empty classes. Also drop volatile
535 variables on the RHS to avoid infinite recursion from
536 gimplify_expr trying to load the value. */
537 if (TREE_SIDE_EFFECTS (op1
))
539 if (TREE_THIS_VOLATILE (op1
)
540 && (REFERENCE_CLASS_P (op1
) || DECL_P (op1
)))
541 op1
= build_fold_addr_expr (op1
);
543 gimplify_and_add (op1
, pre_p
);
545 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
546 is_gimple_lvalue
, fb_lvalue
);
547 *expr_p
= TREE_OPERAND (*expr_p
, 0);
548 if (code
== RETURN_EXPR
&& REFERENCE_CLASS_P (*expr_p
))
549 /* Avoid 'return *<retval>;' */
550 *expr_p
= TREE_OPERAND (*expr_p
, 0);
552 /* P0145 says that the RHS is sequenced before the LHS.
553 gimplify_modify_expr gimplifies the RHS before the LHS, but that
554 isn't quite strong enough in two cases:
556 1) gimplify.cc wants to leave a CALL_EXPR on the RHS, which would
557 mean it's evaluated after the LHS.
559 2) the value calculation of the RHS is also sequenced before the
560 LHS, so for scalar assignment we need to preevaluate if the
561 RHS could be affected by LHS side-effects even if it has no
562 side-effects of its own. We don't need this for classes because
563 class assignment takes its RHS by reference. */
564 else if (flag_strong_eval_order
> 1
565 && TREE_CODE (*expr_p
) == MODIFY_EXPR
566 && lvalue_has_side_effects (op0
)
567 && (TREE_CODE (op1
) == CALL_EXPR
568 || (SCALAR_TYPE_P (TREE_TYPE (op1
))
569 && !TREE_CONSTANT (op1
))))
570 TREE_OPERAND (*expr_p
, 1) = get_initialized_tmp_var (op1
, pre_p
);
575 case EMPTY_CLASS_EXPR
:
576 /* We create an empty CONSTRUCTOR with RECORD_TYPE. */
577 *expr_p
= build_constructor (TREE_TYPE (*expr_p
), NULL
);
582 *expr_p
= BASELINK_FUNCTIONS (*expr_p
);
587 genericize_try_block (expr_p
);
592 genericize_catch_block (expr_p
);
597 genericize_eh_spec_block (expr_p
);
617 ret
= cp_gimplify_omp_for (expr_p
, pre_p
);
621 gimplify_expr_stmt (expr_p
);
625 case UNARY_PLUS_EXPR
:
627 tree arg
= TREE_OPERAND (*expr_p
, 0);
628 tree type
= TREE_TYPE (*expr_p
);
629 *expr_p
= (TREE_TYPE (arg
) != type
) ? fold_convert (type
, arg
)
637 if (flag_strong_eval_order
== 2
638 && CALL_EXPR_FN (*expr_p
)
639 && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p
)
640 && cp_get_callee_fndecl_nofold (*expr_p
) == NULL_TREE
)
642 tree fnptrtype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
643 enum gimplify_status t
644 = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p
), pre_p
, NULL
,
645 is_gimple_call_addr
);
648 /* GIMPLE considers most pointer conversion useless, but for
649 calls we actually care about the exact function pointer type. */
650 else if (TREE_TYPE (CALL_EXPR_FN (*expr_p
)) != fnptrtype
)
651 CALL_EXPR_FN (*expr_p
)
652 = build1 (NOP_EXPR
, fnptrtype
, CALL_EXPR_FN (*expr_p
));
654 if (!CALL_EXPR_FN (*expr_p
))
655 /* Internal function call. */;
656 else if (CALL_EXPR_REVERSE_ARGS (*expr_p
))
658 /* This is a call to a (compound) assignment operator that used
659 the operator syntax; gimplify the RHS first. */
660 gcc_assert (call_expr_nargs (*expr_p
) == 2);
661 gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p
));
662 enum gimplify_status t
663 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p
, 1), pre_p
, loc
,
664 TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p
, 0)));
668 else if (CALL_EXPR_ORDERED_ARGS (*expr_p
))
670 /* Leave the last argument for gimplify_call_expr, to avoid problems
671 with __builtin_va_arg_pack(). */
672 int nargs
= call_expr_nargs (*expr_p
) - 1;
673 int last_side_effects_arg
= -1;
674 for (int i
= nargs
; i
> 0; --i
)
675 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p
, i
)))
677 last_side_effects_arg
= i
;
680 for (int i
= 0; i
< nargs
; ++i
)
682 enum gimplify_status t
683 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p
, i
), pre_p
, loc
,
684 i
< last_side_effects_arg
);
689 else if (flag_strong_eval_order
690 && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p
))
692 /* If flag_strong_eval_order, evaluate the object argument first. */
693 tree fntype
= TREE_TYPE (CALL_EXPR_FN (*expr_p
));
694 if (INDIRECT_TYPE_P (fntype
))
695 fntype
= TREE_TYPE (fntype
);
696 if (TREE_CODE (fntype
) == METHOD_TYPE
)
698 int nargs
= call_expr_nargs (*expr_p
);
699 bool side_effects
= false;
700 for (int i
= 1; i
< nargs
; ++i
)
701 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p
, i
)))
706 enum gimplify_status t
707 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p
, 0), pre_p
, loc
,
715 tree decl
= cp_get_callee_fndecl_nofold (*expr_p
);
716 if (decl
&& fndecl_built_in_p (decl
, BUILT_IN_FRONTEND
))
717 switch (DECL_FE_FUNCTION_CODE (decl
))
719 case CP_BUILT_IN_IS_CONSTANT_EVALUATED
:
720 *expr_p
= boolean_false_node
;
722 case CP_BUILT_IN_SOURCE_LOCATION
:
724 = fold_builtin_source_location (EXPR_LOCATION (*expr_p
));
726 case CP_BUILT_IN_IS_CORRESPONDING_MEMBER
:
728 = fold_builtin_is_corresponding_member
729 (EXPR_LOCATION (*expr_p
), call_expr_nargs (*expr_p
),
730 &CALL_EXPR_ARG (*expr_p
, 0));
732 case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS
:
734 = fold_builtin_is_pointer_inverconvertible_with_class
735 (EXPR_LOCATION (*expr_p
), call_expr_nargs (*expr_p
),
736 &CALL_EXPR_ARG (*expr_p
, 0));
745 /* A TARGET_EXPR that expresses direct-initialization should have been
746 elided by cp_gimplify_init_expr. */
747 gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p
));
752 *expr_p
= cplus_expand_constant (*expr_p
);
753 if (TREE_CODE (*expr_p
) == PTRMEM_CST
)
760 if (TREE_OPERAND (*expr_p
, 0)
761 && (TREE_CODE (TREE_OPERAND (*expr_p
, 0)) == INIT_EXPR
762 || TREE_CODE (TREE_OPERAND (*expr_p
, 0)) == MODIFY_EXPR
))
764 expr_p
= &TREE_OPERAND (*expr_p
, 0);
765 /* Avoid going through the INIT_EXPR case, which can
766 degrade INIT_EXPRs into AGGR_INIT_EXPRs. */
767 goto modify_expr_case
;
772 ret
= (enum gimplify_status
) c_gimplify_expr (expr_p
, pre_p
, post_p
);
776 /* Restore saved state. */
777 if (STATEMENT_CODE_P (code
))
778 current_stmt_tree ()->stmts_are_full_exprs_p
779 = saved_stmts_are_full_exprs_p
;
785 is_invisiref_parm (const_tree t
)
787 return ((TREE_CODE (t
) == PARM_DECL
|| TREE_CODE (t
) == RESULT_DECL
)
788 && DECL_BY_REFERENCE (t
));
791 /* A stable comparison routine for use with splay trees and DECLs. */
794 splay_tree_compare_decl_uid (splay_tree_key xa
, splay_tree_key xb
)
799 return DECL_UID (a
) - DECL_UID (b
);
802 /* OpenMP context during genericization. */
804 struct cp_genericize_omp_taskreg
808 struct cp_genericize_omp_taskreg
*outer
;
809 splay_tree variables
;
812 /* Return true if genericization should try to determine if
813 DECL is firstprivate or shared within task regions. */
816 omp_var_to_track (tree decl
)
818 tree type
= TREE_TYPE (decl
);
819 if (is_invisiref_parm (decl
))
820 type
= TREE_TYPE (type
);
821 else if (TYPE_REF_P (type
))
822 type
= TREE_TYPE (type
);
823 while (TREE_CODE (type
) == ARRAY_TYPE
)
824 type
= TREE_TYPE (type
);
825 if (type
== error_mark_node
|| !CLASS_TYPE_P (type
))
827 if (VAR_P (decl
) && CP_DECL_THREAD_LOCAL_P (decl
))
829 if (cxx_omp_predetermined_sharing (decl
) != OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
834 /* Note DECL use in OpenMP region OMP_CTX during genericization. */
837 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg
*omp_ctx
, tree decl
)
839 splay_tree_node n
= splay_tree_lookup (omp_ctx
->variables
,
840 (splay_tree_key
) decl
);
843 int flags
= OMP_CLAUSE_DEFAULT_SHARED
;
845 omp_cxx_notice_variable (omp_ctx
->outer
, decl
);
846 if (!omp_ctx
->default_shared
)
848 struct cp_genericize_omp_taskreg
*octx
;
850 for (octx
= omp_ctx
->outer
; octx
; octx
= octx
->outer
)
852 n
= splay_tree_lookup (octx
->variables
, (splay_tree_key
) decl
);
853 if (n
&& n
->value
!= OMP_CLAUSE_DEFAULT_SHARED
)
855 flags
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
858 if (octx
->is_parallel
)
862 && (TREE_CODE (decl
) == PARM_DECL
863 || (!(TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
864 && DECL_CONTEXT (decl
) == current_function_decl
)))
865 flags
= OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
866 if (flags
== OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
)
868 /* DECL is implicitly determined firstprivate in
869 the current task construct. Ensure copy ctor and
870 dtor are instantiated, because during gimplification
871 it will be already too late. */
872 tree type
= TREE_TYPE (decl
);
873 if (is_invisiref_parm (decl
))
874 type
= TREE_TYPE (type
);
875 else if (TYPE_REF_P (type
))
876 type
= TREE_TYPE (type
);
877 while (TREE_CODE (type
) == ARRAY_TYPE
)
878 type
= TREE_TYPE (type
);
879 get_copy_ctor (type
, tf_none
);
880 get_dtor (type
, tf_none
);
883 splay_tree_insert (omp_ctx
->variables
, (splay_tree_key
) decl
, flags
);
887 /* If we might need to clean up a partially constructed object, break down the
888 CONSTRUCTOR with split_nonconstant_init. Also expand VEC_INIT_EXPR at this
889 point. If initializing TO with FROM is non-trivial, overwrite *REPLACE with
893 cp_genericize_init (tree
*replace
, tree from
, tree to
)
895 if (TREE_CODE (from
) == VEC_INIT_EXPR
)
897 tree init
= expand_vec_init_expr (to
, from
, tf_warning_or_error
);
899 /* Make cp_gimplify_init_expr call replace_decl. */
900 *replace
= fold_convert (void_type_node
, init
);
902 else if (flag_exceptions
903 && TREE_CODE (from
) == CONSTRUCTOR
904 && TREE_SIDE_EFFECTS (from
)
905 && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (from
)))
907 to
= cp_stabilize_reference (to
);
908 replace_placeholders (from
, to
);
909 *replace
= split_nonconstant_init (to
, from
);
913 /* For an INIT_EXPR, replace the INIT_EXPR itself. */
916 cp_genericize_init_expr (tree
*stmt_p
)
918 tree to
= TREE_OPERAND (*stmt_p
, 0);
919 tree from
= TREE_OPERAND (*stmt_p
, 1);
920 if (SIMPLE_TARGET_EXPR_P (from
)
921 /* Return gets confused if we clobber its INIT_EXPR this soon. */
922 && TREE_CODE (to
) != RESULT_DECL
)
923 from
= TARGET_EXPR_INITIAL (from
);
924 cp_genericize_init (stmt_p
, from
, to
);
927 /* For a TARGET_EXPR, change the TARGET_EXPR_INITIAL. We will need to use
928 replace_decl later when we know what we're initializing. */
931 cp_genericize_target_expr (tree
*stmt_p
)
933 tree slot
= TARGET_EXPR_SLOT (*stmt_p
);
934 cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p
),
935 TARGET_EXPR_INITIAL (*stmt_p
), slot
);
936 gcc_assert (!DECL_INITIAL (slot
));
939 /* Genericization context. */
941 struct cp_genericize_data
943 hash_set
<tree
> *p_set
;
944 auto_vec
<tree
> bind_expr_stack
;
945 struct cp_genericize_omp_taskreg
*omp_ctx
;
948 bool handle_invisiref_parm_p
;
951 /* Perform any pre-gimplification folding of C++ front end trees to
953 Note: The folding of non-omp cases is something to move into
954 the middle-end. As for now we have most foldings only on GENERIC
955 in fold-const, we need to perform this before transformation to
961 bool genericize
; // called from cp_fold_function?
963 cp_fold_data (bool g
): genericize (g
) {}
967 cp_fold_r (tree
*stmt_p
, int *walk_subtrees
, void *data_
)
969 cp_fold_data
*data
= (cp_fold_data
*)data_
;
971 enum tree_code code
= TREE_CODE (stmt
);
976 if (TREE_CODE (PTRMEM_CST_MEMBER (stmt
)) == FUNCTION_DECL
977 && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (stmt
)))
979 if (!data
->pset
.add (stmt
))
980 error_at (PTRMEM_CST_LOCATION (stmt
),
981 "taking address of an immediate function %qD",
982 PTRMEM_CST_MEMBER (stmt
));
983 stmt
= *stmt_p
= build_zero_cst (TREE_TYPE (stmt
));
989 if (TREE_CODE (TREE_OPERAND (stmt
, 0)) == FUNCTION_DECL
990 && DECL_IMMEDIATE_FUNCTION_P (TREE_OPERAND (stmt
, 0)))
992 error_at (EXPR_LOCATION (stmt
),
993 "taking address of an immediate function %qD",
994 TREE_OPERAND (stmt
, 0));
995 stmt
= *stmt_p
= build_zero_cst (TREE_TYPE (stmt
));
1001 if (tree fndecl
= cp_get_callee_fndecl_nofold (stmt
))
1002 if (DECL_IMMEDIATE_FUNCTION_P (fndecl
)
1003 && source_location_current_p (fndecl
))
1004 *stmt_p
= stmt
= cxx_constant_value (stmt
);
1011 *stmt_p
= stmt
= cp_fold (*stmt_p
);
1013 if (data
->pset
.add (stmt
))
1015 /* Don't walk subtrees of stmts we've already walked once, otherwise
1016 we can have exponential complexity with e.g. lots of nested
1017 SAVE_EXPRs or TARGET_EXPRs. cp_fold uses a cache and will return
1018 always the same tree, which the first time cp_fold_r has been
1019 called on it had the subtrees walked. */
1024 code
= TREE_CODE (stmt
);
1031 case OMP_DISTRIBUTE
:
1035 cp_walk_tree (&OMP_FOR_BODY (stmt
), cp_fold_r
, data
, NULL
);
1036 cp_walk_tree (&OMP_FOR_CLAUSES (stmt
), cp_fold_r
, data
, NULL
);
1037 cp_walk_tree (&OMP_FOR_INIT (stmt
), cp_fold_r
, data
, NULL
);
1038 x
= OMP_FOR_COND (stmt
);
1039 if (x
&& TREE_CODE_CLASS (TREE_CODE (x
)) == tcc_comparison
)
1041 cp_walk_tree (&TREE_OPERAND (x
, 0), cp_fold_r
, data
, NULL
);
1042 cp_walk_tree (&TREE_OPERAND (x
, 1), cp_fold_r
, data
, NULL
);
1044 else if (x
&& TREE_CODE (x
) == TREE_VEC
)
1046 n
= TREE_VEC_LENGTH (x
);
1047 for (i
= 0; i
< n
; i
++)
1049 tree o
= TREE_VEC_ELT (x
, i
);
1050 if (o
&& TREE_CODE_CLASS (TREE_CODE (o
)) == tcc_comparison
)
1051 cp_walk_tree (&TREE_OPERAND (o
, 1), cp_fold_r
, data
, NULL
);
1054 x
= OMP_FOR_INCR (stmt
);
1055 if (x
&& TREE_CODE (x
) == TREE_VEC
)
1057 n
= TREE_VEC_LENGTH (x
);
1058 for (i
= 0; i
< n
; i
++)
1060 tree o
= TREE_VEC_ELT (x
, i
);
1061 if (o
&& TREE_CODE (o
) == MODIFY_EXPR
)
1062 o
= TREE_OPERAND (o
, 1);
1063 if (o
&& (TREE_CODE (o
) == PLUS_EXPR
|| TREE_CODE (o
) == MINUS_EXPR
1064 || TREE_CODE (o
) == POINTER_PLUS_EXPR
))
1066 cp_walk_tree (&TREE_OPERAND (o
, 0), cp_fold_r
, data
, NULL
);
1067 cp_walk_tree (&TREE_OPERAND (o
, 1), cp_fold_r
, data
, NULL
);
1071 cp_walk_tree (&OMP_FOR_PRE_BODY (stmt
), cp_fold_r
, data
, NULL
);
1076 if (IF_STMT_CONSTEVAL_P (stmt
))
1078 /* Don't walk THEN_CLAUSE (stmt) for consteval if. IF_COND is always
1079 boolean_false_node. */
1080 cp_walk_tree (&ELSE_CLAUSE (stmt
), cp_fold_r
, data
, NULL
);
1081 cp_walk_tree (&IF_SCOPE (stmt
), cp_fold_r
, data
, NULL
);
1087 /* cp_genericize_{init,target}_expr are only for genericize time; they're
1088 here rather than in cp_genericize to avoid problems with the invisible
1089 reference transition. */
1091 if (data
->genericize
)
1092 cp_genericize_init_expr (stmt_p
);
1096 if (data
->genericize
)
1097 cp_genericize_target_expr (stmt_p
);
1099 /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in
1100 that case, use it in place of this one. */
1101 if (tree
&init
= TARGET_EXPR_INITIAL (stmt
))
1103 cp_walk_tree (&init
, cp_fold_r
, data
, NULL
);
1105 if (TREE_CODE (init
) == TARGET_EXPR
)
1117 /* Fold ALL the trees! FIXME we should be able to remove this, but
1118 apparently that still causes optimization regressions. */
1121 cp_fold_function (tree fndecl
)
1123 cp_fold_data
data (/*genericize*/true);
1124 cp_walk_tree (&DECL_SAVED_TREE (fndecl
), cp_fold_r
, &data
, NULL
);
1127 /* Turn SPACESHIP_EXPR EXPR into GENERIC. */
1129 static tree
genericize_spaceship (tree expr
)
1131 iloc_sentinel
s (cp_expr_location (expr
));
1132 tree type
= TREE_TYPE (expr
);
1133 tree op0
= TREE_OPERAND (expr
, 0);
1134 tree op1
= TREE_OPERAND (expr
, 1);
1135 return genericize_spaceship (input_location
, type
, op0
, op1
);
1138 /* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
1139 to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
1140 the middle-end (c++/88256). If EXPR is a DECL, use add_stmt and return
1141 NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR. */
1144 predeclare_vla (tree expr
)
1146 tree type
= TREE_TYPE (expr
);
1147 if (type
== error_mark_node
)
1149 if (is_typedef_decl (expr
))
1150 type
= DECL_ORIGINAL_TYPE (expr
);
1152 /* We need to strip pointers for gimplify_type_sizes. */
1154 while (POINTER_TYPE_P (vla
))
1156 if (TYPE_NAME (vla
))
1158 vla
= TREE_TYPE (vla
);
1160 if (vla
== type
|| TYPE_NAME (vla
)
1161 || !variably_modified_type_p (vla
, NULL_TREE
))
1164 tree decl
= build_decl (input_location
, TYPE_DECL
, NULL_TREE
, vla
);
1165 DECL_ARTIFICIAL (decl
) = 1;
1166 TYPE_NAME (vla
) = decl
;
1167 tree dexp
= build_stmt (input_location
, DECL_EXPR
, decl
);
1175 expr
= build2 (COMPOUND_EXPR
, type
, dexp
, expr
);
1180 /* Perform any pre-gimplification lowering of C++ front end trees to
1184 cp_genericize_r (tree
*stmt_p
, int *walk_subtrees
, void *data
)
1186 tree stmt
= *stmt_p
;
1187 struct cp_genericize_data
*wtd
= (struct cp_genericize_data
*) data
;
1188 hash_set
<tree
> *p_set
= wtd
->p_set
;
1190 /* If in an OpenMP context, note var uses. */
1191 if (UNLIKELY (wtd
->omp_ctx
!= NULL
)
1193 || TREE_CODE (stmt
) == PARM_DECL
1194 || TREE_CODE (stmt
) == RESULT_DECL
)
1195 && omp_var_to_track (stmt
))
1196 omp_cxx_notice_variable (wtd
->omp_ctx
, stmt
);
1198 /* Don't dereference parms in a thunk, pass the references through. */
1199 if ((TREE_CODE (stmt
) == CALL_EXPR
&& call_from_lambda_thunk_p (stmt
))
1200 || (TREE_CODE (stmt
) == AGGR_INIT_EXPR
&& AGGR_INIT_FROM_THUNK_P (stmt
)))
1206 /* Dereference invisible reference parms. */
1207 if (wtd
->handle_invisiref_parm_p
&& is_invisiref_parm (stmt
))
1209 *stmt_p
= convert_from_reference (stmt
);
1210 p_set
->add (*stmt_p
);
1215 /* Map block scope extern declarations to visible declarations with the
1216 same name and type in outer scopes if any. */
1217 if (VAR_OR_FUNCTION_DECL_P (stmt
) && DECL_LOCAL_DECL_P (stmt
))
1218 if (tree alias
= DECL_LOCAL_DECL_ALIAS (stmt
))
1220 if (alias
!= error_mark_node
)
1223 TREE_USED (alias
) |= TREE_USED (stmt
);
1229 if (TREE_CODE (stmt
) == INTEGER_CST
1230 && TYPE_REF_P (TREE_TYPE (stmt
))
1231 && (flag_sanitize
& (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1232 && !wtd
->no_sanitize_p
)
1234 ubsan_maybe_instrument_reference (stmt_p
);
1235 if (*stmt_p
!= stmt
)
1242 /* Other than invisiref parms, don't walk the same tree twice. */
1243 if (p_set
->contains (stmt
))
1249 switch (TREE_CODE (stmt
))
1252 if (is_invisiref_parm (TREE_OPERAND (stmt
, 0)))
1254 /* If in an OpenMP context, note var uses. */
1255 if (UNLIKELY (wtd
->omp_ctx
!= NULL
)
1256 && omp_var_to_track (TREE_OPERAND (stmt
, 0)))
1257 omp_cxx_notice_variable (wtd
->omp_ctx
, TREE_OPERAND (stmt
, 0));
1258 *stmt_p
= fold_convert (TREE_TYPE (stmt
), TREE_OPERAND (stmt
, 0));
1264 if (TREE_OPERAND (stmt
, 0) && is_invisiref_parm (TREE_OPERAND (stmt
, 0)))
1265 /* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR. */
1270 switch (OMP_CLAUSE_CODE (stmt
))
1272 case OMP_CLAUSE_LASTPRIVATE
:
1273 /* Don't dereference an invisiref in OpenMP clauses. */
1274 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
1277 if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt
))
1278 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt
),
1279 cp_genericize_r
, data
, NULL
);
1282 case OMP_CLAUSE_PRIVATE
:
1283 /* Don't dereference an invisiref in OpenMP clauses. */
1284 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
1286 else if (wtd
->omp_ctx
!= NULL
)
1288 /* Private clause doesn't cause any references to the
1289 var in outer contexts, avoid calling
1290 omp_cxx_notice_variable for it. */
1291 struct cp_genericize_omp_taskreg
*old
= wtd
->omp_ctx
;
1292 wtd
->omp_ctx
= NULL
;
1293 cp_walk_tree (&OMP_CLAUSE_DECL (stmt
), cp_genericize_r
,
1299 case OMP_CLAUSE_SHARED
:
1300 case OMP_CLAUSE_FIRSTPRIVATE
:
1301 case OMP_CLAUSE_COPYIN
:
1302 case OMP_CLAUSE_COPYPRIVATE
:
1303 case OMP_CLAUSE_INCLUSIVE
:
1304 case OMP_CLAUSE_EXCLUSIVE
:
1305 /* Don't dereference an invisiref in OpenMP clauses. */
1306 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
1309 case OMP_CLAUSE_REDUCTION
:
1310 case OMP_CLAUSE_IN_REDUCTION
:
1311 case OMP_CLAUSE_TASK_REDUCTION
:
1312 /* Don't dereference an invisiref in reduction clause's
1313 OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE}
1314 still needs to be genericized. */
1315 if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt
)))
1318 if (OMP_CLAUSE_REDUCTION_INIT (stmt
))
1319 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt
),
1320 cp_genericize_r
, data
, NULL
);
1321 if (OMP_CLAUSE_REDUCTION_MERGE (stmt
))
1322 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt
),
1323 cp_genericize_r
, data
, NULL
);
1331 /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1332 to lower this construct before scanning it, so we need to lower these
1333 before doing anything else. */
1335 *stmt_p
= build2_loc (EXPR_LOCATION (stmt
),
1336 CLEANUP_EH_ONLY (stmt
) ? TRY_CATCH_EXPR
1339 CLEANUP_BODY (stmt
),
1340 CLEANUP_EXPR (stmt
));
1344 genericize_if_stmt (stmt_p
);
1345 /* *stmt_p has changed, tail recurse to handle it again. */
1346 return cp_genericize_r (stmt_p
, walk_subtrees
, data
);
1348 /* COND_EXPR might have incompatible types in branches if one or both
1349 arms are bitfields. Fix it up now. */
1353 = (TREE_OPERAND (stmt
, 1)
1354 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt
, 1))
1357 = (TREE_OPERAND (stmt
, 2)
1358 ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt
, 2))
1361 && !useless_type_conversion_p (TREE_TYPE (stmt
),
1362 TREE_TYPE (TREE_OPERAND (stmt
, 1))))
1364 TREE_OPERAND (stmt
, 1)
1365 = fold_convert (type_left
, TREE_OPERAND (stmt
, 1));
1366 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt
),
1370 && !useless_type_conversion_p (TREE_TYPE (stmt
),
1371 TREE_TYPE (TREE_OPERAND (stmt
, 2))))
1373 TREE_OPERAND (stmt
, 2)
1374 = fold_convert (type_right
, TREE_OPERAND (stmt
, 2));
1375 gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt
),
1382 if (UNLIKELY (wtd
->omp_ctx
!= NULL
))
1385 for (decl
= BIND_EXPR_VARS (stmt
); decl
; decl
= DECL_CHAIN (decl
))
1387 && !DECL_EXTERNAL (decl
)
1388 && omp_var_to_track (decl
))
1391 = splay_tree_lookup (wtd
->omp_ctx
->variables
,
1392 (splay_tree_key
) decl
);
1394 splay_tree_insert (wtd
->omp_ctx
->variables
,
1395 (splay_tree_key
) decl
,
1397 ? OMP_CLAUSE_DEFAULT_SHARED
1398 : OMP_CLAUSE_DEFAULT_PRIVATE
);
1401 if (sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
| SANITIZE_VPTR
))
1403 /* The point here is to not sanitize static initializers. */
1404 bool no_sanitize_p
= wtd
->no_sanitize_p
;
1405 wtd
->no_sanitize_p
= true;
1406 for (tree decl
= BIND_EXPR_VARS (stmt
);
1408 decl
= DECL_CHAIN (decl
))
1410 && TREE_STATIC (decl
)
1411 && DECL_INITIAL (decl
))
1412 cp_walk_tree (&DECL_INITIAL (decl
), cp_genericize_r
, data
, NULL
);
1413 wtd
->no_sanitize_p
= no_sanitize_p
;
1415 wtd
->bind_expr_stack
.safe_push (stmt
);
1416 cp_walk_tree (&BIND_EXPR_BODY (stmt
),
1417 cp_genericize_r
, data
, NULL
);
1418 wtd
->bind_expr_stack
.pop ();
1423 tree block
= NULL_TREE
;
1425 /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1426 BLOCK, and append an IMPORTED_DECL to its
1427 BLOCK_VARS chained list. */
1428 if (wtd
->bind_expr_stack
.exists ())
1431 for (i
= wtd
->bind_expr_stack
.length () - 1; i
>= 0; i
--)
1432 if ((block
= BIND_EXPR_BLOCK (wtd
->bind_expr_stack
[i
])))
1437 tree decl
= TREE_OPERAND (stmt
, 0);
1440 if (undeduced_auto_decl (decl
))
1441 /* Omit from the GENERIC, the back-end can't handle it. */;
1444 tree using_directive
= make_node (IMPORTED_DECL
);
1445 TREE_TYPE (using_directive
) = void_type_node
;
1446 DECL_CONTEXT (using_directive
) = current_function_decl
;
1448 IMPORTED_DECL_ASSOCIATED_DECL (using_directive
) = decl
;
1449 DECL_CHAIN (using_directive
) = BLOCK_VARS (block
);
1450 BLOCK_VARS (block
) = using_directive
;
1453 /* The USING_STMT won't appear in GENERIC. */
1454 *stmt_p
= build1 (NOP_EXPR
, void_type_node
, integer_zero_node
);
1460 if (TREE_CODE (DECL_EXPR_DECL (stmt
)) == USING_DECL
)
1462 /* Using decls inside DECL_EXPRs are just dropped on the floor. */
1463 *stmt_p
= build1 (NOP_EXPR
, void_type_node
, integer_zero_node
);
1468 tree d
= DECL_EXPR_DECL (stmt
);
1470 gcc_assert (CP_DECL_THREAD_LOCAL_P (d
) == DECL_THREAD_LOCAL_P (d
));
1478 struct cp_genericize_omp_taskreg omp_ctx
;
1483 cp_walk_tree (&OMP_CLAUSES (stmt
), cp_genericize_r
, data
, NULL
);
1484 omp_ctx
.is_parallel
= TREE_CODE (stmt
) == OMP_PARALLEL
;
1485 omp_ctx
.default_shared
= omp_ctx
.is_parallel
;
1486 omp_ctx
.outer
= wtd
->omp_ctx
;
1487 omp_ctx
.variables
= splay_tree_new (splay_tree_compare_decl_uid
, 0, 0);
1488 wtd
->omp_ctx
= &omp_ctx
;
1489 for (c
= OMP_CLAUSES (stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
1490 switch (OMP_CLAUSE_CODE (c
))
1492 case OMP_CLAUSE_SHARED
:
1493 case OMP_CLAUSE_PRIVATE
:
1494 case OMP_CLAUSE_FIRSTPRIVATE
:
1495 case OMP_CLAUSE_LASTPRIVATE
:
1496 decl
= OMP_CLAUSE_DECL (c
);
1497 if (decl
== error_mark_node
|| !omp_var_to_track (decl
))
1499 n
= splay_tree_lookup (omp_ctx
.variables
, (splay_tree_key
) decl
);
1502 splay_tree_insert (omp_ctx
.variables
, (splay_tree_key
) decl
,
1503 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
1504 ? OMP_CLAUSE_DEFAULT_SHARED
1505 : OMP_CLAUSE_DEFAULT_PRIVATE
);
1506 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
&& omp_ctx
.outer
)
1507 omp_cxx_notice_variable (omp_ctx
.outer
, decl
);
1509 case OMP_CLAUSE_DEFAULT
:
1510 if (OMP_CLAUSE_DEFAULT_KIND (c
) == OMP_CLAUSE_DEFAULT_SHARED
)
1511 omp_ctx
.default_shared
= true;
1515 if (TREE_CODE (stmt
) == OMP_TASKLOOP
)
1516 c_genericize_control_stmt (stmt_p
, walk_subtrees
, data
,
1517 cp_genericize_r
, cp_walk_subtrees
);
1519 cp_walk_tree (&OMP_BODY (stmt
), cp_genericize_r
, data
, NULL
);
1520 wtd
->omp_ctx
= omp_ctx
.outer
;
1521 splay_tree_delete (omp_ctx
.variables
);
1526 cfun
->has_omp_target
= true;
1532 tree try_block
= wtd
->try_block
;
1533 wtd
->try_block
= stmt
;
1534 cp_walk_tree (&TRY_STMTS (stmt
), cp_genericize_r
, data
, NULL
);
1535 wtd
->try_block
= try_block
;
1536 cp_walk_tree (&TRY_HANDLERS (stmt
), cp_genericize_r
, data
, NULL
);
1540 case MUST_NOT_THROW_EXPR
:
1541 /* MUST_NOT_THROW_COND might be something else with TM. */
1542 if (MUST_NOT_THROW_COND (stmt
) == NULL_TREE
)
1545 tree try_block
= wtd
->try_block
;
1546 wtd
->try_block
= stmt
;
1547 cp_walk_tree (&TREE_OPERAND (stmt
, 0), cp_genericize_r
, data
, NULL
);
1548 wtd
->try_block
= try_block
;
1554 location_t loc
= location_of (stmt
);
1555 if (warning_suppressed_p (stmt
/* What warning? */))
1557 else if (wtd
->try_block
)
1559 if (TREE_CODE (wtd
->try_block
) == MUST_NOT_THROW_EXPR
)
1561 auto_diagnostic_group d
;
1562 if (warning_at (loc
, OPT_Wterminate
,
1563 "%<throw%> will always call %<terminate%>")
1564 && cxx_dialect
>= cxx11
1565 && DECL_DESTRUCTOR_P (current_function_decl
))
1566 inform (loc
, "in C++11 destructors default to %<noexcept%>");
1571 if (warn_cxx11_compat
&& cxx_dialect
< cxx11
1572 && DECL_DESTRUCTOR_P (current_function_decl
)
1573 && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl
))
1575 && (get_defaulted_eh_spec (current_function_decl
)
1576 == empty_except_spec
))
1577 warning_at (loc
, OPT_Wc__11_compat
,
1578 "in C++11 this %<throw%> will call %<terminate%> "
1579 "because destructors default to %<noexcept%>");
1585 gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt
));
1588 case SPACESHIP_EXPR
:
1589 *stmt_p
= genericize_spaceship (*stmt_p
);
1593 /* By the time we get here we're handing off to the back end, so we don't
1594 need or want to preserve PTRMEM_CST anymore. */
1595 *stmt_p
= cplus_expand_constant (stmt
);
1600 /* For MEM_REF, make sure not to sanitize the second operand even
1601 if it has reference type. It is just an offset with a type
1602 holding other information. There is no other processing we
1603 need to do for INTEGER_CSTs, so just ignore the second argument
1605 cp_walk_tree (&TREE_OPERAND (stmt
, 0), cp_genericize_r
, data
, NULL
);
1610 *stmt_p
= predeclare_vla (*stmt_p
);
1611 if (!wtd
->no_sanitize_p
1612 && sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
)
1613 && TYPE_REF_P (TREE_TYPE (stmt
)))
1614 ubsan_maybe_instrument_reference (stmt_p
);
1618 /* Evaluate function concept checks instead of treating them as
1619 normal functions. */
1620 if (concept_check_p (stmt
))
1622 *stmt_p
= evaluate_concept_check (stmt
);
1623 * walk_subtrees
= 0;
1627 if (!wtd
->no_sanitize_p
1628 && sanitize_flags_p ((SANITIZE_NULL
1629 | SANITIZE_ALIGNMENT
| SANITIZE_VPTR
)))
1631 tree fn
= CALL_EXPR_FN (stmt
);
1633 && !error_operand_p (fn
)
1634 && INDIRECT_TYPE_P (TREE_TYPE (fn
))
1635 && TREE_CODE (TREE_TYPE (TREE_TYPE (fn
))) == METHOD_TYPE
)
1638 = TREE_CODE (fn
) == ADDR_EXPR
1639 && TREE_CODE (TREE_OPERAND (fn
, 0)) == FUNCTION_DECL
1640 && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn
, 0));
1641 if (sanitize_flags_p (SANITIZE_NULL
| SANITIZE_ALIGNMENT
))
1642 ubsan_maybe_instrument_member_call (stmt
, is_ctor
);
1643 if (sanitize_flags_p (SANITIZE_VPTR
) && !is_ctor
)
1644 cp_ubsan_maybe_instrument_member_call (stmt
);
1646 else if (fn
== NULL_TREE
1647 && CALL_EXPR_IFN (stmt
) == IFN_UBSAN_NULL
1648 && TREE_CODE (CALL_EXPR_ARG (stmt
, 0)) == INTEGER_CST
1649 && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt
, 0))))
1653 case AGGR_INIT_EXPR
:
1654 /* For calls to a multi-versioned function, overload resolution
1655 returns the function with the highest target priority, that is,
1656 the version that will checked for dispatching first. If this
1657 version is inlinable, a direct call to this version can be made
1658 otherwise the call should go through the dispatcher. */
1660 tree fn
= cp_get_callee_fndecl_nofold (stmt
);
1661 if (fn
&& DECL_FUNCTION_VERSIONED (fn
)
1662 && (current_function_decl
== NULL
1663 || !targetm
.target_option
.can_inline_p (current_function_decl
,
1665 if (tree dis
= get_function_version_dispatcher (fn
))
1667 mark_versions_used (dis
);
1668 dis
= build_address (dis
);
1669 if (TREE_CODE (stmt
) == CALL_EXPR
)
1670 CALL_EXPR_FN (stmt
) = dis
;
1672 AGGR_INIT_EXPR_FN (stmt
) = dis
;
1678 if (TARGET_EXPR_INITIAL (stmt
)
1679 && TREE_CODE (TARGET_EXPR_INITIAL (stmt
)) == CONSTRUCTOR
1680 && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt
)))
1681 TARGET_EXPR_NO_ELIDE (stmt
) = 1;
1684 case TEMPLATE_ID_EXPR
:
1685 gcc_assert (concept_check_p (stmt
));
1686 /* Emit the value of the concept check. */
1687 *stmt_p
= evaluate_concept_check (stmt
);
1691 case OMP_DISTRIBUTE
:
1692 /* Need to explicitly instantiate copy ctors on class iterators of
1693 composite distribute parallel for. */
1694 if (OMP_FOR_INIT (*stmt_p
) == NULL_TREE
)
1696 tree
*data
[4] = { NULL
, NULL
, NULL
, NULL
};
1697 tree inner
= walk_tree (&OMP_FOR_BODY (*stmt_p
),
1698 find_combined_omp_for
, data
, NULL
);
1699 if (inner
!= NULL_TREE
1700 && TREE_CODE (inner
) == OMP_FOR
)
1702 for (int i
= 0; i
< TREE_VEC_LENGTH (OMP_FOR_INIT (inner
)); i
++)
1703 if (OMP_FOR_ORIG_DECLS (inner
)
1704 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner
),
1706 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner
),
1709 tree orig
= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner
), i
);
1710 /* Class iterators aren't allowed on OMP_SIMD, so the only
1711 case we need to solve is distribute parallel for. */
1712 gcc_assert (TREE_CODE (inner
) == OMP_FOR
1714 tree orig_decl
= TREE_PURPOSE (orig
);
1715 tree c
, cl
= NULL_TREE
;
1716 for (c
= OMP_FOR_CLAUSES (inner
);
1717 c
; c
= OMP_CLAUSE_CHAIN (c
))
1718 if ((OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1719 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
1720 && OMP_CLAUSE_DECL (c
) == orig_decl
)
1725 if (cl
== NULL_TREE
)
1727 for (c
= OMP_PARALLEL_CLAUSES (*data
[1]);
1728 c
; c
= OMP_CLAUSE_CHAIN (c
))
1729 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1730 && OMP_CLAUSE_DECL (c
) == orig_decl
)
1738 orig_decl
= require_complete_type (orig_decl
);
1739 tree inner_type
= TREE_TYPE (orig_decl
);
1740 if (orig_decl
== error_mark_node
)
1742 if (TYPE_REF_P (TREE_TYPE (orig_decl
)))
1743 inner_type
= TREE_TYPE (inner_type
);
1745 while (TREE_CODE (inner_type
) == ARRAY_TYPE
)
1746 inner_type
= TREE_TYPE (inner_type
);
1747 get_copy_ctor (inner_type
, tf_warning_or_error
);
1764 case STATEMENT_LIST
:
1765 /* These cases are handled by shared code. */
1766 c_genericize_control_stmt (stmt_p
, walk_subtrees
, data
,
1767 cp_genericize_r
, cp_walk_subtrees
);
1771 *stmt_p
= build1_loc (EXPR_LOCATION (stmt
), VIEW_CONVERT_EXPR
,
1772 TREE_TYPE (stmt
), TREE_OPERAND (stmt
, 0));
1776 if (IS_TYPE_OR_DECL_P (stmt
))
1781 p_set
->add (*stmt_p
);
1786 /* Lower C++ front end trees to GENERIC in T_P. */
1789 cp_genericize_tree (tree
* t_p
, bool handle_invisiref_parm_p
)
1791 struct cp_genericize_data wtd
;
1793 wtd
.p_set
= new hash_set
<tree
>;
1794 wtd
.bind_expr_stack
.create (0);
1796 wtd
.try_block
= NULL_TREE
;
1797 wtd
.no_sanitize_p
= false;
1798 wtd
.handle_invisiref_parm_p
= handle_invisiref_parm_p
;
1799 cp_walk_tree (t_p
, cp_genericize_r
, &wtd
, NULL
);
1801 if (sanitize_flags_p (SANITIZE_VPTR
))
1802 cp_ubsan_instrument_member_accesses (t_p
);
1805 /* If a function that should end with a return in non-void
1806 function doesn't obviously end with return, add ubsan
1807 instrumentation code to verify it at runtime. If -fsanitize=return
1808 is not enabled, instrument __builtin_unreachable. */
1811 cp_maybe_instrument_return (tree fndecl
)
1813 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl
)))
1814 || DECL_CONSTRUCTOR_P (fndecl
)
1815 || DECL_DESTRUCTOR_P (fndecl
)
1816 || !targetm
.warn_func_return (fndecl
))
1819 if (!sanitize_flags_p (SANITIZE_RETURN
, fndecl
)
1820 /* Don't add __builtin_unreachable () if not optimizing, it will not
1821 improve any optimizations in that case, just break UB code.
1822 Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
1823 UBSan covers this with ubsan_instrument_return above where sufficient
1824 information is provided, while the __builtin_unreachable () below
1825 if return sanitization is disabled will just result in hard to
1826 understand runtime error without location. */
1827 && ((!optimize
&& !flag_unreachable_traps
)
1828 || sanitize_flags_p (SANITIZE_UNREACHABLE
, fndecl
)))
1831 tree t
= DECL_SAVED_TREE (fndecl
);
1834 switch (TREE_CODE (t
))
1837 t
= BIND_EXPR_BODY (t
);
1839 case TRY_FINALLY_EXPR
:
1840 case CLEANUP_POINT_EXPR
:
1841 t
= TREE_OPERAND (t
, 0);
1843 case STATEMENT_LIST
:
1845 tree_stmt_iterator i
= tsi_last (t
);
1846 while (!tsi_end_p (i
))
1848 tree p
= tsi_stmt (i
);
1849 if (TREE_CODE (p
) != DEBUG_BEGIN_STMT
)
1869 tree
*p
= &DECL_SAVED_TREE (fndecl
);
1870 if (TREE_CODE (*p
) == BIND_EXPR
)
1871 p
= &BIND_EXPR_BODY (*p
);
1873 location_t loc
= DECL_SOURCE_LOCATION (fndecl
);
1874 if (sanitize_flags_p (SANITIZE_RETURN
, fndecl
))
1875 t
= ubsan_instrument_return (loc
);
1877 t
= build_builtin_unreachable (BUILTINS_LOCATION
);
1879 append_to_statement_list (t
, p
);
1883 cp_genericize (tree fndecl
)
1887 /* Fix up the types of parms passed by invisible reference. */
1888 for (t
= DECL_ARGUMENTS (fndecl
); t
; t
= DECL_CHAIN (t
))
1889 if (TREE_ADDRESSABLE (TREE_TYPE (t
)))
1891 /* If a function's arguments are copied to create a thunk,
1892 then DECL_BY_REFERENCE will be set -- but the type of the
1893 argument will be a pointer type, so we will never get
1895 gcc_assert (!DECL_BY_REFERENCE (t
));
1896 gcc_assert (DECL_ARG_TYPE (t
) != TREE_TYPE (t
));
1897 TREE_TYPE (t
) = DECL_ARG_TYPE (t
);
1898 DECL_BY_REFERENCE (t
) = 1;
1899 TREE_ADDRESSABLE (t
) = 0;
1903 /* Do the same for the return value. */
1904 if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl
))))
1906 t
= DECL_RESULT (fndecl
);
1907 TREE_TYPE (t
) = build_reference_type (TREE_TYPE (t
));
1908 DECL_BY_REFERENCE (t
) = 1;
1909 TREE_ADDRESSABLE (t
) = 0;
1913 /* Adjust DECL_VALUE_EXPR of the original var. */
1914 tree outer
= outer_curly_brace_block (current_function_decl
);
1918 for (var
= BLOCK_VARS (outer
); var
; var
= DECL_CHAIN (var
))
1920 && DECL_NAME (t
) == DECL_NAME (var
)
1921 && DECL_HAS_VALUE_EXPR_P (var
)
1922 && DECL_VALUE_EXPR (var
) == t
)
1924 tree val
= convert_from_reference (t
);
1925 SET_DECL_VALUE_EXPR (var
, val
);
1931 /* If we're a clone, the body is already GIMPLE. */
1932 if (DECL_CLONED_FUNCTION_P (fndecl
))
1935 /* Allow cp_genericize calls to be nested. */
1936 bc_state_t save_state
;
1937 save_bc_state (&save_state
);
1939 /* We do want to see every occurrence of the parms, so we can't just use
1940 walk_tree's hash functionality. */
1941 cp_genericize_tree (&DECL_SAVED_TREE (fndecl
), true);
1943 cp_maybe_instrument_return (fndecl
);
1945 /* Do everything else. */
1946 c_genericize (fndecl
);
1947 restore_bc_state (&save_state
);
1950 /* Build code to apply FN to each member of ARG1 and ARG2. FN may be
1951 NULL if there is in fact nothing to do. ARG2 may be null if FN
1952 actually only takes one argument. */
1955 cxx_omp_clause_apply_fn (tree fn
, tree arg1
, tree arg2
)
1957 tree defparm
, parm
, t
;
1965 nargs
= list_length (DECL_ARGUMENTS (fn
));
1966 argarray
= XALLOCAVEC (tree
, nargs
);
1968 defparm
= TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn
)));
1970 defparm
= TREE_CHAIN (defparm
);
1972 bool is_method
= TREE_CODE (TREE_TYPE (fn
)) == METHOD_TYPE
;
1973 if (TREE_CODE (TREE_TYPE (arg1
)) == ARRAY_TYPE
)
1975 tree inner_type
= TREE_TYPE (arg1
);
1976 tree start1
, end1
, p1
;
1977 tree start2
= NULL
, p2
= NULL
;
1978 tree ret
= NULL
, lab
;
1984 inner_type
= TREE_TYPE (inner_type
);
1985 start1
= build4 (ARRAY_REF
, inner_type
, start1
,
1986 size_zero_node
, NULL
, NULL
);
1988 start2
= build4 (ARRAY_REF
, inner_type
, start2
,
1989 size_zero_node
, NULL
, NULL
);
1991 while (TREE_CODE (inner_type
) == ARRAY_TYPE
);
1992 start1
= build_fold_addr_expr_loc (input_location
, start1
);
1994 start2
= build_fold_addr_expr_loc (input_location
, start2
);
1996 end1
= TYPE_SIZE_UNIT (TREE_TYPE (arg1
));
1997 end1
= fold_build_pointer_plus (start1
, end1
);
1999 p1
= create_tmp_var (TREE_TYPE (start1
));
2000 t
= build2 (MODIFY_EXPR
, TREE_TYPE (p1
), p1
, start1
);
2001 append_to_statement_list (t
, &ret
);
2005 p2
= create_tmp_var (TREE_TYPE (start2
));
2006 t
= build2 (MODIFY_EXPR
, TREE_TYPE (p2
), p2
, start2
);
2007 append_to_statement_list (t
, &ret
);
2010 lab
= create_artificial_label (input_location
);
2011 t
= build1 (LABEL_EXPR
, void_type_node
, lab
);
2012 append_to_statement_list (t
, &ret
);
2017 /* Handle default arguments. */
2018 for (parm
= defparm
; parm
&& parm
!= void_list_node
;
2019 parm
= TREE_CHAIN (parm
), i
++)
2020 argarray
[i
] = convert_default_arg (TREE_VALUE (parm
),
2021 TREE_PURPOSE (parm
), fn
,
2022 i
- is_method
, tf_warning_or_error
);
2023 t
= build_call_a (fn
, i
, argarray
);
2024 t
= fold_convert (void_type_node
, t
);
2025 t
= fold_build_cleanup_point_expr (TREE_TYPE (t
), t
);
2026 append_to_statement_list (t
, &ret
);
2028 t
= fold_build_pointer_plus (p1
, TYPE_SIZE_UNIT (inner_type
));
2029 t
= build2 (MODIFY_EXPR
, TREE_TYPE (p1
), p1
, t
);
2030 append_to_statement_list (t
, &ret
);
2034 t
= fold_build_pointer_plus (p2
, TYPE_SIZE_UNIT (inner_type
));
2035 t
= build2 (MODIFY_EXPR
, TREE_TYPE (p2
), p2
, t
);
2036 append_to_statement_list (t
, &ret
);
2039 t
= build2 (NE_EXPR
, boolean_type_node
, p1
, end1
);
2040 t
= build3 (COND_EXPR
, void_type_node
, t
, build_and_jump (&lab
), NULL
);
2041 append_to_statement_list (t
, &ret
);
2047 argarray
[i
++] = build_fold_addr_expr_loc (input_location
, arg1
);
2049 argarray
[i
++] = build_fold_addr_expr_loc (input_location
, arg2
);
2050 /* Handle default arguments. */
2051 for (parm
= defparm
; parm
&& parm
!= void_list_node
;
2052 parm
= TREE_CHAIN (parm
), i
++)
2053 argarray
[i
] = convert_default_arg (TREE_VALUE (parm
),
2054 TREE_PURPOSE (parm
), fn
,
2055 i
- is_method
, tf_warning_or_error
);
2056 t
= build_call_a (fn
, i
, argarray
);
2057 t
= fold_convert (void_type_node
, t
);
2058 return fold_build_cleanup_point_expr (TREE_TYPE (t
), t
);
2062 /* Return code to initialize DECL with its default constructor, or
2063 NULL if there's nothing to do. */
2066 cxx_omp_clause_default_ctor (tree clause
, tree decl
, tree
/*outer*/)
2068 tree info
= CP_OMP_CLAUSE_INFO (clause
);
2072 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 0), decl
, NULL
);
2077 /* Return code to initialize DST with a copy constructor from SRC. */
2080 cxx_omp_clause_copy_ctor (tree clause
, tree dst
, tree src
)
2082 tree info
= CP_OMP_CLAUSE_INFO (clause
);
2086 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 0), dst
, src
);
2088 ret
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
2093 /* Similarly, except use an assignment operator instead. */
2096 cxx_omp_clause_assign_op (tree clause
, tree dst
, tree src
)
2098 tree info
= CP_OMP_CLAUSE_INFO (clause
);
2102 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 2), dst
, src
);
2104 ret
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
2109 /* Return code to destroy DECL. */
2112 cxx_omp_clause_dtor (tree clause
, tree decl
)
2114 tree info
= CP_OMP_CLAUSE_INFO (clause
);
2118 ret
= cxx_omp_clause_apply_fn (TREE_VEC_ELT (info
, 1), decl
, NULL
);
2123 /* True if OpenMP should privatize what this DECL points to rather
2124 than the DECL itself. */
2127 cxx_omp_privatize_by_reference (const_tree decl
)
2129 return (TYPE_REF_P (TREE_TYPE (decl
))
2130 || is_invisiref_parm (decl
));
2133 /* Return true if DECL is const qualified var having no mutable member. */
2135 cxx_omp_const_qual_no_mutable (tree decl
)
2137 tree type
= TREE_TYPE (decl
);
2138 if (TYPE_REF_P (type
))
2140 if (!is_invisiref_parm (decl
))
2142 type
= TREE_TYPE (type
);
2144 if (TREE_CODE (decl
) == RESULT_DECL
&& DECL_NAME (decl
))
2146 /* NVR doesn't preserve const qualification of the
2148 tree outer
= outer_curly_brace_block (current_function_decl
);
2152 for (var
= BLOCK_VARS (outer
); var
; var
= DECL_CHAIN (var
))
2154 && DECL_NAME (decl
) == DECL_NAME (var
)
2155 && (TYPE_MAIN_VARIANT (type
)
2156 == TYPE_MAIN_VARIANT (TREE_TYPE (var
))))
2158 if (TYPE_READONLY (TREE_TYPE (var
)))
2159 type
= TREE_TYPE (var
);
2165 if (type
== error_mark_node
)
2168 /* Variables with const-qualified type having no mutable member
2169 are predetermined shared. */
2170 if (TYPE_READONLY (type
) && !cp_has_mutable_p (type
))
2176 /* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
2177 of DECL is predetermined. */
2179 enum omp_clause_default_kind
2180 cxx_omp_predetermined_sharing_1 (tree decl
)
2182 /* Static data members are predetermined shared. */
2183 if (TREE_STATIC (decl
))
2185 tree ctx
= CP_DECL_CONTEXT (decl
);
2186 if (TYPE_P (ctx
) && MAYBE_CLASS_TYPE_P (ctx
))
2187 return OMP_CLAUSE_DEFAULT_SHARED
;
2189 if (c_omp_predefined_variable (decl
))
2190 return OMP_CLAUSE_DEFAULT_SHARED
;
2193 /* this may not be specified in data-sharing clauses, still we need
2194 to predetermined it firstprivate. */
2195 if (decl
== current_class_ptr
)
2196 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
;
2198 return OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
2201 /* Likewise, but also include the artificial vars. We don't want to
2202 disallow the artificial vars being mentioned in explicit clauses,
2203 as we use artificial vars e.g. for loop constructs with random
2204 access iterators other than pointers, but during gimplification
2205 we want to treat them as predetermined. */
2207 enum omp_clause_default_kind
2208 cxx_omp_predetermined_sharing (tree decl
)
2210 enum omp_clause_default_kind ret
= cxx_omp_predetermined_sharing_1 (decl
);
2211 if (ret
!= OMP_CLAUSE_DEFAULT_UNSPECIFIED
)
2214 /* Predetermine artificial variables holding integral values, those
2215 are usually result of gimplify_one_sizepos or SAVE_EXPR
2218 && DECL_ARTIFICIAL (decl
)
2219 && INTEGRAL_TYPE_P (TREE_TYPE (decl
))
2220 && !(DECL_LANG_SPECIFIC (decl
)
2221 && DECL_OMP_PRIVATIZED_MEMBER (decl
)))
2222 return OMP_CLAUSE_DEFAULT_SHARED
;
2224 /* Similarly for typeinfo symbols. */
2225 if (VAR_P (decl
) && DECL_ARTIFICIAL (decl
) && DECL_TINFO_P (decl
))
2226 return OMP_CLAUSE_DEFAULT_SHARED
;
2228 return OMP_CLAUSE_DEFAULT_UNSPECIFIED
;
2231 enum omp_clause_defaultmap_kind
2232 cxx_omp_predetermined_mapping (tree decl
)
2234 /* Predetermine artificial variables holding integral values, those
2235 are usually result of gimplify_one_sizepos or SAVE_EXPR
2238 && DECL_ARTIFICIAL (decl
)
2239 && INTEGRAL_TYPE_P (TREE_TYPE (decl
))
2240 && !(DECL_LANG_SPECIFIC (decl
)
2241 && DECL_OMP_PRIVATIZED_MEMBER (decl
)))
2242 return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE
;
2244 if (c_omp_predefined_variable (decl
))
2245 return OMP_CLAUSE_DEFAULTMAP_TO
;
2247 return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
;
2250 /* Finalize an implicitly determined clause. */
2253 cxx_omp_finish_clause (tree c
, gimple_seq
*, bool /* openacc */)
2255 tree decl
, inner_type
;
2256 bool make_shared
= false;
2258 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_FIRSTPRIVATE
2259 && OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
2260 && (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_LASTPRIVATE
2261 || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c
)))
2264 decl
= OMP_CLAUSE_DECL (c
);
2265 decl
= require_complete_type (decl
);
2266 inner_type
= TREE_TYPE (decl
);
2267 if (decl
== error_mark_node
)
2269 else if (TYPE_REF_P (TREE_TYPE (decl
)))
2270 inner_type
= TREE_TYPE (inner_type
);
2272 /* We're interested in the base element, not arrays. */
2273 while (TREE_CODE (inner_type
) == ARRAY_TYPE
)
2274 inner_type
= TREE_TYPE (inner_type
);
2276 /* Check for special function availability by building a call to one.
2277 Save the results, because later we won't be in the right context
2278 for making these queries. */
2279 bool first
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
;
2280 bool last
= OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
;
2282 && CLASS_TYPE_P (inner_type
)
2283 && cxx_omp_create_clause_info (c
, inner_type
, !first
, first
, last
,
2289 OMP_CLAUSE_CODE (c
) = OMP_CLAUSE_SHARED
;
2290 OMP_CLAUSE_SHARED_FIRSTPRIVATE (c
) = 0;
2291 OMP_CLAUSE_SHARED_READONLY (c
) = 0;
2295 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
2296 disregarded in OpenMP construct, because it is going to be
2297 remapped during OpenMP lowering. SHARED is true if DECL
2298 is going to be shared, false if it is going to be privatized. */
2301 cxx_omp_disregard_value_expr (tree decl
, bool shared
)
2306 && DECL_HAS_VALUE_EXPR_P (decl
)
2307 && DECL_ARTIFICIAL (decl
)
2308 && DECL_LANG_SPECIFIC (decl
)
2309 && DECL_OMP_PRIVATIZED_MEMBER (decl
))
2311 if (VAR_P (decl
) && DECL_CONTEXT (decl
) && is_capture_proxy (decl
))
2316 /* Fold expression X which is used as an rvalue if RVAL is true. */
2319 cp_fold_maybe_rvalue (tree x
, bool rval
)
2325 x
= mark_rvalue_use (x
);
2326 if (rval
&& DECL_P (x
)
2327 && !TYPE_REF_P (TREE_TYPE (x
)))
2329 tree v
= decl_constant_value (x
);
2330 if (v
!= x
&& v
!= error_mark_node
)
2341 /* Fold expression X which is used as an rvalue. */
2344 cp_fold_rvalue (tree x
)
2346 return cp_fold_maybe_rvalue (x
, true);
2349 /* Perform folding on expression X. */
2352 cp_fully_fold (tree x
)
2354 if (processing_template_decl
)
2356 /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
2357 have to call both. */
2358 if (cxx_dialect
>= cxx11
)
2360 x
= maybe_constant_value (x
);
2361 /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
2362 a TARGET_EXPR; undo that here. */
2363 if (TREE_CODE (x
) == TARGET_EXPR
)
2364 x
= TARGET_EXPR_INITIAL (x
);
2365 else if (TREE_CODE (x
) == VIEW_CONVERT_EXPR
2366 && TREE_CODE (TREE_OPERAND (x
, 0)) == CONSTRUCTOR
2367 && TREE_TYPE (TREE_OPERAND (x
, 0)) == TREE_TYPE (x
))
2368 x
= TREE_OPERAND (x
, 0);
2370 return cp_fold_rvalue (x
);
2373 /* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
2377 cp_fully_fold_init (tree x
)
2379 if (processing_template_decl
)
2381 x
= cp_fully_fold (x
);
2382 cp_fold_data
data (/*genericize*/false);
2383 cp_walk_tree (&x
, cp_fold_r
, &data
, NULL
);
2387 /* c-common interface to cp_fold. If IN_INIT, this is in a static initializer
2388 and certain changes are made to the folding done. Or should be (FIXME). We
2389 never touch maybe_const, as it is only used for the C front-end
2390 C_MAYBE_CONST_EXPR. */
2393 c_fully_fold (tree x
, bool /*in_init*/, bool */
*maybe_const*/
, bool lval
)
2395 return cp_fold_maybe_rvalue (x
, !lval
);
2398 static GTY((deletable
)) hash_map
<tree
, tree
> *fold_cache
;
2400 /* Dispose of the whole FOLD_CACHE. */
2403 clear_fold_cache (void)
2405 if (fold_cache
!= NULL
)
2406 fold_cache
->empty ();
2409 /* This function tries to fold an expression X.
2410 To avoid combinatorial explosion, folding results are kept in fold_cache.
2411 If X is invalid, we don't fold at all.
2412 For performance reasons we don't cache expressions representing a
2413 declaration or constant.
2414 Function returns X or its folded variant. */
2419 tree op0
, op1
, op2
, op3
;
2420 tree org_x
= x
, r
= NULL_TREE
;
2421 enum tree_code code
;
2423 bool rval_ops
= true;
2425 if (!x
|| x
== error_mark_node
)
2428 if (EXPR_P (x
) && (!TREE_TYPE (x
) || TREE_TYPE (x
) == error_mark_node
))
2431 /* Don't bother to cache DECLs or constants. */
2432 if (DECL_P (x
) || CONSTANT_CLASS_P (x
))
2435 if (fold_cache
== NULL
)
2436 fold_cache
= hash_map
<tree
, tree
>::create_ggc (101);
2438 if (tree
*cached
= fold_cache
->get (x
))
2441 uid_sensitive_constexpr_evaluation_checker c
;
2443 code
= TREE_CODE (x
);
2446 case CLEANUP_POINT_EXPR
:
2447 /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
2449 r
= cp_fold_rvalue (TREE_OPERAND (x
, 0));
2450 if (!TREE_SIDE_EFFECTS (r
))
2455 x
= fold_sizeof_expr (x
);
2458 case VIEW_CONVERT_EXPR
:
2461 case NON_LVALUE_EXPR
:
2464 if (VOID_TYPE_P (TREE_TYPE (x
)))
2466 /* This is just to make sure we don't end up with casts to
2467 void from error_mark_node. If we just return x, then
2468 cp_fold_r might fold the operand into error_mark_node and
2469 leave the conversion in the IR. STRIP_USELESS_TYPE_CONVERSION
2470 during gimplification doesn't like such casts.
2471 Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
2472 folding of the operand should be in the caches and if in cp_fold_r
2473 it will modify it in place. */
2474 op0
= cp_fold (TREE_OPERAND (x
, 0));
2475 if (op0
== error_mark_node
)
2476 x
= error_mark_node
;
2480 loc
= EXPR_LOCATION (x
);
2481 op0
= cp_fold_maybe_rvalue (TREE_OPERAND (x
, 0), rval_ops
);
2483 if (code
== CONVERT_EXPR
2484 && SCALAR_TYPE_P (TREE_TYPE (x
))
2485 && op0
!= void_node
)
2486 /* During parsing we used convert_to_*_nofold; re-convert now using the
2487 folding variants, since fold() doesn't do those transformations. */
2488 x
= fold (convert (TREE_TYPE (x
), op0
));
2489 else if (op0
!= TREE_OPERAND (x
, 0))
2491 if (op0
== error_mark_node
)
2492 x
= error_mark_node
;
2494 x
= fold_build1_loc (loc
, code
, TREE_TYPE (x
), op0
);
2499 /* Conversion of an out-of-range value has implementation-defined
2500 behavior; the language considers it different from arithmetic
2501 overflow, which is undefined. */
2502 if (TREE_CODE (op0
) == INTEGER_CST
2503 && TREE_OVERFLOW_P (x
) && !TREE_OVERFLOW_P (op0
))
2504 TREE_OVERFLOW (x
) = false;
2509 /* We don't need the decltype(auto) obfuscation anymore. */
2510 if (REF_PARENTHESIZED_P (x
))
2512 tree p
= maybe_undo_parenthesized_ref (x
);
2519 loc
= EXPR_LOCATION (x
);
2520 op0
= cp_fold_maybe_rvalue (TREE_OPERAND (x
, 0), false);
2522 /* Cope with user tricks that amount to offsetof. */
2523 if (op0
!= error_mark_node
2524 && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0
)))
2526 tree val
= get_base_address (op0
);
2528 && INDIRECT_REF_P (val
)
2529 && COMPLETE_TYPE_P (TREE_TYPE (val
))
2530 && TREE_CONSTANT (TREE_OPERAND (val
, 0)))
2532 val
= TREE_OPERAND (val
, 0);
2534 val
= maybe_constant_value (val
);
2535 if (TREE_CODE (val
) == INTEGER_CST
)
2536 return fold_offsetof (op0
, TREE_TYPE (x
));
2546 case FIX_TRUNC_EXPR
:
2552 case TRUTH_NOT_EXPR
:
2553 case FIXED_CONVERT_EXPR
:
2556 loc
= EXPR_LOCATION (x
);
2557 op0
= cp_fold_maybe_rvalue (TREE_OPERAND (x
, 0), rval_ops
);
2560 if (op0
!= TREE_OPERAND (x
, 0))
2562 if (op0
== error_mark_node
)
2563 x
= error_mark_node
;
2566 x
= fold_build1_loc (loc
, code
, TREE_TYPE (x
), op0
);
2567 if (code
== INDIRECT_REF
2568 && (INDIRECT_REF_P (x
) || TREE_CODE (x
) == MEM_REF
))
2570 TREE_READONLY (x
) = TREE_READONLY (org_x
);
2571 TREE_SIDE_EFFECTS (x
) = TREE_SIDE_EFFECTS (org_x
);
2572 TREE_THIS_VOLATILE (x
) = TREE_THIS_VOLATILE (org_x
);
2579 gcc_assert (TREE_CODE (x
) != COND_EXPR
2580 || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x
, 0))));
2583 case UNARY_PLUS_EXPR
:
2584 op0
= cp_fold_rvalue (TREE_OPERAND (x
, 0));
2585 if (op0
== error_mark_node
)
2586 x
= error_mark_node
;
2588 x
= fold_convert (TREE_TYPE (x
), op0
);
2591 case POSTDECREMENT_EXPR
:
2592 case POSTINCREMENT_EXPR
:
2594 case PREDECREMENT_EXPR
:
2595 case PREINCREMENT_EXPR
:
2600 case POINTER_PLUS_EXPR
:
2602 case POINTER_DIFF_EXPR
:
2605 case TRUNC_DIV_EXPR
:
2607 case FLOOR_DIV_EXPR
:
2608 case ROUND_DIV_EXPR
:
2609 case TRUNC_MOD_EXPR
:
2611 case ROUND_MOD_EXPR
:
2613 case EXACT_DIV_EXPR
:
2623 case TRUTH_AND_EXPR
:
2624 case TRUTH_ANDIF_EXPR
:
2626 case TRUTH_ORIF_EXPR
:
2627 case TRUTH_XOR_EXPR
:
2628 case LT_EXPR
: case LE_EXPR
:
2629 case GT_EXPR
: case GE_EXPR
:
2630 case EQ_EXPR
: case NE_EXPR
:
2631 case UNORDERED_EXPR
: case ORDERED_EXPR
:
2632 case UNLT_EXPR
: case UNLE_EXPR
:
2633 case UNGT_EXPR
: case UNGE_EXPR
:
2634 case UNEQ_EXPR
: case LTGT_EXPR
:
2635 case RANGE_EXPR
: case COMPLEX_EXPR
:
2637 loc
= EXPR_LOCATION (x
);
2638 op0
= cp_fold_maybe_rvalue (TREE_OPERAND (x
, 0), rval_ops
);
2639 op1
= cp_fold_rvalue (TREE_OPERAND (x
, 1));
2641 /* decltype(nullptr) has only one value, so optimize away all comparisons
2642 with that type right away, keeping them in the IL causes troubles for
2643 various optimizations. */
2644 if (COMPARISON_CLASS_P (org_x
)
2645 && TREE_CODE (TREE_TYPE (op0
)) == NULLPTR_TYPE
2646 && TREE_CODE (TREE_TYPE (op1
)) == NULLPTR_TYPE
)
2651 x
= constant_boolean_node (true, TREE_TYPE (x
));
2654 x
= constant_boolean_node (false, TREE_TYPE (x
));
2659 return omit_two_operands_loc (loc
, TREE_TYPE (x
), x
,
2663 if (op0
!= TREE_OPERAND (x
, 0) || op1
!= TREE_OPERAND (x
, 1))
2665 if (op0
== error_mark_node
|| op1
== error_mark_node
)
2666 x
= error_mark_node
;
2668 x
= fold_build2_loc (loc
, code
, TREE_TYPE (x
), op0
, op1
);
2673 /* This is only needed for -Wnonnull-compare and only if
2674 TREE_NO_WARNING (org_x), but to avoid that option affecting code
2675 generation, we do it always. */
2676 if (COMPARISON_CLASS_P (org_x
))
2678 if (x
== error_mark_node
|| TREE_CODE (x
) == INTEGER_CST
)
2680 else if (COMPARISON_CLASS_P (x
))
2682 if (warn_nonnull_compare
2683 && warning_suppressed_p (org_x
, OPT_Wnonnull_compare
))
2684 suppress_warning (x
, OPT_Wnonnull_compare
);
2686 /* Otherwise give up on optimizing these, let GIMPLE folders
2687 optimize those later on. */
2688 else if (op0
!= TREE_OPERAND (org_x
, 0)
2689 || op1
!= TREE_OPERAND (org_x
, 1))
2691 x
= build2_loc (loc
, code
, TREE_TYPE (org_x
), op0
, op1
);
2692 if (warn_nonnull_compare
2693 && warning_suppressed_p (org_x
, OPT_Wnonnull_compare
))
2694 suppress_warning (x
, OPT_Wnonnull_compare
);
2704 loc
= EXPR_LOCATION (x
);
2705 op0
= cp_fold_rvalue (TREE_OPERAND (x
, 0));
2706 op1
= cp_fold (TREE_OPERAND (x
, 1));
2707 op2
= cp_fold (TREE_OPERAND (x
, 2));
2709 if (TREE_CODE (TREE_TYPE (x
)) == BOOLEAN_TYPE
)
2711 warning_sentinel
s (warn_int_in_bool_context
);
2712 if (!VOID_TYPE_P (TREE_TYPE (op1
)))
2713 op1
= cp_truthvalue_conversion (op1
, tf_warning_or_error
);
2714 if (!VOID_TYPE_P (TREE_TYPE (op2
)))
2715 op2
= cp_truthvalue_conversion (op2
, tf_warning_or_error
);
2717 else if (VOID_TYPE_P (TREE_TYPE (x
)))
2719 if (TREE_CODE (op0
) == INTEGER_CST
)
2721 /* If the condition is constant, fold can fold away
2722 the COND_EXPR. If some statement-level uses of COND_EXPR
2723 have one of the branches NULL, avoid folding crash. */
2725 op1
= build_empty_stmt (loc
);
2727 op2
= build_empty_stmt (loc
);
2731 /* Otherwise, don't bother folding a void condition, since
2732 it can't produce a constant value. */
2733 if (op0
!= TREE_OPERAND (x
, 0)
2734 || op1
!= TREE_OPERAND (x
, 1)
2735 || op2
!= TREE_OPERAND (x
, 2))
2736 x
= build3_loc (loc
, code
, TREE_TYPE (x
), op0
, op1
, op2
);
2741 if (op0
!= TREE_OPERAND (x
, 0)
2742 || op1
!= TREE_OPERAND (x
, 1)
2743 || op2
!= TREE_OPERAND (x
, 2))
2745 if (op0
== error_mark_node
2746 || op1
== error_mark_node
2747 || op2
== error_mark_node
)
2748 x
= error_mark_node
;
2750 x
= fold_build3_loc (loc
, code
, TREE_TYPE (x
), op0
, op1
, op2
);
2755 /* A COND_EXPR might have incompatible types in branches if one or both
2756 arms are bitfields. If folding exposed such a branch, fix it up. */
2757 if (TREE_CODE (x
) != code
2758 && x
!= error_mark_node
2759 && !useless_type_conversion_p (TREE_TYPE (org_x
), TREE_TYPE (x
)))
2760 x
= fold_convert (TREE_TYPE (org_x
), x
);
2766 tree callee
= get_callee_fndecl (x
);
2768 /* "Inline" calls to std::move/forward and other cast-like functions
2769 by simply folding them into a corresponding cast to their return
2770 type. This is cheaper than relying on the middle end to do so, and
2771 also means we avoid generating useless debug info for them at all.
2773 At this point the argument has already been converted into a
2774 reference, so it suffices to use a NOP_EXPR to express the
2776 if ((OPTION_SET_P (flag_fold_simple_inlines
)
2777 ? flag_fold_simple_inlines
2779 && call_expr_nargs (x
) == 1
2780 && decl_in_std_namespace_p (callee
)
2781 && DECL_NAME (callee
) != NULL_TREE
2782 && (id_equal (DECL_NAME (callee
), "move")
2783 || id_equal (DECL_NAME (callee
), "forward")
2784 || id_equal (DECL_NAME (callee
), "addressof")
2785 /* This addressof equivalent is used heavily in libstdc++. */
2786 || id_equal (DECL_NAME (callee
), "__addressof")
2787 || id_equal (DECL_NAME (callee
), "as_const")))
2789 r
= CALL_EXPR_ARG (x
, 0);
2790 /* Check that the return and argument types are sane before
2792 if (INDIRECT_TYPE_P (TREE_TYPE (x
))
2793 && INDIRECT_TYPE_P (TREE_TYPE (r
)))
2795 if (!same_type_p (TREE_TYPE (x
), TREE_TYPE (r
)))
2796 r
= build_nop (TREE_TYPE (x
), r
);
2802 int sv
= optimize
, nw
= sv
;
2804 /* Some built-in function calls will be evaluated at compile-time in
2805 fold (). Set optimize to 1 when folding __builtin_constant_p inside
2806 a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
2807 if (callee
&& fndecl_built_in_p (callee
) && !optimize
2808 && DECL_IS_BUILTIN_CONSTANT_P (callee
)
2809 && current_function_decl
2810 && DECL_DECLARED_CONSTEXPR_P (current_function_decl
))
2813 if (callee
&& fndecl_built_in_p (callee
, BUILT_IN_FRONTEND
))
2815 switch (DECL_FE_FUNCTION_CODE (callee
))
2817 /* Defer folding __builtin_is_constant_evaluated. */
2818 case CP_BUILT_IN_IS_CONSTANT_EVALUATED
:
2820 case CP_BUILT_IN_SOURCE_LOCATION
:
2821 x
= fold_builtin_source_location (EXPR_LOCATION (x
));
2823 case CP_BUILT_IN_IS_CORRESPONDING_MEMBER
:
2824 x
= fold_builtin_is_corresponding_member
2825 (EXPR_LOCATION (x
), call_expr_nargs (x
),
2826 &CALL_EXPR_ARG (x
, 0));
2828 case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS
:
2829 x
= fold_builtin_is_pointer_inverconvertible_with_class
2830 (EXPR_LOCATION (x
), call_expr_nargs (x
),
2831 &CALL_EXPR_ARG (x
, 0));
2840 && fndecl_built_in_p (callee
, CP_BUILT_IN_SOURCE_LOCATION
,
2843 x
= fold_builtin_source_location (EXPR_LOCATION (x
));
2847 bool changed
= false;
2848 int m
= call_expr_nargs (x
);
2849 for (int i
= 0; i
< m
; i
++)
2851 r
= cp_fold (CALL_EXPR_ARG (x
, i
));
2852 if (r
!= CALL_EXPR_ARG (x
, i
))
2854 if (r
== error_mark_node
)
2856 x
= error_mark_node
;
2861 CALL_EXPR_ARG (x
, i
) = r
;
2865 if (x
== error_mark_node
)
2872 if (TREE_CODE (r
) != CALL_EXPR
)
2880 /* Invoke maybe_constant_value for functions declared
2881 constexpr and not called with AGGR_INIT_EXPRs.
2883 Do constexpr expansion of expressions where the call itself is not
2884 constant, but the call followed by an INDIRECT_REF is. */
2885 if (callee
&& DECL_DECLARED_CONSTEXPR_P (callee
)
2887 r
= maybe_constant_value (x
);
2890 if (TREE_CODE (r
) != CALL_EXPR
)
2892 if (DECL_CONSTRUCTOR_P (callee
))
2894 loc
= EXPR_LOCATION (x
);
2895 tree s
= build_fold_indirect_ref_loc (loc
,
2896 CALL_EXPR_ARG (x
, 0));
2897 r
= build2_loc (loc
, INIT_EXPR
, TREE_TYPE (s
), s
, r
);
2910 vec
<constructor_elt
, va_gc
> *elts
= CONSTRUCTOR_ELTS (x
);
2911 vec
<constructor_elt
, va_gc
> *nelts
= NULL
;
2912 FOR_EACH_VEC_SAFE_ELT (elts
, i
, p
)
2914 tree op
= cp_fold (p
->value
);
2917 if (op
== error_mark_node
)
2919 x
= error_mark_node
;
2924 nelts
= elts
->copy ();
2925 (*nelts
)[i
].value
= op
;
2930 x
= build_constructor (TREE_TYPE (x
), nelts
);
2931 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x
)
2932 = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x
);
2934 if (VECTOR_TYPE_P (TREE_TYPE (x
)))
2940 bool changed
= false;
2941 int n
= TREE_VEC_LENGTH (x
);
2943 for (int i
= 0; i
< n
; i
++)
2945 tree op
= cp_fold (TREE_VEC_ELT (x
, i
));
2946 if (op
!= TREE_VEC_ELT (x
, i
))
2950 TREE_VEC_ELT (x
, i
) = op
;
2959 case ARRAY_RANGE_REF
:
2961 loc
= EXPR_LOCATION (x
);
2962 op0
= cp_fold (TREE_OPERAND (x
, 0));
2963 op1
= cp_fold (TREE_OPERAND (x
, 1));
2964 op2
= cp_fold (TREE_OPERAND (x
, 2));
2965 op3
= cp_fold (TREE_OPERAND (x
, 3));
2967 if (op0
!= TREE_OPERAND (x
, 0)
2968 || op1
!= TREE_OPERAND (x
, 1)
2969 || op2
!= TREE_OPERAND (x
, 2)
2970 || op3
!= TREE_OPERAND (x
, 3))
2972 if (op0
== error_mark_node
2973 || op1
== error_mark_node
2974 || op2
== error_mark_node
2975 || op3
== error_mark_node
)
2976 x
= error_mark_node
;
2979 x
= build4_loc (loc
, code
, TREE_TYPE (x
), op0
, op1
, op2
, op3
);
2980 TREE_READONLY (x
) = TREE_READONLY (org_x
);
2981 TREE_SIDE_EFFECTS (x
) = TREE_SIDE_EFFECTS (org_x
);
2982 TREE_THIS_VOLATILE (x
) = TREE_THIS_VOLATILE (org_x
);
2990 /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
2991 folding, evaluates to an invariant. In that case no need to wrap
2992 this folded tree with a SAVE_EXPR. */
2993 r
= cp_fold (TREE_OPERAND (x
, 0));
2994 if (tree_invariant_p (r
))
2999 x
= evaluate_requires_expr (x
);
3006 if (EXPR_P (x
) && TREE_CODE (x
) == code
)
3008 TREE_THIS_VOLATILE (x
) = TREE_THIS_VOLATILE (org_x
);
3009 copy_warning (x
, org_x
);
3012 if (!c
.evaluation_restricted_p ())
3014 fold_cache
->put (org_x
, x
);
3015 /* Prevent that we try to fold an already folded result again. */
3017 fold_cache
->put (x
, x
);
3023 /* Look up either "hot" or "cold" in attribute list LIST. */
3026 lookup_hotness_attribute (tree list
)
3028 for (; list
; list
= TREE_CHAIN (list
))
3030 tree name
= get_attribute_name (list
);
3031 if (is_attribute_p ("hot", name
)
3032 || is_attribute_p ("cold", name
)
3033 || is_attribute_p ("likely", name
)
3034 || is_attribute_p ("unlikely", name
))
3040 /* Remove both "hot" and "cold" attributes from LIST. */
3043 remove_hotness_attribute (tree list
)
3045 list
= remove_attribute ("hot", list
);
3046 list
= remove_attribute ("cold", list
);
3047 list
= remove_attribute ("likely", list
);
3048 list
= remove_attribute ("unlikely", list
);
3052 /* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
3056 process_stmt_hotness_attribute (tree std_attrs
, location_t attrs_loc
)
3058 if (std_attrs
== error_mark_node
)
3060 if (tree attr
= lookup_hotness_attribute (std_attrs
))
3062 tree name
= get_attribute_name (attr
);
3063 bool hot
= (is_attribute_p ("hot", name
)
3064 || is_attribute_p ("likely", name
));
3065 tree pred
= build_predict_expr (hot
? PRED_HOT_LABEL
: PRED_COLD_LABEL
,
3066 hot
? TAKEN
: NOT_TAKEN
);
3067 SET_EXPR_LOCATION (pred
, attrs_loc
);
3069 if (tree other
= lookup_hotness_attribute (TREE_CHAIN (attr
)))
3070 warning (OPT_Wattributes
, "ignoring attribute %qE after earlier %qE",
3071 get_attribute_name (other
), name
);
3072 std_attrs
= remove_hotness_attribute (std_attrs
);
3077 /* Helper of fold_builtin_source_location, return the
3078 std::source_location::__impl type after performing verification
3079 on it. LOC is used for reporting any errors. */
3082 get_source_location_impl_type (location_t loc
)
3084 tree name
= get_identifier ("source_location");
3085 tree decl
= lookup_qualified_name (std_node
, name
);
3086 if (TREE_CODE (decl
) != TYPE_DECL
)
3088 auto_diagnostic_group d
;
3089 if (decl
== error_mark_node
|| TREE_CODE (decl
) == TREE_LIST
)
3090 qualified_name_lookup_error (std_node
, name
, decl
, loc
);
3092 error_at (loc
, "%qD is not a type", decl
);
3093 return error_mark_node
;
3095 name
= get_identifier ("__impl");
3096 tree type
= TREE_TYPE (decl
);
3097 decl
= lookup_qualified_name (type
, name
);
3098 if (TREE_CODE (decl
) != TYPE_DECL
)
3100 auto_diagnostic_group d
;
3101 if (decl
== error_mark_node
|| TREE_CODE (decl
) == TREE_LIST
)
3102 qualified_name_lookup_error (type
, name
, decl
, loc
);
3104 error_at (loc
, "%qD is not a type", decl
);
3105 return error_mark_node
;
3107 type
= TREE_TYPE (decl
);
3108 if (TREE_CODE (type
) != RECORD_TYPE
)
3110 error_at (loc
, "%qD is not a class type", decl
);
3111 return error_mark_node
;
3115 for (tree field
= TYPE_FIELDS (type
);
3116 (field
= next_aggregate_field (field
)) != NULL_TREE
;
3117 field
= DECL_CHAIN (field
))
3119 if (DECL_NAME (field
) != NULL_TREE
)
3121 const char *n
= IDENTIFIER_POINTER (DECL_NAME (field
));
3122 if (strcmp (n
, "_M_file_name") == 0
3123 || strcmp (n
, "_M_function_name") == 0)
3125 if (TREE_TYPE (field
) != const_string_type_node
)
3127 error_at (loc
, "%qD does not have %<const char *%> type",
3129 return error_mark_node
;
3134 else if (strcmp (n
, "_M_line") == 0 || strcmp (n
, "_M_column") == 0)
3136 if (TREE_CODE (TREE_TYPE (field
)) != INTEGER_TYPE
)
3138 error_at (loc
, "%qD does not have integral type", field
);
3139 return error_mark_node
;
3150 error_at (loc
, "%<std::source_location::__impl%> does not contain only "
3151 "non-static data members %<_M_file_name%>, "
3152 "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
3153 return error_mark_node
;
3155 return build_qualified_type (type
, TYPE_QUAL_CONST
);
3158 /* Type for source_location_table hash_set. */
3159 struct GTY((for_user
)) source_location_table_entry
{
3165 /* Traits class for function start hash maps below. */
3167 struct source_location_table_entry_hash
3168 : ggc_remove
<source_location_table_entry
>
3170 typedef source_location_table_entry value_type
;
3171 typedef source_location_table_entry compare_type
;
3174 hash (const source_location_table_entry
&ref
)
3176 inchash::hash
hstate (0);
3177 hstate
.add_int (ref
.loc
);
3178 hstate
.add_int (ref
.uid
);
3179 return hstate
.end ();
3183 equal (const source_location_table_entry
&ref1
,
3184 const source_location_table_entry
&ref2
)
3186 return ref1
.loc
== ref2
.loc
&& ref1
.uid
== ref2
.uid
;
3190 mark_deleted (source_location_table_entry
&ref
)
3192 ref
.loc
= UNKNOWN_LOCATION
;
3194 ref
.var
= NULL_TREE
;
3197 static const bool empty_zero_p
= true;
3200 mark_empty (source_location_table_entry
&ref
)
3202 ref
.loc
= UNKNOWN_LOCATION
;
3204 ref
.var
= NULL_TREE
;
3208 is_deleted (const source_location_table_entry
&ref
)
3210 return (ref
.loc
== UNKNOWN_LOCATION
3212 && ref
.var
== NULL_TREE
);
3216 is_empty (const source_location_table_entry
&ref
)
3218 return (ref
.loc
== UNKNOWN_LOCATION
3220 && ref
.var
== NULL_TREE
);
3224 pch_nx (source_location_table_entry
&p
)
3226 extern void gt_pch_nx (source_location_table_entry
&);
3231 pch_nx (source_location_table_entry
&p
, gt_pointer_operator op
, void *cookie
)
3233 extern void gt_pch_nx (source_location_table_entry
*, gt_pointer_operator
,
3235 gt_pch_nx (&p
, op
, cookie
);
3239 static GTY(()) hash_table
<source_location_table_entry_hash
>
3240 *source_location_table
;
3241 static GTY(()) unsigned int source_location_id
;
3243 /* Fold __builtin_source_location () call. LOC is the location
3247 fold_builtin_source_location (location_t loc
)
3249 if (source_location_impl
== NULL_TREE
)
3251 auto_diagnostic_group d
;
3252 source_location_impl
= get_source_location_impl_type (loc
);
3253 if (source_location_impl
== error_mark_node
)
3254 inform (loc
, "evaluating %qs", "__builtin_source_location");
3256 if (source_location_impl
== error_mark_node
)
3257 return build_zero_cst (const_ptr_type_node
);
3258 if (source_location_table
== NULL
)
3259 source_location_table
3260 = hash_table
<source_location_table_entry_hash
>::create_ggc (64);
3261 const line_map_ordinary
*map
;
3262 source_location_table_entry entry
;
3264 = linemap_resolve_location (line_table
, loc
, LRK_MACRO_EXPANSION_POINT
,
3266 entry
.uid
= current_function_decl
? DECL_UID (current_function_decl
) : -1;
3267 entry
.var
= error_mark_node
;
3268 source_location_table_entry
*entryp
3269 = source_location_table
->find_slot (entry
, INSERT
);
3276 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lsrc_loc", source_location_id
++);
3277 var
= build_decl (loc
, VAR_DECL
, get_identifier (tmp_name
),
3278 source_location_impl
);
3279 TREE_STATIC (var
) = 1;
3280 TREE_PUBLIC (var
) = 0;
3281 DECL_ARTIFICIAL (var
) = 1;
3282 DECL_IGNORED_P (var
) = 1;
3283 DECL_EXTERNAL (var
) = 0;
3284 DECL_DECLARED_CONSTEXPR_P (var
) = 1;
3285 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var
) = 1;
3286 layout_decl (var
, 0);
3288 vec
<constructor_elt
, va_gc
> *v
= NULL
;
3290 for (tree field
= TYPE_FIELDS (source_location_impl
);
3291 (field
= next_aggregate_field (field
)) != NULL_TREE
;
3292 field
= DECL_CHAIN (field
))
3294 const char *n
= IDENTIFIER_POINTER (DECL_NAME (field
));
3295 tree val
= NULL_TREE
;
3296 if (strcmp (n
, "_M_file_name") == 0)
3298 if (const char *fname
= LOCATION_FILE (loc
))
3300 fname
= remap_macro_filename (fname
);
3301 val
= build_string_literal (strlen (fname
) + 1, fname
);
3304 val
= build_string_literal (1, "");
3306 else if (strcmp (n
, "_M_function_name") == 0)
3308 const char *name
= "";
3310 if (current_function_decl
)
3311 name
= cxx_printable_name (current_function_decl
, 2);
3313 val
= build_string_literal (strlen (name
) + 1, name
);
3315 else if (strcmp (n
, "_M_line") == 0)
3316 val
= build_int_cst (TREE_TYPE (field
), LOCATION_LINE (loc
));
3317 else if (strcmp (n
, "_M_column") == 0)
3318 val
= build_int_cst (TREE_TYPE (field
), LOCATION_COLUMN (loc
));
3321 CONSTRUCTOR_APPEND_ELT (v
, field
, val
);
3324 tree ctor
= build_constructor (source_location_impl
, v
);
3325 TREE_CONSTANT (ctor
) = 1;
3326 TREE_STATIC (ctor
) = 1;
3327 DECL_INITIAL (var
) = ctor
;
3328 varpool_node::finalize_decl (var
);
3333 return build_fold_addr_expr_with_type_loc (loc
, var
, const_ptr_type_node
);
3336 #include "gt-cp-cp-gimplify.h"