diff mbox

C++ PATCH for c++/55017 (rvalue ref and defaulted copy constructor)

Message ID 5144C040.1060209@redhat.com
State New
Headers show

Commit Message

Jason Merrill March 16, 2013, 6:56 p.m. UTC
We were failing to enforce the rule that a field with rvalue reference 
type causes a defaulted copy constructor to be deleted.

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

Patch

commit 5e57beb36ec51c1e0a6f175142f89c8d4b782e30
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Feb 14 12:14:36 2013 -0500

    	PR c++/55017
    	* method.c (walk_field_subobs): Disallow copy of rvalue ref.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index ff29b59..55c7e50 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1115,6 +1115,19 @@  walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
 			"initialize %q+#D", field);
 	    }
 	}
+      else if (sfk == sfk_copy_constructor)
+	{
+	  /* 12.8p11b5 */
+	  if (TREE_CODE (mem_type) == REFERENCE_TYPE
+	      && TYPE_REF_IS_RVALUE (mem_type))
+	    {
+	      if (diag)
+		error ("copying non-static data member %q#D of rvalue "
+		       "reference type", field);
+	      if (deleted_p)
+		*deleted_p = true;
+	    }
+	}
 
       if (!CLASS_TYPE_P (mem_type))
 	continue;
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-copy1.C b/gcc/testsuite/g++.dg/cpp0x/rv-copy1.C
new file mode 100644
index 0000000..70d3d71
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-copy1.C
@@ -0,0 +1,10 @@ 
+// PR c++/55017
+// { dg-do compile { target c++11 } }
+
+struct S {			// { dg-error "rvalue ref" }
+  int&& rr;
+  S(int&& rr) : rr(static_cast<int&&>(rr)) {}
+};
+
+S s1(13);
+S s2 = s1;			// { dg-error "deleted" }
diff --git a/libstdc++-v3/testsuite/20_util/pair/piecewise2.cc b/libstdc++-v3/testsuite/20_util/pair/piecewise2.cc
index d53e49c..0273c14 100644
--- a/libstdc++-v3/testsuite/20_util/pair/piecewise2.cc
+++ b/libstdc++-v3/testsuite/20_util/pair/piecewise2.cc
@@ -51,7 +51,8 @@  struct Default
 void test01(std::tuple<NoCon&, NoCon&&> t1,
             std::tuple<NoCon&, NoCon&&, NoCon&> t2)
 {
-  std::pair<RefCheck1, RefCheck2>(std::piecewise_construct, t1, t2);
+  std::pair<RefCheck1, RefCheck2>(std::piecewise_construct,
+				  std::move(t1), std::move(t2));
 }
 
 void test02(std::tuple<> t1, std::tuple<int> t2)