Implement P0135R1, Guaranteed copy elision.
authorJason Merrill <jason@redhat.com>
Wed, 5 Oct 2016 22:59:02 +0000 (18:59 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 5 Oct 2016 22:59:02 +0000 (18:59 -0400)
* cvt.c (ocp_convert): Don't re-copy a TARGET_EXPR in C++17.

From-SVN: r240820

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/testsuite/g++.dg/cpp1z/elide1.C [new file with mode: 0644]

index 569d696546d7d1401f685f639d64f5bd0056fdde..7bd7db64f4efc0751e07180fb93c9fee845bdee8 100644 (file)
@@ -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.
 
index 2f5f15a2c8269c6f0ea003737b2828c4ee7ba203..ecc8ef82b2a25b49b1a968ca3d7766fda104efb0 100644 (file)
@@ -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 (file)
index 0000000..a0538bb
--- /dev/null
@@ -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();