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>
* parser.c: Remove ENABLE_CHECKING markers around debugging
......
......@@ -2736,13 +2736,12 @@ add_implicitly_declared_members (tree t,
If a class definition does not explicitly declare a copy
constructor, one is declared implicitly. */
if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t)
&& !type_has_move_constructor (t))
if (! TYPE_HAS_COPY_CTOR (t) && ! TYPE_FOR_JAVA (t))
{
TYPE_HAS_COPY_CTOR (t) = 1;
TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor;
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;
}
......@@ -2750,13 +2749,12 @@ add_implicitly_declared_members (tree t,
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
non-const reference. */
if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t)
&& !type_has_move_assign (t))
if (!TYPE_HAS_COPY_ASSIGN (t) && !TYPE_FOR_JAVA (t))
{
TYPE_HAS_COPY_ASSIGN (t) = 1;
TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
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;
}
......@@ -4495,6 +4493,54 @@ type_has_move_assign (tree t)
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
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
......
......@@ -4870,6 +4870,8 @@ extern bool type_has_constexpr_default_constructor (tree);
extern bool type_has_virtual_destructor (tree);
extern bool type_has_move_constructor (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 void explain_non_literal_class (tree);
extern void defaulted_late_check (tree);
......
......@@ -1375,18 +1375,31 @@ maybe_explain_implicit_delete (tree decl)
{
informed = true;
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)
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
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)
{
tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
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);
pop_scope (scope);
synthesized_method_walk (ctype, sfk, const_p,
......@@ -1743,6 +1756,15 @@ lazily_declare_fn (special_function_kind sfk, tree type)
/* Declare the function. */
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
don't declare them at all. */
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>
* gcc.target/i386/avx2-vpop-check.h: New header.
......
......@@ -2,13 +2,12 @@
// { dg-options -std=c++0x }
struct A {
A(A&&) = default; // { dg-message "A::A|no known conversion" }
A(A&&) = default;
};
struct B {
const A a;
B(const B&) = default;
B(B&&) = default; // { dg-error "implicitly deleted|no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 10 }
B(B&&) = default; // { dg-error "implicitly deleted|use of deleted" }
};
void g(B); // { dg-error "argument 1" }
......
......@@ -12,7 +12,7 @@ struct 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 }
X f() {
......
......@@ -3,13 +3,13 @@ struct S
{
S();
private:
S(S const &&); // { dg-error "" }
S & operator=(S const &&); // { dg-error "" }
S(S const &&);
S & operator=(S const &&);
};
void f()
{
S a;
S b(a); // { dg-error "" }
a = b; // { dg-error "" }
S b(a); // { dg-error "deleted" }
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 @@
// constructor to be deleted.
// { dg-options "-std=c++0x" }
struct A
struct A // { dg-message "declares a move" }
{
A(); // { dg-message "A::A|candidate expects" }
A(A&&); // { dg-message "A::A|no known conversion" }
A();
A(A&&);
};
struct B: A // { dg-error "implicit|no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 11 }
struct B: A // { dg-error "use of deleted" }
{
};
......
// Test that the default B copy constructor calls the A member template
// constructor.
// Test that the default B copy constructor calls the deleted A
// copy constructor.
// { dg-options -std=c++0x }
struct A
struct A // { dg-message "declares a move" }
{
A() = default;
A(A&&) = default;
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()
{
B b;
B b2(b);
B b2(b); // { dg-error "deleted" }
}
// The hack for PR c++/44909 breaks this testcase. We need feedback
// from the C++ committee to know how to proceed.
// { dg-options -std=c++0x }
// { dg-prune-output "implicitly deleted" }
// { dg-prune-output "cannot bind" }
// { dg-prune-output "initializing argument" }
struct A
{
......@@ -28,7 +25,8 @@ struct B
// 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
// 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 c2(c); // { dg-bogus "deleted" "" { xfail *-*-* } }
C c2(c); // { dg-error "deleted" }
......@@ -9,7 +9,7 @@ decltype(F()) run(F f) // { dg-message "note" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 14 }
......
// I, Howard Hinnant, hereby place this code in the public domain.
// Test that move constructor and move assignement are special.
// That is, their presence should inhibit compiler generated
// copy ctor or assignment.
// That is, their presence should cause compiler declared
// copy ctor or assignment to be deleted.
// { dg-options "-std=c++0x" }
......@@ -24,12 +24,12 @@ struct base
base& operator=(const base&) {++assign; return *this;}
};
struct derived
struct derived // { dg-message "declares a move" }
: base
{
derived() {}
derived(derived&&) {} // { dg-error "argument 1" }
derived& operator=(derived&&) {return *this;} // { dg-error "argument 1" }
derived(derived&&) {}
derived& operator=(derived&&) {return *this;}
};
int test1()
......@@ -37,11 +37,11 @@ int test1()
derived d;
derived d2(static_cast<derived&&>(d)); // should not call base::(const base&)
assert(copy == 0);
derived d3(d); // { dg-error "lvalue" }
derived d3(d); // { dg-error "deleted" }
assert(copy == 1);
d2 = static_cast<derived&&>(d); // should not call base::operator=
assert(assign == 0);
d3 = d; // { dg-error "lvalue" }
d3 = d; // { dg-error "deleted" }
assert(assign == 1);
return 0;
}
......
......@@ -5,22 +5,22 @@
int move_construct = 0;
int move_assign = 0;
struct base2
struct base2 // { dg-message "declares a move" }
{
base2() {}
base2(base2&&) {++move_construct;} // { dg-error "argument 1" }
base2& operator=(base2&&) {++move_assign; return *this;} // { dg-error "argument 1" }
base2(base2&&) {++move_construct;}
base2& operator=(base2&&) {++move_assign; return *this;}
};
int test2()
{
base2 b;
base2 b2(b); // { dg-error "lvalue" }
base2 b2(b); // { dg-error "deleted" }
assert(move_construct == 0);
base2 b3(static_cast<base2&&>(b));
base2 b4 = static_cast<base2&&>(b);
assert(move_construct == 2);
b = b2; // { dg-error "lvalue" }
b = b2; // { dg-error "deleted" }
assert(move_assign == 0);
b = static_cast<base2&&>(b2);
assert(move_assign == 1);
......
......@@ -20,7 +20,7 @@ struct eight {char x[8];};
struct A
{
A();
A(const volatile A&&); // { dg-error "argument 1" }
A(const volatile A&&);
};
A source();
......@@ -35,9 +35,9 @@ one sink_1_1( A&); // { dg-error "" }
int test1_1()
{
A a;
const A ca = a; // { dg-error "cannot bind" }
const A ca = a; // { dg-error "deleted" }
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(va); // { dg-error "invalid initialization" }
sink_1_1(cva); // { dg-error "invalid initialization" }
......@@ -53,9 +53,9 @@ two sink_1_2(const A&); // { dg-error "" }
int test1_2()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(cva); // { 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 "" }
int test1_3()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(cva); // { 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 "" }
int test1_4()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(c_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 "" }
int test1_5()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(ca); // { dg-error "invalid initialization" }
sink_1_5(va); // { dg-error "invalid initialization" }
......@@ -118,9 +118,9 @@ six sink_1_6(const A&&); // { dg-error "" }
int test1_6()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(ca); // { dg-error "lvalue" }
sink_1_6(va); // { dg-error "invalid initialization" }
......@@ -135,9 +135,9 @@ seven sink_1_7(volatile A&&); // { dg-error "" }
int test1_7()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(ca); // { dg-error "invalid initialization" }
sink_1_7(va); // { dg-error "lvalue" }
......@@ -152,9 +152,9 @@ eight sink_1_8(const volatile A&&); // { dg-error "" }
int test1_8()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(ca); // { dg-error "lvalue" }
sink_1_8(va); // { dg-error "lvalue" }
......
......@@ -20,7 +20,7 @@ struct eight {char x[8];};
struct A
{
A();
A(const volatile A&&); // { dg-error "argument 1" }
A(const volatile A&&);
};
A source();
......@@ -40,9 +40,9 @@ six sink_6_123456(const A&&); // { dg-message "note" }
int test6_123456()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 46 }
sink_6_123456(cv_source()); // { dg-error "no match" }
......@@ -60,9 +60,9 @@ seven sink_6_123457(volatile A&&); // { dg-message "note" }
int test6_123457()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 66 }
return 0;
......@@ -78,9 +78,9 @@ eight sink_6_235678(const volatile A&&); // { dg-message "" }
int test6_235678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 84 }
sink_6_235678(cva); // { dg-error "lvalue" }
......@@ -97,9 +97,9 @@ eight sink_6_234678(const volatile A&&); // { dg-message "note" }
int test6_234678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 103 }
sink_6_234678(source()); // { dg-error "ambiguous" }
......@@ -117,9 +117,9 @@ eight sink_6_234578(const volatile A&&); // { dg-message "note" }
int test6_234578()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 123 }
return 0;
......@@ -135,9 +135,9 @@ eight sink_6_234568(const volatile A&&); // { dg-message "note" }
int test6_234568()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 141 }
return 0;
......@@ -153,9 +153,9 @@ seven sink_6_234567(volatile A&&); // { dg-message "note" }
int test6_234567()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 159 }
sink_6_234567(cv_source()); // { dg-error "no match" }
......@@ -173,9 +173,9 @@ eight sink_6_134678(const volatile A&&); // { dg-message "note" }
int test6_134678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 179 }
return 0;
......@@ -191,9 +191,9 @@ eight sink_6_124678(const volatile A&&); // { dg-message "note" }
int test6_124678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 197 }
return 0;
......@@ -209,9 +209,9 @@ eight sink_6_123678(const volatile A&&); // { dg-message "" }
int test6_123678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(source()); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 216 }
......@@ -228,9 +228,9 @@ seven sink_6_123567(volatile A&&); // { dg-message "note" }
int test6_123567()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 234 }
sink_6_123567(cv_source()); // { dg-error "no match" }
......@@ -248,9 +248,9 @@ eight sink_6_123568(const volatile A&&); // { dg-message "" }
int test6_123568()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
return 0;
}
......@@ -265,9 +265,9 @@ eight sink_6_123578(const volatile A&&); // { dg-message "" }
int test6_123578()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
return 0;
}
......@@ -282,9 +282,9 @@ seven sink_6_123467(volatile A&&); // { dg-message "note" }
int test6_123467()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 288 }
sink_6_123467(cv_source()); // { dg-error "no match" }
......@@ -302,9 +302,9 @@ seven sink_6_124567(volatile A&&); // { dg-message "note" }
int test6_124567()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 308 }
return 0;
......@@ -320,9 +320,9 @@ eight sink_6_125678(const volatile A&&); // { dg-message "" }
int test6_125678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(cva); // { dg-error "lvalue" }
return 0;
......@@ -338,9 +338,9 @@ seven sink_6_134567(volatile A&&); // { dg-message "note" }
int test6_134567()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 344 }
return 0;
......@@ -356,9 +356,9 @@ eight sink_6_135678(const volatile A&&); // { dg-message "" }
int test6_135678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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(cva); // { dg-error "lvalue" }
return 0;
......
......@@ -20,7 +20,7 @@ struct eight {char x[8];};
struct A
{
A();
A(const volatile A&&); // { dg-error "argument 1" }
A(const volatile A&&);
};
A source();
......@@ -41,9 +41,9 @@ seven sink_7_1234567(volatile A&&); // { dg-message "note" }
int test7_1234567()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 47 }
return 0;
......@@ -60,9 +60,9 @@ eight sink_7_1235678(const volatile A&&); // { dg-message "" }
int test7_1235678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
return 0;
}
......@@ -78,9 +78,9 @@ eight sink_7_2345678(const volatile A&&); // { dg-message "note" }
int test7_2345678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 84 }
return 0;
......@@ -97,9 +97,9 @@ eight sink_7_1234678(const volatile A&&); // { dg-message "note" }
int test7_1234678()
{
A a;
const A ca = a; // { dg-error "lvalue" }
const A ca = a; // { dg-error "deleted" }
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" }
// { dg-message "candidate" "candidate note" { target *-*-* } 103 }
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>
* include/tr2/type_traits (bases, direct_bases, typelist): New.
......
......@@ -211,6 +211,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __r A %shared_ptr.
* @post get() == __r.get() && use_count() == __r.use_count()
*/
shared_ptr(const shared_ptr&) noexcept = default;
template<typename _Tp1, typename = typename
std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
......@@ -264,6 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr shared_ptr(nullptr_t __p) noexcept
: __shared_ptr<_Tp>(__p) { }
shared_ptr& operator=(const shared_ptr&) noexcept = default;
template<typename _Tp1>
shared_ptr&
operator=(const shared_ptr<_Tp1>& __r) noexcept
......
......@@ -41,19 +41,3 @@ main()
test01();
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
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>
propagating_allocator&
operator=(const propagating_allocator<Tp, P2>& a) noexcept
......
......@@ -255,6 +255,9 @@ namespace __gnu_test
{ throw 1; }
throwing_move_constructor(const throwing_move_constructor&) = default;
throwing_move_constructor&
operator=(const throwing_move_constructor&) = default;
};
} // 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