From 1cbdf932b41eb58ed94fbc240e93b63653d95bd3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 29 Jul 2020 12:29:05 -0700 Subject: [PATCH] PR46231: Promote diagnostic for 'template<...>;' from ExtWarn to Error. No other compiler accepts this as an extension, not even in permissive mode. We're not doing anyone any favors by allowing this, and it's unlikely to be at all common, even in Clang-only code, in the wild. --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 1 + clang/lib/Sema/SemaDecl.cpp | 5 ++++- clang/test/Parser/cxx-template-decl.cpp | 11 ++++++++++- clang/test/SemaCXX/PR16677.cpp | 2 +- clang/test/SemaCXX/invalid-template-params.cpp | 4 ++-- clang/test/SemaTemplate/template-decl-fail.cpp | 2 +- 6 files changed, 19 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 794ef23..9111286 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -793,6 +793,7 @@ def ext_main_used : Extension< /// parser diagnostics def ext_no_declarators : ExtWarn<"declaration does not declare anything">, InGroup; +def err_no_declarators : Error<"declaration does not declare anything">; def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">, InGroup; def err_typedef_not_identifier : Error<"typedef name must be an identifier">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ddbf086..9b9d164 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4766,7 +4766,10 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, if (!DeclaresAnything) { // In C, we allow this as a (popular) extension / bug. Don't bother // producing further diagnostics for redundant qualifiers after this. - Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange(); + Diag(DS.getBeginLoc(), (IsExplicitInstantiation || !TemplateParams.empty()) + ? diag::err_no_declarators + : diag::ext_no_declarators) + << DS.getSourceRange(); return TagD; } diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp index 64e7ca9..7455b1d 100644 --- a/clang/test/Parser/cxx-template-decl.cpp +++ b/clang/test/Parser/cxx-template-decl.cpp @@ -12,7 +12,7 @@ export template x; // expected-error {{expected '<' after 'template'}} export template class x0; // expected-warning {{exported templates are unsupported}} template < ; // expected-error {{expected template parameter}} \ // expected-error{{expected ',' or '>' in template-parameter-list}} \ -// expected-warning {{declaration does not declare anything}} +// expected-error {{declaration does not declare anything}} template struct x1; // expected-error {{expected ',' or '>' in template-parameter-list}} // verifies that we only walk to the ',' & still produce errors on the rest of the template parameters @@ -286,3 +286,12 @@ namespace PR45239 { template int b; template auto f() -> b<0>; // expected-error +{{}} } + +namespace PR46231 { + template; // expected-error {{declaration does not declare anything}} + template<>; // expected-error {{declaration does not declare anything}} + template; // expected-error {{declaration does not declare anything}} + template int; // expected-error {{declaration does not declare anything}} + template<> int; // expected-error {{declaration does not declare anything}} + template int; // expected-error {{declaration does not declare anything}} +} diff --git a/clang/test/SemaCXX/PR16677.cpp b/clang/test/SemaCXX/PR16677.cpp index efa4faa..3ad76c6 100644 --- a/clang/test/SemaCXX/PR16677.cpp +++ b/clang/test/SemaCXX/PR16677.cpp @@ -11,5 +11,5 @@ template { // expected-error{{'Derived' cannot be defined in a type specifier}} Class_With_Destructor member; }; // expected-error{{expected ',' or '>' in template-parameter-list}} - // expected-warning@-1{{declaration does not declare anything}} + // expected-error@-1{{declaration does not declare anything}} diff --git a/clang/test/SemaCXX/invalid-template-params.cpp b/clang/test/SemaCXX/invalid-template-params.cpp index 0c463fe..21220f3 100644 --- a/clang/test/SemaCXX/invalid-template-params.cpp +++ b/clang/test/SemaCXX/invalid-template-params.cpp @@ -5,7 +5,7 @@ template class Foo { // expected-note@-1 {{'UBar' declared here}} void foo1(); // expected-error {{a non-type template parameter cannot have type 'class UBar'}} // expected-error@-1 {{expected ',' or '>' in template-parameter-list}} - // expected-warning@-2 {{declaration does not declare anything}} + // expected-error@-2 {{declaration does not declare anything}} }; Foo::UBar g1; // expected-error {{no type named 'UBar' in 'Foo'}} @@ -16,7 +16,7 @@ public: struct S0 {}; // expected-error {{'S0' cannot be defined in a type specifier}} // expected-error@-1 {{cannot combine with previous 'type-name' declaration specifier}} // expected-error@-2 {{expected ',' or '>' in template-parameter-list}} - // expected-warning@-3 {{declaration does not declare anything}} + // expected-error@-3 {{declaration does not declare anything}} C0() : m(new S0) {} // expected-error {{expected '(' for function-style cast or type construction}} // expected-error@-1 {{expected expression}} S0 *m; // expected-error {{expected member name or ';' after declaration specifiers}} diff --git a/clang/test/SemaTemplate/template-decl-fail.cpp b/clang/test/SemaTemplate/template-decl-fail.cpp index ad134cd..7019caa 100644 --- a/clang/test/SemaTemplate/template-decl-fail.cpp +++ b/clang/test/SemaTemplate/template-decl-fail.cpp @@ -4,7 +4,7 @@ template typedef T X; // expected-error{{typedef cannot be a templat template enum t0 { A = T::x }; // expected-error{{enumeration cannot be a template}} \ - // expected-warning{{declaration does not declare anything}} + // expected-error{{declaration does not declare anything}} enum e0 {}; template enum e0 f0(int a=x) {} -- 2.7.4