OSDN Git Service

PR c++/54506
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Sep 2012 14:24:19 +0000 (14:24 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 10 Sep 2012 14:24:19 +0000 (14:24 +0000)
* decl.c (move_signature_fn_p): Split out from move_fn_p.
* method.c (process_subob_fn): Use it.
* cp-tree.h: Declare it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@191146 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/implicit14.C [new file with mode: 0644]

index 25d48c5..f33a6e3 100644 (file)
@@ -1,5 +1,10 @@
 2012-09-10  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54506
+       * decl.c (move_signature_fn_p): Split out from move_fn_p.
+       * method.c (process_subob_fn): Use it.
+       * cp-tree.h: Declare it.
+
        PR c++/54341
        PR c++/54253
        * semantics.c (sort_constexpr_mem_initializers): New.
index 4b3c77d..3126963 100644 (file)
@@ -5042,6 +5042,7 @@ extern tree build_ptrmem_type                     (tree, tree);
 extern tree build_this_parm                    (tree, cp_cv_quals);
 extern int copy_fn_p                           (const_tree);
 extern bool move_fn_p                           (const_tree);
+extern bool move_signature_fn_p                 (const_tree);
 extern tree get_scope_of_declarator            (const cp_declarator *);
 extern void grok_special_member_properties     (tree);
 extern int grok_ctor_properties                        (const_tree, const_tree);
index bd6efd9..2379489 100644 (file)
@@ -10843,10 +10843,6 @@ copy_fn_p (const_tree d)
 bool
 move_fn_p (const_tree d)
 {
-  tree args;
-  tree arg_type;
-  bool result = false;
-
   gcc_assert (DECL_FUNCTION_MEMBER_P (d));
 
   if (cxx_dialect == cxx98)
@@ -10856,12 +10852,29 @@ move_fn_p (const_tree d)
   if (TREE_CODE (d) == TEMPLATE_DECL
       || (DECL_TEMPLATE_INFO (d)
          && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
-    /* Instantiations of template member functions are never copy
+    /* Instantiations of template member functions are never move
        functions.  Note that member functions of templated classes are
        represented as template functions internally, and we must
-       accept those as copy functions.  */
+       accept those as move functions.  */
     return 0;
 
+  return move_signature_fn_p (d);
+}
+
+/* D is a constructor or overloaded `operator='.
+
+   Then, this function returns true when D has the same signature as a move
+   constructor or move assignment operator (because either it is such a
+   ctor/op= or it is a template specialization with the same signature),
+   false otherwise.  */
+
+bool
+move_signature_fn_p (const_tree d)
+{
+  tree args;
+  tree arg_type;
+  bool result = false;
+
   args = FUNCTION_FIRST_USER_PARMTYPE (d);
   if (!args)
     return 0;
index c4947d1..e73cf5d 100644 (file)
@@ -949,9 +949,10 @@ process_subob_fn (tree fn, bool move_p, tree *spec_p, bool *trivial_p,
        }
     }
 
-  /* Core 1402: A non-trivial copy op suppresses the implicit
+  /* Core 1402: A non-trivial non-move ctor suppresses the implicit
      declaration of the move ctor/op=.  */
-  if (no_implicit_p && move_p && !move_fn_p (fn) && !trivial_fn_p (fn))
+  if (no_implicit_p && move_p && !move_signature_fn_p (fn)
+      && !trivial_fn_p (fn))
     *no_implicit_p = true;
 
   if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
index 9846aa6..04c5d2d 100644 (file)
@@ -1,5 +1,8 @@
 2012-09-10  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54506
+       * g++.dg/cpp0x/implicit14.C: New.
+
        PR c++/54341
        PR c++/54253
        * g++.dg/cpp0x/constexpr-virtual2.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit14.C b/gcc/testsuite/g++.dg/cpp0x/implicit14.C
new file mode 100644 (file)
index 0000000..8a56244
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/54506
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct A
+{
+  A() {}
+
+  A(A const volatile &&) = delete;
+  A &operator =(A const volatile &&) = delete;
+
+  template <class U> A(A<U> &&) {}
+  template <class U> A &operator =(A<U> &&) { return *this; }
+};
+
+struct B
+{
+  A<int> a;
+  B() = default;
+};
+
+int main()
+{
+  B b = B();
+  b = B();
+}