Skip to content

Commit

Permalink
PR46231: Promote diagnostic for 'template<...>;' from ExtWarn to Error.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zygoloid committed Jul 29, 2020
1 parent decfdb8 commit 1cbdf93
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 6 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,7 @@ def ext_main_used : Extension<
/// parser diagnostics
def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
InGroup<MissingDeclarations>;
def err_no_declarators : Error<"declaration does not declare anything">;
def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
InGroup<MissingDeclarations>;
def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
11 changes: 10 additions & 1 deletion clang/test/Parser/cxx-template-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export template x; // expected-error {{expected '<' after 'template'}}
export template<class T> 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 <int +> 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
Expand Down Expand Up @@ -286,3 +286,12 @@ namespace PR45239 {
template<int> int b;
template<int> 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<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}}
template<int> int; // expected-error {{declaration does not declare anything}}
}
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/PR16677.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ template<class T, // Should be angle bracket instead of comma
class Derived : public Base<T> { // 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}}

4 changes: 2 additions & 2 deletions clang/test/SemaCXX/invalid-template-params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ template<class> 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<int>::UBar g1; // expected-error {{no type named 'UBar' in 'Foo<int>'}}
Expand All @@ -16,7 +16,7 @@ class C0 {
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<int>) {} // expected-error {{expected '(' for function-style cast or type construction}}
// expected-error@-1 {{expected expression}}
S0<int> *m; // expected-error {{expected member name or ';' after declaration specifiers}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaTemplate/template-decl-fail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ template<typename T> typedef T X; // expected-error{{typedef cannot be a templat

template<typename T>
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<int x> enum e0 f0(int a=x) {}

0 comments on commit 1cbdf93

Please sign in to comment.