diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp | 24 |
2 files changed, 26 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index eb10758bc16..3e55ec90ad0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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()) diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp index 1e959364280..1e5e834b6d2 100644 --- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp +++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp @@ -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 { |