Message ID | Zk_gJ8cpHNfRHVba@redhat.com |
---|---|
State | New |
Headers | show |
Series | [v2] c++: mark TARGET_EXPRs for function arguments eliding [PR114707] | expand |
On 5/23/24 20:32, Marek Polacek wrote: > On Thu, May 23, 2024 at 04:04:13PM -0400, Jason Merrill wrote: >> On 5/23/24 10:41, Marek Polacek wrote: >>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? >>> >>> -- >8 -- >>> Coming back to our discussion in >>> <https://gcc.gnu.org/pipermail/gcc-patches/2024-April/649426.html>: >>> TARGET_EXPRs that initialize a function argument are not marked >>> TARGET_EXPR_ELIDING_P even though gimplify_arg drops such TARGET_EXPRs >>> on the floor. >> >> But only if TREE_TYPE (TARGET_EXPR_INITIAL is non-void, I think we should >> check that here too to be parallel. > > Ah yes, definitely. > >> Perhaps most/all affected TARGET_EXPRs will have been handled earlier in the >> function under the TREE_ADDRESSABLE check, but I wouldn't rely on that >> without an assert. > > So like this or you want an assert somewhere too? dg.exp passed. > > -- >8 -- > Coming back to our discussion in > <https://gcc.gnu.org/pipermail/gcc-patches/2024-April/649426.html>: > TARGET_EXPRs that initialize a function argument are not marked > TARGET_EXPR_ELIDING_P even though gimplify_arg drops such TARGET_EXPRs > on the floor. To work around it, I added a pset to > replace_placeholders_for_class_temp_r, but it would be best to just rely > on TARGET_EXPR_ELIDING_P. > > PR c++/114707 > > gcc/cp/ChangeLog: > > * call.cc (convert_for_arg_passing): Call set_target_expr_eliding. > * typeck2.cc (replace_placeholders_for_class_temp_r): Don't use pset. > (digest_nsdmi_init): Call cp_walk_tree_without_duplicates instead of > cp_walk_tree. > --- > gcc/cp/call.cc | 6 ++++++ > gcc/cp/typeck2.cc | 20 ++++---------------- > 2 files changed, 10 insertions(+), 16 deletions(-) > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index ed68eb3c568..35c024f2c7c 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -9437,6 +9437,12 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) > if (complain & tf_warning) > warn_for_address_of_packed_member (type, val); > > + /* gimplify_arg elides TARGET_EXPRs that initialize a function argument. */ > + if (TREE_CODE (val) == TARGET_EXPR) > + if (tree init = TARGET_EXPR_INITIAL (val)) > + if (!VOID_TYPE_P (TREE_TYPE (init))) You can simplify this test to 'if (SIMPLE_TARGET_EXPR_P ...'. OK with that change. Jason
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index ed68eb3c568..35c024f2c7c 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -9437,6 +9437,12 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) if (complain & tf_warning) warn_for_address_of_packed_member (type, val); + /* gimplify_arg elides TARGET_EXPRs that initialize a function argument. */ + if (TREE_CODE (val) == TARGET_EXPR) + if (tree init = TARGET_EXPR_INITIAL (val)) + if (!VOID_TYPE_P (TREE_TYPE (init))) + set_target_expr_eliding (val); + return val; } diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc index 06bad4d3303..7782f38da43 100644 --- a/gcc/cp/typeck2.cc +++ b/gcc/cp/typeck2.cc @@ -1409,16 +1409,14 @@ digest_init_flags (tree type, tree init, int flags, tsubst_flags_t complain) in the context of guaranteed copy elision). */ static tree -replace_placeholders_for_class_temp_r (tree *tp, int *, void *data) +replace_placeholders_for_class_temp_r (tree *tp, int *, void *) { tree t = *tp; - auto pset = static_cast<hash_set<tree> *>(data); /* We're looking for a TARGET_EXPR nested in the whole expression. */ if (TREE_CODE (t) == TARGET_EXPR /* That serves as temporary materialization, not an initializer. */ - && !TARGET_EXPR_ELIDING_P (t) - && !pset->add (t)) + && !TARGET_EXPR_ELIDING_P (t)) { tree init = TARGET_EXPR_INITIAL (t); while (TREE_CODE (init) == COMPOUND_EXPR) @@ -1433,16 +1431,6 @@ replace_placeholders_for_class_temp_r (tree *tp, int *, void *data) gcc_checking_assert (!find_placeholders (init)); } } - /* TARGET_EXPRs initializing function arguments are not marked as eliding, - even though gimplify_arg drops them on the floor. Don't go replacing - placeholders in them. */ - else if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR) - for (int i = 0; i < call_expr_nargs (t); ++i) - { - tree arg = get_nth_callarg (t, i); - if (TREE_CODE (arg) == TARGET_EXPR && !TARGET_EXPR_ELIDING_P (arg)) - pset->add (arg); - } return NULL_TREE; } @@ -1490,8 +1478,8 @@ digest_nsdmi_init (tree decl, tree init, tsubst_flags_t complain) temporary materialization does not occur when initializing an object from a prvalue of the same type, therefore we must not replace the placeholder with a temporary object so that it can be elided. */ - hash_set<tree> pset; - cp_walk_tree (&init, replace_placeholders_for_class_temp_r, &pset, nullptr); + cp_walk_tree_without_duplicates (&init, replace_placeholders_for_class_temp_r, + nullptr); return init; }