diff options
author | Jason Merrill <jason@redhat.com> | 2022-09-17 12:04:05 +0200 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-10-07 20:25:51 -0400 |
commit | 6ffbf87ca66f4ed9cd79cff675fabe2109e46e85 (patch) | |
tree | dc67518a45f51746a76021cdca31b0d4c10677ed /gcc/cp/method.cc | |
parent | 9ff6c33e2ec0d75958d3f19089519034e8f96a30 (diff) | |
download | gcc-6ffbf87ca66f4ed9cd79cff675fabe2109e46e85.zip gcc-6ffbf87ca66f4ed9cd79cff675fabe2109e46e85.tar.gz gcc-6ffbf87ca66f4ed9cd79cff675fabe2109e46e85.tar.bz2 |
c++: track whether we expect a TARGET_EXPR to be elided
A discussion at Cauldron made me think that with the formalization of copy
elision in C++17, we should be able to determine before optimization which
TARGET_EXPRs will become temporaries and which are initializers. This patch
implements that: we set TARGET_EXPR_ELIDING_P if it's used as an
initializer, and later check that we were right.
There's an exception in the cp_gimplify_expr check to allow extra
temporaries of non-addressable type: this is used by
gimplify_init_ctor_preeval to materialize subobjects of a CONSTRUCTOR on the
rhs of a MODIFY_EXPR rather than materializing the whole object. If the
type isn't addressable, there's no way for a program to tell the difference,
so this is a valid optimization.
I considered changing replace_placeholders_for_class_temp_r to check
TARGET_EXPR_ELIDING_P instead of potential_prvalue_result_of, but decided
that would be wrong: if we have an eliding TARGET_EXPR inside a non-eliding
one, we would miss replacing its placeholders.
gcc/cp/ChangeLog:
* cp-tree.h (TARGET_EXPR_ELIDING_P): New.
(unsafe_copy_elision_p, set_target_expr_eliding)
(cp_build_init_expr): Declare.
* call.cc (unsafe_copy_elision_p): No longer static.
(build_over_call, build_special_member_call)
(build_new_method_call): Use cp_build_init_expr.
* coroutines.cc (expand_one_await_expression)
(build_actor_fn, flatten_await_stmt, handle_nested_conditionals)
(await_statement_walker, morph_fn_to_coro): Use cp_build_init_expr.
* cp-gimplify.cc (cp_gimplify_init_expr)
(cp_gimplify_expr): Check TARGET_EXPR_ELIDING_P.
(cp_fold_r): Propagate it.
(cp_fold): Use cp_build_init_expr.
* decl.cc (check_initializer): Use cp_build_init_expr.
* except.cc (build_throw): Use cp_build_init_expr.
* init.cc (get_nsdmi): Call set_target_expr_eliding.
(perform_member_init, expand_default_init, expand_aggr_init_1)
(build_new_1, build_vec_init): Use cp_build_init_expr.
* method.cc (do_build_copy_constructor): Use cp_build_init_expr.
* semantics.cc (simplify_aggr_init_expr, finalize_nrv_r)
(finish_omp_reduction_clause): Use cp_build_init_expr.
* tree.cc (build_target_expr): Call set_target_expr_eliding.
(bot_manip): Copy TARGET_EXPR_ELIDING_P.
* typeck.cc (cp_build_modify_expr): Call set_target_expr_eliding.
(check_return_expr): Use cp_build_modify_expr.
* typeck2.cc (split_nonconstant_init_1)
(split_nonconstant_init): Use cp_build_init_expr.
(massage_init_elt): Call set_target_expr_eliding.
(process_init_constructor_record): Clear TARGET_EXPR_ELIDING_P on
unsafe copy elision.
(set_target_expr_eliding, cp_build_init_expr): New.
Diffstat (limited to 'gcc/cp/method.cc')
-rw-r--r-- | gcc/cp/method.cc | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 622e1b9..c217d7e 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -680,7 +680,7 @@ do_build_copy_constructor (tree fndecl) else if (tree_int_cst_equal (TYPE_SIZE (current_class_type), CLASSTYPE_SIZE (current_class_type))) { - tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm); + tree t = cp_build_init_expr (current_class_ref, parm); finish_expr_stmt (t); } else @@ -695,7 +695,7 @@ do_build_copy_constructor (tree fndecl) current_class_ptr, alias_set); tree rhs = build2 (MEM_REF, array_type, TREE_OPERAND (parm, 0), alias_set); - tree t = build2 (INIT_EXPR, void_type_node, lhs, rhs); + tree t = cp_build_init_expr (lhs, rhs); finish_expr_stmt (t); } } |