summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-02-14 23:27:44 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-02-14 23:27:44 +0000
commit44d0f7062d219377f1c93ada5ae676baf40381c1 (patch)
tree544eeef27ffca0cf2a41027a8766ce797375328f /test/SemaTemplate
parent8e4aad78974956d3cc99409a2567494117611b47 (diff)
Do not implicitly instantiate the definition of a class template specialization
that has been explicitly specialized! We assume in various places that we can tell the template specialization kind of a class type by looking at the declaration produced by TagType::getDecl. That was previously not quite true: for an explicit specialization, we could have first seen a template-id denoting the specialization (with a use that does not trigger an implicit instantiation of the defintiion) and then seen the first explicit specialization declaration. TagType::getDecl would previously return an arbitrary declaration when called on a not-yet-defined class; it now consistently returns the most recent declaration in that case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295118 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index f302836c7e..4300ceb17e 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -57,3 +57,14 @@ template<typename T> struct Helper {
template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
// expected-error {{no function template matches}}
}
+
+namespace b35070233 {
+ template <typename T> struct Cls {
+ static void f() {}
+ };
+
+ void g(Cls<int>);
+
+ template<> struct Cls<int>; // expected-note {{forward declaration}}
+ template<> void Cls<int>::f(); // expected-error {{incomplete type}}
+}