[cfe-commits] r128118 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/Sema/struct-decl.c
John McCall
rjmccall at apple.com
Tue Mar 22 16:00:04 PDT 2011
Author: rjmccall
Date: Tue Mar 22 18:00:04 2011
New Revision: 128118
URL: http://llvm.org/viewvc/llvm-project?rev=128118&view=rev
Log:
Warn about unused declaration-specifiers on tag declarations.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/Sema/struct-decl.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=128118&r1=128117&r2=128118&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 22 18:00:04 2011
@@ -2535,6 +2535,7 @@
"illegal storage class on file-scoped variable">;
def err_unsupported_global_register : Error<
"global register variables are not supported">;
+def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">;
def err_typecheck_sclass_func : Error<"illegal storage class on function">;
def err_static_block_func : Error<
"function declared in block scope cannot have 'static' storage class">;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=128118&r1=128117&r2=128118&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 22 18:00:04 2011
@@ -1764,12 +1764,7 @@
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
- DeclSpec &DS) {
- // FIXME: Error on inline/virtual/explicit
- // FIXME: Warn on useless __thread
- // FIXME: Warn on useless const/volatile
- // FIXME: Warn on useless static/extern/typedef/private_extern/mutable
- // FIXME: Warn on useless attributes
+ DeclSpec &DS) {
Decl *TagD = 0;
TagDecl *Tag = 0;
if (DS.getTypeSpecType() == DeclSpec::TST_class ||
@@ -1803,6 +1798,10 @@
return 0;
return ActOnFriendTypeDecl(S, DS, MultiTemplateParamsArg(*this, 0, 0));
}
+
+ // Track whether we warned about the fact that there aren't any
+ // declarators.
+ bool emittedWarning = false;
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
@@ -1815,6 +1814,7 @@
Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
<< DS.getSourceRange();
+ emittedWarning = true;
}
}
@@ -1840,12 +1840,16 @@
DS.getStorageClassSpec() != DeclSpec::SCS_typedef)
if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Tag))
if (Enum->enumerator_begin() == Enum->enumerator_end() &&
- !Enum->getIdentifier() && !Enum->isInvalidDecl())
+ !Enum->getIdentifier() && !Enum->isInvalidDecl()) {
Diag(Enum->getLocation(), diag::ext_no_declarators)
<< DS.getSourceRange();
+ emittedWarning = true;
+ }
+
+ // Skip all the checks below if we have a type error.
+ if (DS.getTypeSpecType() == DeclSpec::TST_error) return TagD;
- if (!DS.isMissingDeclaratorOk() &&
- DS.getTypeSpecType() != DeclSpec::TST_error) {
+ if (!DS.isMissingDeclaratorOk()) {
// Warn about typedefs of enums without names, since this is an
// extension in both Microsoft and GNU.
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef &&
@@ -1857,8 +1861,36 @@
Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
<< DS.getSourceRange();
+ emittedWarning = true;
}
+ // We're going to complain about a bunch of spurious specifiers;
+ // only do this if we're declaring a tag, because otherwise we
+ // should be getting diag::ext_no_declarators.
+ if (emittedWarning || (TagD && TagD->isInvalidDecl()))
+ return TagD;
+
+ if (DeclSpec::SCS scs = DS.getStorageClassSpec())
+ Diag(DS.getStorageClassSpecLoc(), diag::warn_standalone_specifier)
+ << DeclSpec::getSpecifierName(scs);
+ if (DS.isThreadSpecified())
+ Diag(DS.getThreadSpecLoc(), diag::warn_standalone_specifier) << "__thread";
+ if (DS.getTypeQualifiers()) {
+ if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+ Diag(DS.getConstSpecLoc(), diag::warn_standalone_specifier) << "const";
+ if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
+ Diag(DS.getConstSpecLoc(), diag::warn_standalone_specifier) << "volatile";
+ // Restrict is covered above.
+ }
+ if (DS.isInlineSpecified())
+ Diag(DS.getInlineSpecLoc(), diag::warn_standalone_specifier) << "inline";
+ if (DS.isVirtualSpecified())
+ Diag(DS.getVirtualSpecLoc(), diag::warn_standalone_specifier) << "virtual";
+ if (DS.isExplicitSpecified())
+ Diag(DS.getExplicitSpecLoc(), diag::warn_standalone_specifier) <<"explicit";
+
+ // FIXME: Warn on useless attributes
+
return TagD;
}
Modified: cfe/trunk/test/Sema/struct-decl.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-decl.c?rev=128118&r1=128117&r2=128118&view=diff
==============================================================================
--- cfe/trunk/test/Sema/struct-decl.c (original)
+++ cfe/trunk/test/Sema/struct-decl.c Tue Mar 22 18:00:04 2011
@@ -46,3 +46,14 @@
struct x0 {
unsigned int x1;
};
+
+// rdar://problem/9150338
+static struct test1 { // expected-warning {{'static' ignored on this declaration}}
+ int x;
+};
+const struct test2 { // expected-warning {{'const' ignored on this declaration}}
+ int x;
+};
+inline struct test3 { // expected-warning {{'inline' ignored on this declaration}}
+ int x;
+};
More information about the cfe-commits
mailing list