Commit a2e70335 by Jason Merrill Committed by Jason Merrill

re PR c++/50500 ([C++0x] [DR 1082] move constructor should cause copy…

re PR c++/50500 ([C++0x] [DR 1082] move constructor should cause copy constructor to be deleted, but still declared)

	PR c++/50500
	DR 1082
	* class.c (type_has_user_declared_move_constructor): New.
	(type_has_user_declared_move_assign): New.
	(add_implicitly_declared_members): Add lazy copy ops
	even if there's a move.
	* method.c (lazily_declare_fn): Delete implicit copies
	if there's a move.
	(maybe_explain_implicit_delete): Explain this.  Use inform rather
	than error.
	* cp-tree.h: Declare new fns.

From-SVN: r180159
parent c5d94218
2011-10-18 Jason Merrill <jason@redhat.com>
PR c++/50500
DR 1082
* class.c (type_has_user_declared_move_constructor): New.
(type_has_user_declared_move_assign): New.
(add_implicitly_declared_members): Add lazy copy ops
even if there's a move.
* method.c (lazily_declare_fn): Delete implicit copies
if there's a move.
(maybe_explain_implicit_delete): Explain this. Use inform rather
than error.
* cp-tree.h: Declare new fns.
2011-10-18 Diego Novillo <dnovillo@google.com> 2011-10-18 Diego Novillo <dnovillo@google.com>
* parser.c: Remove ENABLE_CHECKING markers around debugging * parser.c: Remove ENABLE_CHECKING markers around debugging
......
...@@ -2736,13 +2736,12 @@ add_implicitly_declared_members (tree t, ...@@ -2736,13 +2736,12 @@ add_implicitly_declared_members (tree t,
If a class definition does not explicitly declare a copy If a class definition does not explicitly declare a copy
constructor, one is declared implicitly. */ constructor, one is declared implicitly. */
if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t) if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t))
&& !type_has_move_constructor (t))
{ {
TYPE_HAS_COPY_CTOR (t) = 1; TYPE_HAS_COPY_CTOR (t) = 1;
TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor; TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor;
CLASSTYPE_LAZY_COPY_CTOR (t) = 1; CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
if (cxx_dialect >= cxx0x) if (cxx_dialect >= cxx0x && !type_has_move_constructor (t))
CLASSTYPE_LAZY_MOVE_CTOR (t) = 1; CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
} }
...@@ -2750,13 +2749,12 @@ add_implicitly_declared_members (tree t, ...@@ -2750,13 +2749,12 @@ add_implicitly_declared_members (tree t,
when it is needed. For now, just record whether or not the type when it is needed. For now, just record whether or not the type
of the parameter to the assignment operator will be a const or of the parameter to the assignment operator will be a const or
non-const reference. */ non-const reference. */
if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t) if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t))
&& !type_has_move_assign (t))
{ {
TYPE_HAS_COPY_ASSIGN (t) = 1; TYPE_HAS_COPY_ASSIGN (t) = 1;
TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment; TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1; CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
if (cxx_dialect >= cxx0x) if (cxx_dialect >= cxx0x && !type_has_move_assign (t))
CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1; CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
} }
...@@ -4495,6 +4493,54 @@ type_has_move_assign (tree t) ...@@ -4495,6 +4493,54 @@ type_has_move_assign (tree t)
return false; return false;
} }
/* Returns true iff class T has a move constructor that was explicitly
declared in the class body. Note that this is different from
"user-provided", which doesn't include functions that are defaulted in
the class. */
bool
type_has_user_declared_move_constructor (tree t)
{
tree fns;
if (CLASSTYPE_LAZY_MOVE_CTOR (t))
return false;
if (!CLASSTYPE_METHOD_VEC (t))
return false;
for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
return true;
}
return false;
}
/* Returns true iff class T has a move assignment operator that was
explicitly declared in the class body. */
bool
type_has_user_declared_move_assign (tree t)
{
tree fns;
if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
return false;
for (fns = lookup_fnfields_slot (t, ansi_assopname (NOP_EXPR));
fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn))
return true;
}
return false;
}
/* Nonzero if we need to build up a constructor call when initializing an /* Nonzero if we need to build up a constructor call when initializing an
object of this class, either because it has a user-provided constructor object of this class, either because it has a user-provided constructor
or because it doesn't have a default constructor (so we need to give an or because it doesn't have a default constructor (so we need to give an
......
...@@ -4870,6 +4870,8 @@ extern bool type_has_constexpr_default_constructor (tree); ...@@ -4870,6 +4870,8 @@ extern bool type_has_constexpr_default_constructor (tree);
extern bool type_has_virtual_destructor (tree); extern bool type_has_virtual_destructor (tree);
extern bool type_has_move_constructor (tree); extern bool type_has_move_constructor (tree);
extern bool type_has_move_assign (tree); extern bool type_has_move_assign (tree);
extern bool type_has_user_declared_move_constructor (tree);
extern bool type_has_user_declared_move_assign(tree);
extern bool type_build_ctor_call (tree); extern bool type_build_ctor_call (tree);
extern void explain_non_literal_class (tree); extern void explain_non_literal_class (tree);
extern void defaulted_late_check (tree); extern void defaulted_late_check (tree);
......
...@@ -1375,18 +1375,31 @@ maybe_explain_implicit_delete (tree decl) ...@@ -1375,18 +1375,31 @@ maybe_explain_implicit_delete (tree decl)
{ {
informed = true; informed = true;
if (sfk == sfk_constructor) if (sfk == sfk_constructor)
error ("a lambda closure type has a deleted default constructor"); inform (DECL_SOURCE_LOCATION (decl),
"a lambda closure type has a deleted default constructor");
else if (sfk == sfk_copy_assignment) else if (sfk == sfk_copy_assignment)
error ("a lambda closure type has a deleted copy assignment operator"); inform (DECL_SOURCE_LOCATION (decl),
"a lambda closure type has a deleted copy assignment operator");
else else
informed = false; informed = false;
} }
else if (DECL_ARTIFICIAL (decl)
&& (sfk == sfk_copy_assignment
|| sfk == sfk_copy_constructor)
&& (type_has_user_declared_move_constructor (ctype)
|| type_has_user_declared_move_assign (ctype)))
{
inform (0, "%q+#D is implicitly declared as deleted because %qT "
"declares a move constructor or move assignment operator",
decl, ctype);
informed = true;
}
if (!informed) if (!informed)
{ {
tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl)); tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
bool const_p = CP_TYPE_CONST_P (non_reference (parm_type)); bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
tree scope = push_scope (ctype); tree scope = push_scope (ctype);
error ("%qD is implicitly deleted because the default " inform (0, "%q+#D is implicitly deleted because the default "
"definition would be ill-formed:", decl); "definition would be ill-formed:", decl);
pop_scope (scope); pop_scope (scope);
synthesized_method_walk (ctype, sfk, const_p, synthesized_method_walk (ctype, sfk, const_p,
...@@ -1743,6 +1756,15 @@ lazily_declare_fn (special_function_kind sfk, tree type) ...@@ -1743,6 +1756,15 @@ lazily_declare_fn (special_function_kind sfk, tree type)
/* Declare the function. */ /* Declare the function. */
fn = implicitly_declare_fn (sfk, type, const_p); fn = implicitly_declare_fn (sfk, type, const_p);
/* [class.copy]/8 If the class definition declares a move constructor or
move assignment operator, the implicitly declared copy constructor is
defined as deleted.... */
if ((sfk == sfk_copy_assignment
|| sfk == sfk_copy_constructor)
&& (type_has_user_declared_move_constructor (type)
|| type_has_user_declared_move_assign (type)))
DECL_DELETED_FN (fn) = true;
/* For move variants, rather than declare them as deleted we just /* For move variants, rather than declare them as deleted we just
don't declare them at all. */ don't declare them at all. */
if (DECL_DELETED_FN (fn) if (DECL_DELETED_FN (fn)
......
2011-10-18 Jason Merrill <jason@redhat.com>
PR c++/50500
* g++.dg/cpp0x/implicit12.C: New.
* g++.dg/cpp0x/defaulted20.C: Adjust.
* g++.dg/cpp0x/defaulted21.C: Adjust.
* g++.dg/cpp0x/implicit-copy.C: Adjust.
* g++.dg/cpp0x/implicit4.C: Adjust.
* g++.dg/cpp0x/implicit5.C: Adjust.
* g++.dg/cpp0x/implicit8.C: Adjust.
* g++.dg/cpp0x/lambda/lambda-ice2.C: Adjust.
* g++.dg/cpp0x/not_special.C: Adjust.
* g++.dg/cpp0x/rv-trivial-bug.C: Adjust.
* g++.dg/cpp0x/rv1n.C: Adjust.
* g++.dg/cpp0x/rv2n.C: Adjust.
* g++.dg/cpp0x/rv3n.C: Adjust.
* g++.dg/cpp0x/rv4n.C: Adjust.
* g++.dg/cpp0x/rv5n.C: Adjust.
* g++.dg/cpp0x/rv6n.C: Adjust.
* g++.dg/cpp0x/rv7n.C: Adjust.
2011-10-18 Kirill Yukhin <kirill.yukhin@intel.com> 2011-10-18 Kirill Yukhin <kirill.yukhin@intel.com>
* gcc.target/i386/avx2-vpop-check.h: New header. * gcc.target/i386/avx2-vpop-check.h: New header.
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
// { dg-options -std=c++0x } // { dg-options -std=c++0x }
struct A { struct A {
A(A&&) = default; // { dg-message "A::A|no known conversion" } A(A&&) = default;
}; };
struct B { struct B {
const A a; const A a;
B(const B&) = default; B(const B&) = default;
B(B&&) = default; // { dg-error "implicitly deleted|no match" } B(B&&) = default; // { dg-error "implicitly deleted|use of deleted" }
// { dg-message "candidate" "candidate note" { target *-*-* } 10 }
}; };
void g(B); // { dg-error "argument 1" } void g(B); // { dg-error "argument 1" }
......
...@@ -12,7 +12,7 @@ struct X { ...@@ -12,7 +12,7 @@ struct X {
X(X&&); X(X&&);
}; };
X::X(X&&)=default; // { dg-error "implicitly deleted" } X::X(X&&)=default; // { dg-message "implicitly deleted" }
// { dg-error "does not have a move constructor" "" { target *-*-* } 15 } // { dg-error "does not have a move constructor" "" { target *-*-* } 15 }
X f() { X f() {
......
...@@ -3,13 +3,13 @@ struct S ...@@ -3,13 +3,13 @@ struct S
{ {
S(); S();
private: private:
S(S const &&); // { dg-error "" } S(S const &&);
S & operator=(S const &&); // { dg-error "" } S & operator=(S const &&);
}; };
void f() void f()
{ {
S a; S a;
S b(a); // { dg-error "" } S b(a); // { dg-error "deleted" }
a = b; // { dg-error "" } a = b; // { dg-error "deleted" }
} }
// PR c++/50500
// { dg-options "-std=c++0x" }
// If a class declares move operations, the implicitly declared copy
// operations are deleted.
struct A
{
A();
A(A&&);
A& operator=(A&&);
};
// But they can still be explicitly defaulted.
struct B
{
B();
B(B&&);
B(const B&) = default;
B& operator=(B&&);
B& operator=(const B&) = default;
};
struct C
{
C();
C(C&&);
};
struct D
{
D();
D& operator=(D&&);
};
int main()
{
A a;
A a2 (a); // { dg-error "deleted" }
a2 = a; // { dg-error "deleted" }
B b;
B b2 (b);
b2 = b;
C c;
C c2(c); // { dg-error "deleted" }
c2 = c; // { dg-error "deleted" }
D d;
D d2(d); // { dg-error "deleted" }
d2 = d; // { dg-error "deleted" }
}
// { dg-prune-output "because" }
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
// constructor to be deleted. // constructor to be deleted.
// { dg-options "-std=c++0x" } // { dg-options "-std=c++0x" }
struct A struct A // { dg-message "declares a move" }
{ {
A(); // { dg-message "A::A|candidate expects" } A();
A(A&&); // { dg-message "A::A|no known conversion" } A(A&&);
}; };
struct B: A // { dg-error "implicit|no match" } struct B: A // { dg-error "use of deleted" }
// { dg-message "candidate" "candidate note" { target *-*-* } 11 }
{ {
}; };
......
// Test that the default B copy constructor calls the A member template // Test that the default B copy constructor calls the deleted A
// constructor. // copy constructor.
// { dg-options -std=c++0x } // { dg-options -std=c++0x }
struct A struct A // { dg-message "declares a move" }
{ {
A() = default; A() = default;
A(A&&) = default; A(A&&) = default;
template <class T> template <class T>
A(const T& t) { t.i; } // { dg-error "no member" } A(const T& t) { t.i; }
}; };
struct B: A { }; struct B: A { }; // { dg-error "implicitly|use of deleted" }
int main() int main()
{ {
B b; B b;
B b2(b); B b2(b); // { dg-error "deleted" }
} }
// The hack for PR c++/44909 breaks this testcase. We need feedback // The hack for PR c++/44909 breaks this testcase. We need feedback
// from the C++ committee to know how to proceed. // from the C++ committee to know how to proceed.
// { dg-options -std=c++0x } // { dg-options -std=c++0x }
// { dg-prune-output "implicitly deleted" }
// { dg-prune-output "cannot bind" }
// { dg-prune-output "initializing argument" }
struct A struct A
{ {
...@@ -28,7 +25,8 @@ struct B ...@@ -28,7 +25,8 @@ struct B
// subobject of C should use B(const BP&). But we ignore that constructor // subobject of C should use B(const BP&). But we ignore that constructor
// in order to break the cycle in 44909. Perhaps the move ctor shouldn't // in order to break the cycle in 44909. Perhaps the move ctor shouldn't
// suppress the copy ctor? // suppress the copy ctor?
struct C: A, B { }; // As of DR 1082, it doesn't suppress it.
struct C: A, B { }; // { dg-error "use of deleted" }
C c; C c;
C c2(c); // { dg-bogus "deleted" "" { xfail *-*-* } } C c2(c); // { dg-error "deleted" }
...@@ -9,7 +9,7 @@ decltype(F()) run(F f) // { dg-message "note" } ...@@ -9,7 +9,7 @@ decltype(F()) run(F f) // { dg-message "note" }
int main() int main()
{ {
auto l = []() { return 5; }; // { dg-error "lambda closure type" } auto l = []() { return 5; }; // { dg-message "lambda closure type" }
run(l); // { dg-error "no match" } run(l); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 14 } // { dg-message "candidate" "candidate note" { target *-*-* } 14 }
......
// I, Howard Hinnant, hereby place this code in the public domain. // I, Howard Hinnant, hereby place this code in the public domain.
// Test that move constructor and move assignement are special. // Test that move constructor and move assignement are special.
// That is, their presence should inhibit compiler generated // That is, their presence should cause compiler declared
// copy ctor or assignment. // copy ctor or assignment to be deleted.
// { dg-options "-std=c++0x" } // { dg-options "-std=c++0x" }
...@@ -24,12 +24,12 @@ struct base ...@@ -24,12 +24,12 @@ struct base
base& operator=(const base&) {++assign; return *this;} base& operator=(const base&) {++assign; return *this;}
}; };
struct derived struct derived // { dg-message "declares a move" }
: base : base
{ {
derived() {} derived() {}
derived(derived&&) {} // { dg-error "argument 1" } derived(derived&&) {}
derived& operator=(derived&&) {return *this;} // { dg-error "argument 1" } derived& operator=(derived&&) {return *this;}
}; };
int test1() int test1()
...@@ -37,11 +37,11 @@ int test1() ...@@ -37,11 +37,11 @@ int test1()
derived d; derived d;
derived d2(static_cast<derived&&>(d)); // should not call base::(const base&) derived d2(static_cast<derived&&>(d)); // should not call base::(const base&)
assert(copy == 0); assert(copy == 0);
derived d3(d); // { dg-error "lvalue" } derived d3(d); // { dg-error "deleted" }
assert(copy == 1); assert(copy == 1);
d2 = static_cast<derived&&>(d); // should not call base::operator= d2 = static_cast<derived&&>(d); // should not call base::operator=
assert(assign == 0); assert(assign == 0);
d3 = d; // { dg-error "lvalue" } d3 = d; // { dg-error "deleted" }
assert(assign == 1); assert(assign == 1);
return 0; return 0;
} }
......
...@@ -5,22 +5,22 @@ ...@@ -5,22 +5,22 @@
int move_construct = 0; int move_construct = 0;
int move_assign = 0; int move_assign = 0;
struct base2 struct base2 // { dg-message "declares a move" }
{ {
base2() {} base2() {}
base2(base2&&) {++move_construct;} // { dg-error "argument 1" } base2(base2&&) {++move_construct;}
base2& operator=(base2&&) {++move_assign; return *this;} // { dg-error "argument 1" } base2& operator=(base2&&) {++move_assign; return *this;}
}; };
int test2() int test2()
{ {
base2 b; base2 b;
base2 b2(b); // { dg-error "lvalue" } base2 b2(b); // { dg-error "deleted" }
assert(move_construct == 0); assert(move_construct == 0);
base2 b3(static_cast<base2&&>(b)); base2 b3(static_cast<base2&&>(b));
base2 b4 = static_cast<base2&&>(b); base2 b4 = static_cast<base2&&>(b);
assert(move_construct == 2); assert(move_construct == 2);
b = b2; // { dg-error "lvalue" } b = b2; // { dg-error "deleted" }
assert(move_assign == 0); assert(move_assign == 0);
b = static_cast<base2&&>(b2); b = static_cast<base2&&>(b2);
assert(move_assign == 1); assert(move_assign == 1);
......
...@@ -20,7 +20,7 @@ struct eight {char x[8];}; ...@@ -20,7 +20,7 @@ struct eight {char x[8];};
struct A struct A
{ {
A(); A();
A(const volatile A&&); // { dg-error "argument 1" } A(const volatile A&&);
}; };
A source(); A source();
...@@ -35,9 +35,9 @@ one sink_1_1( A&); // { dg-error "" } ...@@ -35,9 +35,9 @@ one sink_1_1( A&); // { dg-error "" }
int test1_1() int test1_1()
{ {
A a; A a;
const A ca = a; // { dg-error "cannot bind" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "cannot bind" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_1(ca); // { dg-error "invalid initialization" } sink_1_1(ca); // { dg-error "invalid initialization" }
sink_1_1(va); // { dg-error "invalid initialization" } sink_1_1(va); // { dg-error "invalid initialization" }
sink_1_1(cva); // { dg-error "invalid initialization" } sink_1_1(cva); // { dg-error "invalid initialization" }
...@@ -53,9 +53,9 @@ two sink_1_2(const A&); // { dg-error "" } ...@@ -53,9 +53,9 @@ two sink_1_2(const A&); // { dg-error "" }
int test1_2() int test1_2()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_2(va); // { dg-error "invalid initialization" } sink_1_2(va); // { dg-error "invalid initialization" }
sink_1_2(cva); // { dg-error "invalid initialization" } sink_1_2(cva); // { dg-error "invalid initialization" }
sink_1_2(v_source()); // { dg-error "invalid initialization" } sink_1_2(v_source()); // { dg-error "invalid initialization" }
...@@ -68,9 +68,9 @@ three sink_1_3(volatile A&); // { dg-error "" } ...@@ -68,9 +68,9 @@ three sink_1_3(volatile A&); // { dg-error "" }
int test1_3() int test1_3()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_3(ca); // { dg-error "invalid initialization" } sink_1_3(ca); // { dg-error "invalid initialization" }
sink_1_3(cva); // { dg-error "invalid initialization" } sink_1_3(cva); // { dg-error "invalid initialization" }
sink_1_3(source()); // { dg-error "invalid initialization" } sink_1_3(source()); // { dg-error "invalid initialization" }
...@@ -85,9 +85,9 @@ four sink_1_4(const volatile A&); // { dg-error "" } ...@@ -85,9 +85,9 @@ four sink_1_4(const volatile A&); // { dg-error "" }
int test1_4() int test1_4()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_4(source()); // { dg-error "invalid initialization" } sink_1_4(source()); // { dg-error "invalid initialization" }
sink_1_4(c_source()); // { dg-error "invalid initialization" } sink_1_4(c_source()); // { dg-error "invalid initialization" }
sink_1_4(v_source()); // { dg-error "invalid initialization" } sink_1_4(v_source()); // { dg-error "invalid initialization" }
...@@ -100,9 +100,9 @@ five sink_1_5( A&&); // { dg-error "" } ...@@ -100,9 +100,9 @@ five sink_1_5( A&&); // { dg-error "" }
int test1_5() int test1_5()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_5(a); // { dg-error "lvalue" } sink_1_5(a); // { dg-error "lvalue" }
sink_1_5(ca); // { dg-error "invalid initialization" } sink_1_5(ca); // { dg-error "invalid initialization" }
sink_1_5(va); // { dg-error "invalid initialization" } sink_1_5(va); // { dg-error "invalid initialization" }
...@@ -118,9 +118,9 @@ six sink_1_6(const A&&); // { dg-error "" } ...@@ -118,9 +118,9 @@ six sink_1_6(const A&&); // { dg-error "" }
int test1_6() int test1_6()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_6(a); // { dg-error "lvalue" } sink_1_6(a); // { dg-error "lvalue" }
sink_1_6(ca); // { dg-error "lvalue" } sink_1_6(ca); // { dg-error "lvalue" }
sink_1_6(va); // { dg-error "invalid initialization" } sink_1_6(va); // { dg-error "invalid initialization" }
...@@ -135,9 +135,9 @@ seven sink_1_7(volatile A&&); // { dg-error "" } ...@@ -135,9 +135,9 @@ seven sink_1_7(volatile A&&); // { dg-error "" }
int test1_7() int test1_7()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_7(a); // { dg-error "lvalue" } sink_1_7(a); // { dg-error "lvalue" }
sink_1_7(ca); // { dg-error "invalid initialization" } sink_1_7(ca); // { dg-error "invalid initialization" }
sink_1_7(va); // { dg-error "lvalue" } sink_1_7(va); // { dg-error "lvalue" }
...@@ -152,9 +152,9 @@ eight sink_1_8(const volatile A&&); // { dg-error "" } ...@@ -152,9 +152,9 @@ eight sink_1_8(const volatile A&&); // { dg-error "" }
int test1_8() int test1_8()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_1_8(a); // { dg-error "lvalue" } sink_1_8(a); // { dg-error "lvalue" }
sink_1_8(ca); // { dg-error "lvalue" } sink_1_8(ca); // { dg-error "lvalue" }
sink_1_8(va); // { dg-error "lvalue" } sink_1_8(va); // { dg-error "lvalue" }
......
...@@ -20,7 +20,7 @@ struct eight {char x[8];}; ...@@ -20,7 +20,7 @@ struct eight {char x[8];};
struct A struct A
{ {
A(); A();
A(const volatile A&&); // { dg-error "argument 1" } A(const volatile A&&);
}; };
A source(); A source();
...@@ -40,9 +40,9 @@ six sink_6_123456(const A&&); // { dg-message "note" } ...@@ -40,9 +40,9 @@ six sink_6_123456(const A&&); // { dg-message "note" }
int test6_123456() int test6_123456()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123456(v_source()); // { dg-error "no match" } sink_6_123456(v_source()); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 46 } // { dg-message "candidate" "candidate note" { target *-*-* } 46 }
sink_6_123456(cv_source()); // { dg-error "no match" } sink_6_123456(cv_source()); // { dg-error "no match" }
...@@ -60,9 +60,9 @@ seven sink_6_123457(volatile A&&); // { dg-message "note" } ...@@ -60,9 +60,9 @@ seven sink_6_123457(volatile A&&); // { dg-message "note" }
int test6_123457() int test6_123457()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123457(cv_source()); // { dg-error "no match" } sink_6_123457(cv_source()); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 66 } // { dg-message "candidate" "candidate note" { target *-*-* } 66 }
return 0; return 0;
...@@ -78,9 +78,9 @@ eight sink_6_235678(const volatile A&&); // { dg-message "" } ...@@ -78,9 +78,9 @@ eight sink_6_235678(const volatile A&&); // { dg-message "" }
int test6_235678() int test6_235678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_235678(a); // { dg-error "ambiguous" } sink_6_235678(a); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 84 } // { dg-message "candidate" "candidate note" { target *-*-* } 84 }
sink_6_235678(cva); // { dg-error "lvalue" } sink_6_235678(cva); // { dg-error "lvalue" }
...@@ -97,9 +97,9 @@ eight sink_6_234678(const volatile A&&); // { dg-message "note" } ...@@ -97,9 +97,9 @@ eight sink_6_234678(const volatile A&&); // { dg-message "note" }
int test6_234678() int test6_234678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_234678(a); // { dg-error "ambiguous" } sink_6_234678(a); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 103 } // { dg-message "candidate" "candidate note" { target *-*-* } 103 }
sink_6_234678(source()); // { dg-error "ambiguous" } sink_6_234678(source()); // { dg-error "ambiguous" }
...@@ -117,9 +117,9 @@ eight sink_6_234578(const volatile A&&); // { dg-message "note" } ...@@ -117,9 +117,9 @@ eight sink_6_234578(const volatile A&&); // { dg-message "note" }
int test6_234578() int test6_234578()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_234578(a); // { dg-error "ambiguous" } sink_6_234578(a); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 123 } // { dg-message "candidate" "candidate note" { target *-*-* } 123 }
return 0; return 0;
...@@ -135,9 +135,9 @@ eight sink_6_234568(const volatile A&&); // { dg-message "note" } ...@@ -135,9 +135,9 @@ eight sink_6_234568(const volatile A&&); // { dg-message "note" }
int test6_234568() int test6_234568()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_234568(a); // { dg-error "ambiguous" } sink_6_234568(a); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 141 } // { dg-message "candidate" "candidate note" { target *-*-* } 141 }
return 0; return 0;
...@@ -153,9 +153,9 @@ seven sink_6_234567(volatile A&&); // { dg-message "note" } ...@@ -153,9 +153,9 @@ seven sink_6_234567(volatile A&&); // { dg-message "note" }
int test6_234567() int test6_234567()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_234567(a); // { dg-error "ambiguous" } sink_6_234567(a); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 159 } // { dg-message "candidate" "candidate note" { target *-*-* } 159 }
sink_6_234567(cv_source()); // { dg-error "no match" } sink_6_234567(cv_source()); // { dg-error "no match" }
...@@ -173,9 +173,9 @@ eight sink_6_134678(const volatile A&&); // { dg-message "note" } ...@@ -173,9 +173,9 @@ eight sink_6_134678(const volatile A&&); // { dg-message "note" }
int test6_134678() int test6_134678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_134678(source()); // { dg-error "ambiguous" } sink_6_134678(source()); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 179 } // { dg-message "candidate" "candidate note" { target *-*-* } 179 }
return 0; return 0;
...@@ -191,9 +191,9 @@ eight sink_6_124678(const volatile A&&); // { dg-message "note" } ...@@ -191,9 +191,9 @@ eight sink_6_124678(const volatile A&&); // { dg-message "note" }
int test6_124678() int test6_124678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_124678(source()); // { dg-error "ambiguous" } sink_6_124678(source()); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 197 } // { dg-message "candidate" "candidate note" { target *-*-* } 197 }
return 0; return 0;
...@@ -209,9 +209,9 @@ eight sink_6_123678(const volatile A&&); // { dg-message "" } ...@@ -209,9 +209,9 @@ eight sink_6_123678(const volatile A&&); // { dg-message "" }
int test6_123678() int test6_123678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123678(cva); // { dg-error "lvalue" } sink_6_123678(cva); // { dg-error "lvalue" }
sink_6_123678(source()); // { dg-error "ambiguous" } sink_6_123678(source()); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 216 } // { dg-message "candidate" "candidate note" { target *-*-* } 216 }
...@@ -228,9 +228,9 @@ seven sink_6_123567(volatile A&&); // { dg-message "note" } ...@@ -228,9 +228,9 @@ seven sink_6_123567(volatile A&&); // { dg-message "note" }
int test6_123567() int test6_123567()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123567(cva); // { dg-error "no match" } sink_6_123567(cva); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 234 } // { dg-message "candidate" "candidate note" { target *-*-* } 234 }
sink_6_123567(cv_source()); // { dg-error "no match" } sink_6_123567(cv_source()); // { dg-error "no match" }
...@@ -248,9 +248,9 @@ eight sink_6_123568(const volatile A&&); // { dg-message "" } ...@@ -248,9 +248,9 @@ eight sink_6_123568(const volatile A&&); // { dg-message "" }
int test6_123568() int test6_123568()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123568(cva); // { dg-error "lvalue" } sink_6_123568(cva); // { dg-error "lvalue" }
return 0; return 0;
} }
...@@ -265,9 +265,9 @@ eight sink_6_123578(const volatile A&&); // { dg-message "" } ...@@ -265,9 +265,9 @@ eight sink_6_123578(const volatile A&&); // { dg-message "" }
int test6_123578() int test6_123578()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123578(cva); // { dg-error "lvalue" } sink_6_123578(cva); // { dg-error "lvalue" }
return 0; return 0;
} }
...@@ -282,9 +282,9 @@ seven sink_6_123467(volatile A&&); // { dg-message "note" } ...@@ -282,9 +282,9 @@ seven sink_6_123467(volatile A&&); // { dg-message "note" }
int test6_123467() int test6_123467()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_123467(source()); // { dg-error "ambiguous" } sink_6_123467(source()); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 288 } // { dg-message "candidate" "candidate note" { target *-*-* } 288 }
sink_6_123467(cv_source()); // { dg-error "no match" } sink_6_123467(cv_source()); // { dg-error "no match" }
...@@ -302,9 +302,9 @@ seven sink_6_124567(volatile A&&); // { dg-message "note" } ...@@ -302,9 +302,9 @@ seven sink_6_124567(volatile A&&); // { dg-message "note" }
int test6_124567() int test6_124567()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_124567(cv_source()); // { dg-error "no match" } sink_6_124567(cv_source()); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 308 } // { dg-message "candidate" "candidate note" { target *-*-* } 308 }
return 0; return 0;
...@@ -320,9 +320,9 @@ eight sink_6_125678(const volatile A&&); // { dg-message "" } ...@@ -320,9 +320,9 @@ eight sink_6_125678(const volatile A&&); // { dg-message "" }
int test6_125678() int test6_125678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_125678(va); // { dg-error "lvalue" } sink_6_125678(va); // { dg-error "lvalue" }
sink_6_125678(cva); // { dg-error "lvalue" } sink_6_125678(cva); // { dg-error "lvalue" }
return 0; return 0;
...@@ -338,9 +338,9 @@ seven sink_6_134567(volatile A&&); // { dg-message "note" } ...@@ -338,9 +338,9 @@ seven sink_6_134567(volatile A&&); // { dg-message "note" }
int test6_134567() int test6_134567()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_134567(cv_source()); // { dg-error "no match" } sink_6_134567(cv_source()); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 344 } // { dg-message "candidate" "candidate note" { target *-*-* } 344 }
return 0; return 0;
...@@ -356,9 +356,9 @@ eight sink_6_135678(const volatile A&&); // { dg-message "" } ...@@ -356,9 +356,9 @@ eight sink_6_135678(const volatile A&&); // { dg-message "" }
int test6_135678() int test6_135678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_6_135678(ca); // { dg-error "lvalue" } sink_6_135678(ca); // { dg-error "lvalue" }
sink_6_135678(cva); // { dg-error "lvalue" } sink_6_135678(cva); // { dg-error "lvalue" }
return 0; return 0;
......
...@@ -20,7 +20,7 @@ struct eight {char x[8];}; ...@@ -20,7 +20,7 @@ struct eight {char x[8];};
struct A struct A
{ {
A(); A();
A(const volatile A&&); // { dg-error "argument 1" } A(const volatile A&&);
}; };
A source(); A source();
...@@ -41,9 +41,9 @@ seven sink_7_1234567(volatile A&&); // { dg-message "note" } ...@@ -41,9 +41,9 @@ seven sink_7_1234567(volatile A&&); // { dg-message "note" }
int test7_1234567() int test7_1234567()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_7_1234567(cv_source()); // { dg-error "no match" } sink_7_1234567(cv_source()); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 47 } // { dg-message "candidate" "candidate note" { target *-*-* } 47 }
return 0; return 0;
...@@ -60,9 +60,9 @@ eight sink_7_1235678(const volatile A&&); // { dg-message "" } ...@@ -60,9 +60,9 @@ eight sink_7_1235678(const volatile A&&); // { dg-message "" }
int test7_1235678() int test7_1235678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_7_1235678(cva); // { dg-error "lvalue" } sink_7_1235678(cva); // { dg-error "lvalue" }
return 0; return 0;
} }
...@@ -78,9 +78,9 @@ eight sink_7_2345678(const volatile A&&); // { dg-message "note" } ...@@ -78,9 +78,9 @@ eight sink_7_2345678(const volatile A&&); // { dg-message "note" }
int test7_2345678() int test7_2345678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_7_2345678(a); // { dg-error "ambiguous" } sink_7_2345678(a); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 84 } // { dg-message "candidate" "candidate note" { target *-*-* } 84 }
return 0; return 0;
...@@ -97,9 +97,9 @@ eight sink_7_1234678(const volatile A&&); // { dg-message "note" } ...@@ -97,9 +97,9 @@ eight sink_7_1234678(const volatile A&&); // { dg-message "note" }
int test7_1234678() int test7_1234678()
{ {
A a; A a;
const A ca = a; // { dg-error "lvalue" } const A ca = a; // { dg-error "deleted" }
volatile A va; volatile A va;
const volatile A cva = a; // { dg-error "lvalue" } const volatile A cva = a; // { dg-error "deleted" }
sink_7_1234678(source()); // { dg-error "ambiguous" } sink_7_1234678(source()); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 103 } // { dg-message "candidate" "candidate note" { target *-*-* } 103 }
return 0; return 0;
......
2011-10-18 Jason Merrill <jason@redhat.com>
PR c++/50500
* include/bits/shared_ptr.h: Default copy ctor and assignment.
* testsuite/util/testsuite_allocator.h: Define copy assignment.
* testsuite/util/testsuite_rvalref.h: Default copy assignment.
* testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Remove note tags.
2011-10-17 Michael Spertus <mike_spertus@symantec.com> 2011-10-17 Michael Spertus <mike_spertus@symantec.com>
* include/tr2/type_traits (bases, direct_bases, typelist): New. * include/tr2/type_traits (bases, direct_bases, typelist): New.
......
...@@ -211,6 +211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -211,6 +211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __r A %shared_ptr. * @param __r A %shared_ptr.
* @post get() == __r.get() && use_count() == __r.use_count() * @post get() == __r.get() && use_count() == __r.use_count()
*/ */
shared_ptr(const shared_ptr&) noexcept = default;
template<typename _Tp1, typename = typename template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
shared_ptr(const shared_ptr<_Tp1>& __r) noexcept shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
...@@ -264,6 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -264,6 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr shared_ptr(nullptr_t __p) noexcept constexpr shared_ptr(nullptr_t __p) noexcept
: __shared_ptr<_Tp>(__p) { } : __shared_ptr<_Tp>(__p) { }
shared_ptr& operator=(const shared_ptr&) noexcept = default;
template<typename _Tp1> template<typename _Tp1>
shared_ptr& shared_ptr&
operator=(const shared_ptr<_Tp1>& __r) noexcept operator=(const shared_ptr<_Tp1>& __r) noexcept
......
...@@ -41,19 +41,3 @@ main() ...@@ -41,19 +41,3 @@ main()
test01(); test01();
return 0; return 0;
} }
// { dg-warning "note" "" { target *-*-* } 370 }
// { dg-warning "note" "" { target *-*-* } 365 }
// { dg-warning "note" "" { target *-*-* } 356 }
// { dg-warning "note" "" { target *-*-* } 1103 }
// { dg-warning "note" "" { target *-*-* } 1098 }
// { dg-warning "note" "" { target *-*-* } 1089 }
// { dg-warning "note" "" { target *-*-* } 485 }
// { dg-warning "note" "" { target *-*-* } 479 }
// { dg-warning "note" "" { target *-*-* } 468 }
// { dg-warning "note" "" { target *-*-* } 841 }
// { dg-warning "note" "" { target *-*-* } 1056 }
// { dg-warning "note" "" { target *-*-* } 1050 }
// { dg-warning "note" "" { target *-*-* } 342 }
// { dg-warning "note" "" { target *-*-* } 292 }
// { dg-warning "note" "" { target *-*-* } 224 }
...@@ -409,6 +409,14 @@ namespace __gnu_test ...@@ -409,6 +409,14 @@ namespace __gnu_test
propagating_allocator(const propagating_allocator&) noexcept = default; propagating_allocator(const propagating_allocator&) noexcept = default;
propagating_allocator&
operator=(const propagating_allocator& a) noexcept
{
static_assert(Propagate, "assigning propagating_allocator<T, true>");
propagating_allocator(a).swap_base(*this);
return *this;
}
template<bool P2> template<bool P2>
propagating_allocator& propagating_allocator&
operator=(const propagating_allocator<Tp, P2>& a) noexcept operator=(const propagating_allocator<Tp, P2>& a) noexcept
......
...@@ -255,6 +255,9 @@ namespace __gnu_test ...@@ -255,6 +255,9 @@ namespace __gnu_test
{ throw 1; } { throw 1; }
throwing_move_constructor(const throwing_move_constructor&) = default; throwing_move_constructor(const throwing_move_constructor&) = default;
throwing_move_constructor&
operator=(const throwing_move_constructor&) = default;
}; };
} // namespace __gnu_test } // namespace __gnu_test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment