Create a subject list for the `used` attribute rather than use custom checking logic.

This changes the diagnostic wording somewhat, but otherwise intends no functional change to the attribute.

llvm-svn: 326665
This commit is contained in:
Aaron Ballman 2018-03-03 21:02:09 +00:00
parent b94863001a
commit 1a3901c69f
3 changed files with 7 additions and 20 deletions

View File

@ -83,6 +83,9 @@ def LocalVar : SubsetSubject<Var,
def NonParmVar : SubsetSubject<Var,
[{S->getKind() != Decl::ParmVar}],
"variables">;
def NonLocalVar : SubsetSubject<Var,
[{!S->hasLocalStorage()}],
"variables with non-local storage">;
def NonBitField : SubsetSubject<Field,
[{!S->isBitField()}],
"non-bit-field non-static data members">;
@ -2007,6 +2010,7 @@ def Unused : InheritableAttr {
def Used : InheritableAttr {
let Spellings = [GCC<"used">];
let Subjects = SubjectList<[Function, ObjCMethod, NonLocalVar]>;
let Documentation = [Undocumented];
}

View File

@ -2086,23 +2086,6 @@ static void handleDisableTailCallsAttr(Sema &S, Decl *D,
AL.getRange(), S.Context, AL.getAttributeSpellingListIndex()));
}
static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &AL) {
if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasLocalStorage()) {
S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL.getName();
return;
}
} else if (!isFunctionOrMethod(D)) {
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
<< AL.getName() << ExpectedVariableOrFunction;
return;
}
D->addAttr(::new (S.Context)
UsedAttr(AL.getRange(), S.Context,
AL.getAttributeSpellingListIndex()));
}
static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &AL) {
bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
@ -6248,7 +6231,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleDisableTailCallsAttr(S, D, AL);
break;
case AttributeList::AT_Used:
handleUsedAttr(S, D, AL);
handleSimpleAttribute<UsedAttr>(S, D, AL);
break;
case AttributeList::AT_Visibility:
handleVisibilityAttr(S, D, AL, false);

View File

@ -3,7 +3,7 @@
extern int l0 __attribute__((used)); // expected-warning {{'used' attribute ignored}}
__private_extern__ int l1 __attribute__((used)); // expected-warning {{'used' attribute ignored}}
struct __attribute__((used)) s { // expected-warning {{'used' attribute only applies to variables and functions}}
struct __attribute__((used)) s { // expected-warning {{'used' attribute only applies to functions, Objective-C methods, and variables with non-local storage}}
int x;
};
@ -14,7 +14,7 @@ static void __attribute__((used)) f0(void) {
void f1() {
static int a __attribute__((used));
int b __attribute__((used)); // expected-warning {{'used' attribute ignored}}
int b __attribute__((used)); // expected-warning {{'used' attribute only applies to functions, Objective-C methods, and variables with non-local storage}}
}
static void __attribute__((used)) f0(void);