forked from OSchip/llvm-project
Centralize the handling of the "attribute declaration must precede definition"
warning. This also makes us warn on tags, which, ironically, is the only case gcc warns on. llvm-svn: 157039
This commit is contained in:
parent
22d405f57b
commit
3619104239
|
@ -1698,9 +1698,30 @@ bool Sema::mergeDeclAttribute(Decl *D, InheritableAttr *Attr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static const Decl *getDefinition(Decl *D) {
|
||||
if (TagDecl *TD = dyn_cast<TagDecl>(D))
|
||||
return TD->getDefinition();
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(D))
|
||||
return VD->getDefinition();
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
const FunctionDecl* Def;
|
||||
if (FD->hasBody(Def))
|
||||
return Def;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// mergeDeclAttributes - Copy attributes from the Old decl to the New one.
|
||||
void Sema::mergeDeclAttributes(Decl *New, Decl *Old,
|
||||
bool MergeDeprecation) {
|
||||
// attributes declared post-definition are currently ignored
|
||||
const Decl *Def = getDefinition(Old);
|
||||
if (Def && Def != New && New->hasAttrs()) {
|
||||
Diag(New->getLocation(), diag::warn_attribute_precede_definition);
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
New->dropAttrs();
|
||||
}
|
||||
|
||||
if (!Old->hasAttrs())
|
||||
return;
|
||||
|
||||
|
@ -4251,18 +4272,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
CheckMemberSpecialization(NewVD, Previous))
|
||||
NewVD->setInvalidDecl();
|
||||
}
|
||||
|
||||
// attributes declared post-definition are currently ignored
|
||||
// FIXME: This should be handled in attribute merging, not
|
||||
// here.
|
||||
if (Previous.isSingleResult()) {
|
||||
VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
|
||||
if (Def && (Def = Def->getDefinition()) &&
|
||||
Def != NewVD && D.hasAttributes()) {
|
||||
Diag(NewVD->getLocation(), diag::warn_attribute_precede_definition);
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a locally-scoped extern C variable, update the map of
|
||||
// such variables.
|
||||
|
@ -5665,17 +5674,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
}
|
||||
}
|
||||
|
||||
// attributes declared post-definition are currently ignored
|
||||
// FIXME: This should happen during attribute merging
|
||||
if (D.isRedeclaration() && Previous.isSingleResult()) {
|
||||
const FunctionDecl *Def;
|
||||
FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
|
||||
if (PrevFD && PrevFD->isDefined(Def) && D.hasAttributes()) {
|
||||
Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition);
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
}
|
||||
}
|
||||
|
||||
AddKnownFunctionAttributes(NewFD);
|
||||
|
||||
if (NewFD->hasAttr<OverloadableAttr>() &&
|
||||
|
|
|
@ -17,3 +17,6 @@ int bar = 0; // expected-note {{previous definition is here}}
|
|||
int bar __attribute__((weak)); // expected-warning {{must precede definition}}
|
||||
int bar;
|
||||
|
||||
struct zed { // expected-note {{previous definition is here}}
|
||||
};
|
||||
struct __attribute__((visibility("hidden"))) zed; // expected-warning {{must precede definition}}
|
||||
|
|
Loading…
Reference in New Issue