aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-10-05 18:59:02 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-10-05 18:59:02 -0400
commitbf9b09fbe23d4efb07eec21bbb3f73f1a075cb2b (patch)
tree5a876d8698a058b630252e34bb1ce6e5df218eed /gcc
parent5794b9f622dce668aa92ebabdf26abd0e799c665 (diff)
downloadgcc-bf9b09fbe23d4efb07eec21bbb3f73f1a075cb2b.zip
gcc-bf9b09fbe23d4efb07eec21bbb3f73f1a075cb2b.tar.gz
gcc-bf9b09fbe23d4efb07eec21bbb3f73f1a075cb2b.tar.bz2
Implement P0135R1, Guaranteed copy elision.
* cvt.c (ocp_convert): Don't re-copy a TARGET_EXPR in C++17. From-SVN: r240820
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/cvt.c7
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/elide1.C16
3 files changed, 24 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 569d696..7bd7db6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2016-10-05 Jason Merrill <jason@redhat.com>
+ Implement P0135R1, Guaranteed copy elision.
+ * cvt.c (ocp_convert): Don't re-copy a TARGET_EXPR in C++17.
+
PR c++/54293
* call.c (reference_binding): Fix binding to member of temporary.
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 2f5f15a..ecc8ef8 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -693,8 +693,11 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
if (error_operand_p (e))
return error_mark_node;
- if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP))
- /* We need a new temporary; don't take this shortcut. */;
+ if (MAYBE_CLASS_TYPE_P (type) && (convtype & CONV_FORCE_TEMP)
+ && !(cxx_dialect >= cxx1z
+ && TREE_CODE (e) == TARGET_EXPR))
+ /* We need a new temporary; don't take this shortcut. But in C++17, don't
+ force a temporary if we already have one. */;
else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e)))
{
if (same_type_p (type, TREE_TYPE (e)))
diff --git a/gcc/testsuite/g++.dg/cpp1z/elide1.C b/gcc/testsuite/g++.dg/cpp1z/elide1.C
new file mode 100644
index 0000000..a0538bb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/elide1.C
@@ -0,0 +1,16 @@
+// { dg-options -std=c++1z }
+
+struct A
+{
+ A();
+ A(const A&) = delete;
+};
+
+bool b;
+A a = A();
+A a1 = b ? A() : A();
+A a2 = (42, A());
+
+A f();
+A a3 = f();
+A a4 = b ? A() : f();