diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-08 16:41:22 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-08 16:41:22 +0000 |
commit | 9916a047c55ea18845d706bf95e7517b646933d0 (patch) | |
tree | a4c3c270df24956f9b8491b455c5a8738ce87a35 | |
parent | 12af63bd2498c1af44b9a50eb0de5839487809d4 (diff) |
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
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp | 14 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp | 59 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp | 61 |
4 files changed, 136 insertions, 0 deletions
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 T> class X; +} + +// FIXME: this diagnostic is terrible (PR3844). +template<> class X<int> { /* ... */ }; // expected-error {{unqualified-id}} + +namespace N { + +template<> class X<char*> { /* ... */ }; // 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<typename T, typename U> +struct X { // expected-note{{here}} + void f() { + T t; // expected-error{{no matching}} + } + + void g() { } + + struct Inner { + T value; + }; + + static T value; +}; + +template<typename T, typename U> +T X<T, U>::value; // expected-error{{no matching constructor}} + +IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) { + xih.g(); // okay + xih.f(); // expected-note{{instantiation}} + + // FIXME: diagnostic here has incorrect reason (PR5154) + X<IntHolder, int>::Inner inner; // expected-error{{implicit default}} + + return X<IntHolder, int>::value; // expected-note{{instantiation}} +} + +// Explicitly specialize the members of X<IntHolder, long> to not cause +// problems with instantiation. +template<> +void X<IntHolder, long>::f() { } + +template<> +struct X<IntHolder, long>::Inner { + Inner() : value(17) { } + IntHolder value; +}; + +template<> +IntHolder X<IntHolder, long>::value = 17; + +IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) { + xih.g(); // okay + xih.f(); // okay, uses specialization + + X<IntHolder, long>::Inner inner; // okay, uses specialization + + return X<IntHolder, long>::value; // okay, uses specialization +} + +template<> +X<IntHolder, long>::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<typename T, typename U> +struct X { + void f() { + T t; + } + + void g() { } + + struct Inner { + T value; + }; + + static T value; +}; + +template<typename T, typename U> +T X<T, U>::value; + +// Explicitly specialize the members of X<IntHolder, long> to not cause +// problems with instantiation, but only provide declarations (not definitions). +template<> +void X<IntHolder, long>::f(); + +template<> +struct X<IntHolder, long>::Inner; // expected-note{{forward declaration}} + +template<> +IntHolder X<IntHolder, long>::value; + +IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) { + xih.g(); // okay + xih.f(); // okay, uses specialization + + X<IntHolder, long>::Inner inner; // expected-error {{incomplete}} + + return X<IntHolder, long>::value; // okay, uses specialization +} + + +template<class T> struct A { + void f(T) { /* ... */ } +}; + +template<> struct A<int> { + void f(int); +}; + +void h() { + A<int> a; + a.f(16); // A<int>::f must be defined somewhere +} + +// explicit specialization syntax not used for a member of +// explicitly specialized class template specialization +void A<int>::f(int) { /* ... */ } |