public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for P0135, C++17 guaranteed copy elision
@ 2016-10-05 22:57 Jason Merrill
  2016-10-05 23:16 ` Pedro Alves
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2016-10-05 22:57 UTC (permalink / raw)
  To: gcc-patches List; +Cc: Ville Voutilainen

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

C++17 changes how we describe prvalues so that they express
initialization of an object to be named later, rather than objects
themselves.  This happens to match the front end's use of TARGET_EXPR
pretty closely, so I think we don't need to do much more than disable
the code that forces us to copy a TARGET_EXPR into another
TARGET_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: elision.diff --]
[-- Type: text/plain, Size: 1910 bytes --]

commit 054719b1c1f71236999ea4082cb3207c42cf883c
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Oct 5 12:59:30 2016 -0400

            Implement P0135R1, Guaranteed copy elision.
    
            * c-opts.c (set_std_cxx1z): Set flag_elide_constructors to 2.
            * cvt.c (ocp_convert): Don't re-copy a TARGET_EXPR in C++17.

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index c5a699d..977348f1 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1579,6 +1579,7 @@ set_std_cxx1z (int iso)
   flag_isoc94 = 1;
   flag_isoc99 = 1;
   flag_isoc11 = 1;
+  flag_elide_constructors = 2;
   cxx_dialect = cxx1z;
   lang_hooks.name = "GNU C++14"; /* Pretend C++14 till standarization.  */
 }
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 2f5f15a..4de9745 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)
+      && !(flag_elide_constructors >= 2
+	   && 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();

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-10-08 16:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-05 22:57 C++ PATCH for P0135, C++17 guaranteed copy elision Jason Merrill
2016-10-05 23:16 ` Pedro Alves
2016-10-05 23:22   ` Jason Merrill
2016-10-06 21:26     ` Jason Merrill
2016-10-08 16:27       ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).