]> granicus.if.org Git - clang/commitdiff
Fix crash if a dependent template-id was assumed to be a type but instantiates
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 4 Dec 2013 00:56:29 +0000 (00:56 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 4 Dec 2013 00:56:29 +0000 (00:56 +0000)
to a variable template specialization.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196337 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/SemaCXX/cxx1y-variable-templates_in_class.cpp

index eb10758bc16e6a200a02c3186fbc00d6800d1436..3e55ec90ad063fd53f8068be4b81969445e1bb4d 100644 (file)
@@ -1959,7 +1959,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
                                                           TemplateArgs);
 
   TemplateDecl *Template = Name.getAsTemplateDecl();
-  if (!Template || isa<FunctionTemplateDecl>(Template)) {
+  if (!Template || isa<FunctionTemplateDecl>(Template) ||
+      isa<VarTemplateDecl>(Template)) {
     // We might have a substituted template template parameter pack. If so,
     // build a template specialization type for it.
     if (Name.getAsSubstTemplateTemplateParmPack())
index 1e959364280384c0e1107b1c4b6507f8adcc3ec2..1e5e834b6d2a0b7acfc82a978d065dd4b6ea1d24 100644 (file)
@@ -291,6 +291,30 @@ namespace in_class_template {
     template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... };
     static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, "");
   }
+
+  namespace bad_reference {
+    struct S {
+      template<typename T> static int A; // expected-note 4{{here}}
+    };
+
+    template<typename T> void f() {
+      typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}}
+    }
+    template<typename T> void g() {
+      T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}}
+    }
+    template<typename T> void h() {
+      class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}}
+    }
+
+    template<typename T>
+    struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}}
+
+    template void f<S>(); // expected-note {{in instantiation of}}
+    template void g<S>(); // expected-note {{in instantiation of}}
+    template void h<S>(); // expected-note {{in instantiation of}}
+    template struct X<S>; // expected-note {{in instantiation of}}
+  }
 }
 
 namespace in_nested_classes {