Author: rsmith Date: Thu Feb 9 16:14:25 2017 New Revision: 294639 URL: http://llvm.org/viewvc/llvm-project?rev=294639&view=rev Log: Diagnose attempts to explicitly instantiate a template at class scope. Previously Clang would simply ignore the 'template' keyword in this case.
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/test/Parser/cxx-template-decl.cpp cfe/trunk/test/Parser/eof.cpp cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp cfe/trunk/test/SemaTemplate/template-id-expr.cpp Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=294639&r1=294638&r2=294639&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Feb 9 16:14:25 2017 @@ -2459,9 +2459,10 @@ Parser::ParseCXXClassMemberDeclaration(A if (Tok.is(tok::kw_template)) { assert(!TemplateInfo.TemplateParams && "Nested template improperly parsed?"); + ObjCDeclContextSwitch ObjCDC(*this); SourceLocation DeclEnd; return DeclGroupPtrTy::make( - DeclGroupRef(ParseDeclarationStartingWithTemplate( + DeclGroupRef(ParseTemplateDeclarationOrSpecialization( Declarator::MemberContext, DeclEnd, AS, AccessAttrs))); } Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=294639&r1=294638&r2=294639&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx-template-decl.cpp (original) +++ cfe/trunk/test/Parser/cxx-template-decl.cpp Thu Feb 9 16:14:25 2017 @@ -238,3 +238,13 @@ struct t2 : base<int, // expected-error@-1 {{expected '{' after base class list}} } + +namespace class_scope_instantiation { + struct A { + template<typename T> void f(T); + template void f<int>(int); // expected-error {{expected '<' after 'template'}} + template void f(float); // expected-error {{expected '<' after 'template'}} + extern template // expected-error {{expected member name or ';'}} + void f(double); + }; +} Modified: cfe/trunk/test/Parser/eof.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/eof.cpp?rev=294639&r1=294638&r2=294639&view=diff ============================================================================== --- cfe/trunk/test/Parser/eof.cpp (original) +++ cfe/trunk/test/Parser/eof.cpp Thu Feb 9 16:14:25 2017 @@ -1,6 +1,6 @@ // RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s -// CHECK: error: expected member name or ';' after declaration specifiers +// CHECK: error: expected '<' after 'template' // CHECK: error: expected '}' // CHECK: note: to match this '{' // CHECK: error: expected ';' after class Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=294639&r1=294638&r2=294639&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Thu Feb 9 16:14:25 2017 @@ -17,8 +17,7 @@ class A { template<typename T> CONST float right<float,T> = 5; // expected-error {{member 'right' declared as a template}} template<> static CONST int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} template<> static CONST float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} - template static CONST int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ - // expected-error {{explicit specialization of 'right' in class scope}} + template static CONST int right<int,int>; // expected-error {{expected '<' after 'template'}} }; namespace out_of_line { @@ -166,8 +165,7 @@ namespace constexpred { template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}} template<> static constexpr int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} template<> static constexpr float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} - template static constexpr int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ - // expected-error {{explicit specialization of 'right' in class scope}} + template static constexpr int right<int,int>; // expected-error {{expected '<' after 'template'}} }; } #endif Modified: cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp?rev=294639&r1=294638&r2=294639&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp (original) +++ cfe/trunk/test/SemaTemplate/explicit-instantiation.cpp Thu Feb 9 16:14:25 2017 @@ -103,8 +103,8 @@ namespace PR7622 { // Test that we do not crash. class TC1 { class TC2 { - template // FIXME: error here. - void foo() { } + template + void foo() { } // expected-error{{expected '<' after 'template'}} }; }; Modified: cfe/trunk/test/SemaTemplate/template-id-expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/template-id-expr.cpp?rev=294639&r1=294638&r2=294639&view=diff ============================================================================== --- cfe/trunk/test/SemaTemplate/template-id-expr.cpp (original) +++ cfe/trunk/test/SemaTemplate/template-id-expr.cpp Thu Feb 9 16:14:25 2017 @@ -98,7 +98,11 @@ void f5() { template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} class C {}; -template <template <typename> class D> // expected-note{{previous use is here}} +template <template <typename> class D> class E { - template class D<C>; // expected-error {{template template argument 'D' cannot be referenced with a class specifier}} + template class D<C>; // expected-error {{expected '<' after 'template'}} + template<> class D<C>; // expected-error {{cannot specialize a template template parameter}} + friend class D<C>; // expected-error {{type alias template 'D' cannot be referenced with a class specifier}} }; +template<typename T> using D = int; // expected-note {{declared here}} expected-warning {{extension}} +E<D> ed; // expected-note {{instantiation of}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits