From: Douglas Gregor Date: Thu, 8 Oct 2009 16:41:22 +0000 (+0000) Subject: Add more testing for the properties of explicit specialization. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9916a047c55ea18845d706bf95e7517b646933d0;p=clang Add more testing for the properties of explicit specialization. Also, eliminate a redundant diagnostic by marking a variable declared with incomplete type as an invalid declaration. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83553 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9163aba9f5..fa6d623ae3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3454,6 +3454,8 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl, FinalizeVarWithDestructor(Var, InitType); } + } else { + Var->setInvalidDecl(); } } } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp new file mode 100644 index 0000000000..2bd1400fae --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +namespace N { + template class X; +} + +// FIXME: this diagnostic is terrible (PR3844). +template<> class X { /* ... */ }; // expected-error {{unqualified-id}} + +namespace N { + +template<> class X { /* ... */ }; // OK: X is a template + +} \ No newline at end of file diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp new file mode 100644 index 0000000000..a09cccd1fd --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp @@ -0,0 +1,59 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct IntHolder { // expected-note{{here}} + IntHolder(int); +}; + +template +struct X { // expected-note{{here}} + void f() { + T t; // expected-error{{no matching}} + } + + void g() { } + + struct Inner { + T value; + }; + + static T value; +}; + +template +T X::value; // expected-error{{no matching constructor}} + +IntHolder &test_X_IntHolderInt(X xih) { + xih.g(); // okay + xih.f(); // expected-note{{instantiation}} + + // FIXME: diagnostic here has incorrect reason (PR5154) + X::Inner inner; // expected-error{{implicit default}} + + return X::value; // expected-note{{instantiation}} +} + +// Explicitly specialize the members of X to not cause +// problems with instantiation. +template<> +void X::f() { } + +template<> +struct X::Inner { + Inner() : value(17) { } + IntHolder value; +}; + +template<> +IntHolder X::value = 17; + +IntHolder &test_X_IntHolderInt(X xih) { + xih.g(); // okay + xih.f(); // okay, uses specialization + + X::Inner inner; // okay, uses specialization + + return X::value; // okay, uses specialization +} + +template<> +X::X() { } // expected-error{{instantiated member}} diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp new file mode 100644 index 0000000000..58682c786f --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp @@ -0,0 +1,61 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct IntHolder { + IntHolder(int); +}; + +template +struct X { + void f() { + T t; + } + + void g() { } + + struct Inner { + T value; + }; + + static T value; +}; + +template +T X::value; + +// Explicitly specialize the members of X to not cause +// problems with instantiation, but only provide declarations (not definitions). +template<> +void X::f(); + +template<> +struct X::Inner; // expected-note{{forward declaration}} + +template<> +IntHolder X::value; + +IntHolder &test_X_IntHolderInt(X xih) { + xih.g(); // okay + xih.f(); // okay, uses specialization + + X::Inner inner; // expected-error {{incomplete}} + + return X::value; // okay, uses specialization +} + + +template struct A { + void f(T) { /* ... */ } +}; + +template<> struct A { + void f(int); +}; + +void h() { + A a; + a.f(16); // A::f must be defined somewhere +} + +// explicit specialization syntax not used for a member of +// explicitly specialized class template specialization +void A::f(int) { /* ... */ }