From: Jason Merrill Date: Mon, 10 Sep 2012 14:08:32 +0000 (-0400) Subject: re PR c++/54506 (Defaulted move constructors and move assignment operators are errone... X-Git-Tag: upstream/12.2.0~74360 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8f5a5a8ecd12377ea58ca7ddb326db59d6cd6436;p=platform%2Fupstream%2Fgcc.git re PR c++/54506 (Defaulted move constructors and move assignment operators are erroneously defined as deleted) 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. From-SVN: r191140 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 64b591f..2fd7c12 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-09-10 Jason Merrill + + 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. + 2012-09-07 Jason Merrill * semantics.c (sort_constexpr_mem_initializers): Tweak. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3e0fc3f..3c55ba4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5066,6 +5066,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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7655f78..e34092d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10859,10 +10859,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) @@ -10872,12 +10868,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; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index c21ae15..a42ed60 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -947,9 +947,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)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c977af8..65e31bd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-09-10 Jason Merrill + + PR c++/54506 + * g++.dg/cpp0x/implicit14.C: New. + 2012-09-07 Mikael Morin PR fortran/54208 diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit14.C b/gcc/testsuite/g++.dg/cpp0x/implicit14.C new file mode 100644 index 0000000..8a56244 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/implicit14.C @@ -0,0 +1,26 @@ +// PR c++/54506 +// { dg-do compile { target c++11 } } + +template +struct A +{ + A() {} + + A(A const volatile &&) = delete; + A &operator =(A const volatile &&) = delete; + + template A(A &&) {} + template A &operator =(A &&) { return *this; } +}; + +struct B +{ + A a; + B() = default; +}; + +int main() +{ + B b = B(); + b = B(); +}