From b6d846de2be1df6fe282b0b4094ec9cdb9268d88 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 30 Jul 2013 09:28:31 -0400 Subject: [PATCH] re PR c++/57901 (Cannot call-by-value such that class has non-trivial (constexpr) move constructor) PR c++/57901 * semantics.c (build_data_member_initialization, constexpr_fn_retval): Use break_out_target_exprs instead of unshare_expr. From-SVN: r201338 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/semantics.c | 6 +++--- gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1bedc846215..72acda1cba8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-07-29 Jason Merrill + + PR c++/57901 + * semantics.c (build_data_member_initialization, constexpr_fn_retval): + Use break_out_target_exprs instead of unshare_expr. + 2013-07-29 Paolo Carlini PR c++/57948 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f68d3863ab1..acdd1788f6e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6016,7 +6016,7 @@ build_data_member_initialization (tree t, vec **vec) || TREE_CODE (t) == MODIFY_EXPR) { member = TREE_OPERAND (t, 0); - init = unshare_expr (TREE_OPERAND (t, 1)); + init = break_out_target_exprs (TREE_OPERAND (t, 1)); } else if (TREE_CODE (t) == CALL_EXPR) { @@ -6024,7 +6024,7 @@ build_data_member_initialization (tree t, vec **vec) /* We don't use build_cplus_new here because it complains about abstract bases. Leaving the call unwrapped means that it has the wrong type, but cxx_eval_constant_expression doesn't care. */ - init = unshare_expr (t); + init = break_out_target_exprs (t); } else if (TREE_CODE (t) == DECL_EXPR) /* Declaring a temporary, don't add it to the CONSTRUCTOR. */ @@ -6261,7 +6261,7 @@ constexpr_fn_retval (tree body) } case RETURN_EXPR: - return unshare_expr (TREE_OPERAND (body, 0)); + return break_out_target_exprs (TREE_OPERAND (body, 0)); case DECL_EXPR: if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C new file mode 100644 index 00000000000..1fc3738554e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C @@ -0,0 +1,16 @@ +// PR c++/57901 +// { dg-require-effective-target c++11 } + +struct Z { + Z() = default; + Z(Z const&) = default; + constexpr Z(Z&&) {} /* non-trivial (constexpr) move ctor */ +}; + +template +constexpr int fn0(T v) { return 0; } +template +constexpr int fn (T v) { return fn0(v); } + +constexpr auto t0 = fn0(Z()); // OK! +constexpr auto t = fn (Z()); // error! (GCC 4.8.1) -- 2.30.2