diff options
author | Jason Merrill <jason@redhat.com> | 2013-07-30 09:28:31 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-07-30 09:28:31 -0400 |
commit | b6d846de2be1df6fe282b0b4094ec9cdb9268d88 (patch) | |
tree | d1ad9f0bc1432c5f5782a879e9fe3fb28d01c148 /gcc | |
parent | 1b798a0fe160162efebffb974ebb67ed2456466a (diff) | |
download | gcc-b6d846de2be1df6fe282b0b4094ec9cdb9268d88.zip gcc-b6d846de2be1df6fe282b0b4094ec9cdb9268d88.tar.gz gcc-b6d846de2be1df6fe282b0b4094ec9cdb9268d88.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C | 16 |
3 files changed, 25 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1bedc84..72acda1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-07-29 Jason Merrill <jason@redhat.com> + + 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 <paolo.carlini@oracle.com> PR c++/57948 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f68d386..acdd178 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6016,7 +6016,7 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **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<constructor_elt, va_gc> **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 0000000..1fc3738 --- /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<typename T> +constexpr int fn0(T v) { return 0; } +template<typename T> +constexpr int fn (T v) { return fn0(v); } + +constexpr auto t0 = fn0(Z()); // OK! +constexpr auto t = fn (Z()); // error! (GCC 4.8.1) |