diff options
author | Jason Merrill <jason@redhat.com> | 2010-06-29 20:51:29 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-06-29 20:51:29 -0400 |
commit | 54ca9930b79c8f759919fdbe671ff24ce4141b0c (patch) | |
tree | 9475890307f4ab29171a55ba449382044eb779cb /gcc | |
parent | 9a71b305bf556ad173b123d2d58612652b82e6dc (diff) | |
download | gcc-54ca9930b79c8f759919fdbe671ff24ce4141b0c.zip gcc-54ca9930b79c8f759919fdbe671ff24ce4141b0c.tar.gz gcc-54ca9930b79c8f759919fdbe671ff24ce4141b0c.tar.bz2 |
Enable implicitly deleted functions (N2346)
Enable implicitly deleted functions (N2346)
* class.c (check_bases_and_members): Adjust lambda flags.
* method.c (implicitly_declare_fn): Set DECL_DELETED_FN if appropriate.
From-SVN: r161581
Diffstat (limited to 'gcc')
21 files changed, 125 insertions, 29 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9ac64c4..8c9b424 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2010-06-29 Jason Merrill <jason@redhat.com> + Enable implicitly deleted functions (N2346) + * class.c (check_bases_and_members): Adjust lambda flags. + * method.c (implicitly_declare_fn): Set DECL_DELETED_FN if appropriate. + * decl2.c (mark_used): Adjust error for use of deleted function. Machinery to support implicit delete/move. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6f6aab6..031a4ea 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4563,10 +4563,9 @@ check_bases_and_members (tree t) /* "The closure type associated with a lambda-expression has a deleted default constructor and a deleted copy assignment operator." */ TYPE_NEEDS_CONSTRUCTING (t) = 1; - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; - CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 0; - TYPE_HAS_COPY_ASSIGN (t) = 0; - CLASSTYPE_LAZY_COPY_ASSIGN (t) = 0; + TYPE_HAS_COMPLEX_DFLT (t) = 1; + TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1; + CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 0; /* "This class type is not an aggregate." */ CLASSTYPE_NON_AGGREGATE (t) = 1; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 64f7b7f..ad41e9a 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1408,6 +1408,8 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) DECL_IN_AGGR_P (fn) = 1; DECL_ARTIFICIAL (fn) = 1; DECL_DEFAULTED_FN (fn) = 1; + if (cxx_dialect >= cxx0x) + DECL_DELETED_FN (fn) = deleted_p; DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; gcc_assert (!TREE_USED (fn)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf7180a..7b7dc7b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,24 @@ 2010-06-29 Jason Merrill <jason@redhat.com> + Enable implicitly deleted functions (N2346) + * g++.dg/cpp0x/defaulted17.C: New. + * g++.dg/cpp0x/implicit1.C: New. + * g++.dg/cpp0x/implicit2.C: New. + * g++.dg/cpp0x/lambda/lambda-ctor-neg.C: Adjust. + * g++.dg/ext/has_virtual_destructor.C: Adjust. + * g++.dg/init/ctor4.C: Adjust. + * g++.dg/init/synth2.C: Adjust. + * g++.dg/lto/20081118_1.C: Adjust. + * g++.dg/other/error13.C: Adjust. + * g++.dg/other/unused1.C: Adjust. + * g++.old-deja/g++.bob/inherit2.C: Adjust. + * g++.old-deja/g++.bugs/900205_04.C: Adjust. + * g++.old-deja/g++.jason/opeq3.C: Adjust. + * g++.old-deja/g++.law/ctors17.C: Adjust. + * g++.old-deja/g++.oliva/delete1.C: Adjust. + * g++.old-deja/g++.pt/assign1.C: Adjust. + * g++.old-deja/g++.pt/crash20.C: Adjust. + * g++.dg/cpp0x/defaulted10.C: Adjust for new deleted message. * g++.dg/cpp0x/defaulted13.C: Adjust. * g++.dg/cpp0x/defaulted2.C: Adjust. diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted17.C b/gcc/testsuite/g++.dg/cpp0x/defaulted17.C new file mode 100644 index 0000000..79e91a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/defaulted17.C @@ -0,0 +1,12 @@ +// { dg-options -std=c++0x } + +struct A // { dg-error "const|operator=" } +{ + const int i; +}; + +int main() +{ + A a = { 0 }; + a = a; // { dg-error "deleted" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit1.C b/gcc/testsuite/g++.dg/cpp0x/implicit1.C new file mode 100644 index 0000000..2efbde6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/implicit1.C @@ -0,0 +1,26 @@ +// Test for implicitly deleted destructors. +// { dg-options "-std=c++0x" } +// { dg-prune-output "default definition would be ill-formed" } +// { dg-prune-output "within this context" } + +class C +{ + void operator delete (void *); // { dg-error "private" } +public: + virtual ~C(); // { dg-error "overriding" } +}; + +struct D: C { }; // { dg-error "deleted" } +D d; // { dg-error "deleted" } + +struct E +{ + ~E() = delete; // { dg-error "declared here" } +}; + +struct F +{ + virtual ~F(); // { dg-error "overriding" } +}; + +struct G: E, F { }; // { dg-error "deleted" } diff --git a/gcc/testsuite/g++.dg/cpp0x/implicit2.C b/gcc/testsuite/g++.dg/cpp0x/implicit2.C new file mode 100644 index 0000000..f24a788 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/implicit2.C @@ -0,0 +1,33 @@ +// Test that the synthesized C copy constructor calls the A template +// constructor and has the appropriate exception specification. +// { dg-options -std=c++0x } +// { dg-do run } + +int r = 1; + +struct A +{ + A() {} + A(const A&) throw () { } + template <class T> + A(T& t) { r = 0; } +}; + +struct B +{ + B() {} + B(B&) throw () { } +}; + +struct C: A, B { }; + +#define SA(E) static_assert(E, #E) + +C c; +SA (!noexcept(C(c))); + +int main() +{ + (C(c)); + return r; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C index c38f295..76ed744 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ctor-neg.C @@ -3,7 +3,7 @@ void f() { int i; - auto lam = [i]{}; // { dg-message "note" } + auto lam = [i]{}; // { dg-message "" } decltype(lam) lam2 = { 1 }; // { dg-error "" "not an aggregate" } decltype(lam) lam3; // { dg-error "" "deleted default ctor" } lam3 = lam; // { dg-error "" "deleted assignment op" } @@ -12,7 +12,7 @@ void f() template <class T> void g(T i) { - auto lam = [i]{}; // { dg-message "note" } + auto lam = [i]{}; // { dg-message "" } decltype(lam) lam2 = { 1 }; // { dg-error "" "not an aggregate" } decltype(lam) lam3; // { dg-error "" "deleted default ctor" } lam3 = lam; // { dg-error "" "deleted assignment op" } diff --git a/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C b/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C index c263a94..093e7f5 100644 --- a/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C +++ b/gcc/testsuite/g++.dg/ext/has_virtual_destructor.C @@ -14,15 +14,15 @@ union U double b; }; -class B +struct B { virtual ~B() { } }; -class C +struct C : public B { }; -class D +struct D { ~D() { } }; diff --git a/gcc/testsuite/g++.dg/init/ctor4.C b/gcc/testsuite/g++.dg/init/ctor4.C index 0671dd8..1c92bb9 100644 --- a/gcc/testsuite/g++.dg/init/ctor4.C +++ b/gcc/testsuite/g++.dg/init/ctor4.C @@ -6,7 +6,7 @@ public: foo(); }; -class bar: public foo {// { dg-error "uninitialized" } +class bar: public foo { // { dg-error "reference|bar::bar" } private: int &a; }; @@ -16,5 +16,5 @@ foo::foo() { int main(int argc, char **argv) { - bar x; // { dg-message "synthesized" } + bar x; // { dg-message "synthesized|deleted" } } diff --git a/gcc/testsuite/g++.dg/init/synth2.C b/gcc/testsuite/g++.dg/init/synth2.C index 507db34..9e8a08a 100644 --- a/gcc/testsuite/g++.dg/init/synth2.C +++ b/gcc/testsuite/g++.dg/init/synth2.C @@ -5,7 +5,7 @@ struct G { G(G&); // { dg-message "" "candidate" } }; -class A // { dg-error "no match" } +class A // { dg-error "" } { const G g; }; diff --git a/gcc/testsuite/g++.dg/lto/20081118_1.C b/gcc/testsuite/g++.dg/lto/20081118_1.C index b9e56a4..a1bf081 100644 --- a/gcc/testsuite/g++.dg/lto/20081118_1.C +++ b/gcc/testsuite/g++.dg/lto/20081118_1.C @@ -1,4 +1,5 @@ class object { +public: virtual ~object() {} }; diff --git a/gcc/testsuite/g++.dg/other/error13.C b/gcc/testsuite/g++.dg/other/error13.C index 89e8847..7845501 100644 --- a/gcc/testsuite/g++.dg/other/error13.C +++ b/gcc/testsuite/g++.dg/other/error13.C @@ -5,6 +5,6 @@ struct A // { dg-message "note" } A(void x); // { dg-error "invalid use|incomplete type|candidates" } }; -struct B : A {}; // { dg-error "no matching function for call" } +struct B : A {}; // { dg-error "no matching function for call|deleted" } -B b; // { dg-message "synthesized method" } +B b; // { dg-message "synthesized method|deleted" } diff --git a/gcc/testsuite/g++.dg/other/unused1.C b/gcc/testsuite/g++.dg/other/unused1.C index d652f41..2a3ca1b 100644 --- a/gcc/testsuite/g++.dg/other/unused1.C +++ b/gcc/testsuite/g++.dg/other/unused1.C @@ -32,7 +32,7 @@ int bar4 (void) return const_cast<printer *>(dotmatrix)->i; } -class class1 { virtual ~class1(); } *c1; +class class1 { public: virtual ~class1(); } *c1; class class2 : class1 { char j; }; int bar5 (void) { diff --git a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C index c0a821b..6e26ecf 100644 --- a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C +++ b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C @@ -10,7 +10,7 @@ private: const A& operator =(const A &) { abort(); } }; -class B : public A { // { dg-error "within" } +class B : public A { // { dg-error "" } public: B(void) {} }; @@ -20,5 +20,5 @@ void f(B b) { // { dg-error "initializing" } void g() { B h; - f(h); // { dg-message "synthesized" "synth" } + f(h); // { dg-message "synthesized|deleted" "synth" } } diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C b/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C index 8d91db6..4290144 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C @@ -23,9 +23,9 @@ struct0::struct0 (int, void *) // { dg-message "note" } { } -struct struct0_derived_struct_0 : public struct0 { // { dg-error "no matching" } +struct struct0_derived_struct_0 : public struct0 { // { dg-error "no matching|deleted" } }; -struct0_derived_struct_0 object; // { dg-message "synthesized" } +struct0_derived_struct_0 object; // { dg-message "synthesized|deleted" } int main () { return 0; } diff --git a/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C b/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C index 7a50abb..b4e6e25 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C @@ -1,7 +1,7 @@ // { dg-do assemble } // Bug: g++ generates code for assignment in invalid situations. -class X { // { dg-error "assignment" } +class X { // { dg-error "reference|operator=" } int& a; public: X(int& i): a(i) { } @@ -11,5 +11,5 @@ void foo () { int one=1, two=2; X a(one), b(two); - a = b; // { dg-message "synthesized" } + a = b; // { dg-message "synthesized|deleted" } } diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors17.C b/gcc/testsuite/g++.old-deja/g++.law/ctors17.C index 3d63d01..0d61c49 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/ctors17.C +++ b/gcc/testsuite/g++.old-deja/g++.law/ctors17.C @@ -6,10 +6,12 @@ // Subject: gcc 2.4.3.1: illegal constructor call not rejected // Date: Tue, 15 Jun 1993 18:34:14 +0200 (MET DST) +// C++0x mode doesn't print the deleted copy constructor as a candidate. +// { dg-prune-output ":14:" } #include <fstream> -class X : public std::ifstream { // { dg-message "note" } candidate +class X : public std::ifstream { public: X(int a, const char *b) {} // { dg-message "note" } candidate }; diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/delete1.C b/gcc/testsuite/g++.old-deja/g++.oliva/delete1.C index 3912dba..368a87a 100644 --- a/gcc/testsuite/g++.old-deja/g++.oliva/delete1.C +++ b/gcc/testsuite/g++.old-deja/g++.oliva/delete1.C @@ -28,5 +28,4 @@ struct baz : foo { virtual ~baz() {} // { dg-error "" } delete is private in vdtor } baz_; -struct bad : baz {} bad_; // { dg-error "" } delete is private in vdtor -// { dg-message "synthesized" "note" { target *-*-* } 31 } +struct bad : baz {} bad_; // { dg-message "" } delete is private in vdtor diff --git a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C index 464b7c6..854d8ee 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C @@ -2,7 +2,7 @@ // Origin: Mark Mitchell <mark@codesourcery.com> template <class T> -struct S { // { dg-error "assignment" } +struct S { // { dg-error "const|operator=" } S(); T t; }; @@ -10,5 +10,5 @@ struct S { // { dg-error "assignment" } void f() { S<const int> s; - s = s; // { dg-message "synthesized" } + s = s; // { dg-message "synthesized|deleted" } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C index 0a32209..a5175b9 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C @@ -1,8 +1,7 @@ // { dg-do compile } template <class T = int> -struct A { // { dg-error "assignment" "assignment" } -// { dg-message "instantiated" "inst" { target *-*-* } 4 } +struct A { // { dg-message "const|operator=" "assignment" } const T x; A() : x(0) { } A(T x) : x(x) { } }; @@ -11,7 +10,7 @@ template <class B> void func () { B y; - y = B(); // { dg-message "synthesized" } + y = B(); // { dg-message "synthesized|deleted" } } int main (void) { func< A<> >(); } |