forked from OSchip/llvm-project
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:
parent
b94863001a
commit
1a3901c69f
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue