string DiagSpelling = diag;
}
-// This is the type of a variable which C++11 allows alignas(...) to appertain
-// to.
-def NormalVar : SubsetSubject<Var,
- [{S->getStorageClass() != VarDecl::Register &&
- S->getKind() != Decl::ImplicitParam &&
- S->getKind() != Decl::ParmVar &&
- S->getKind() != Decl::NonTypeTemplateParm}],
+def LocalVar : SubsetSubject<Var,
+ [{S->hasLocalStorage() && !isa<ParmVarDecl>(S)}],
"local variables">;
def NonParmVar : SubsetSubject<Var,
[{S->getKind() != Decl::ParmVar}],
def Aligned : InheritableAttr {
let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
Keyword<"_Alignas">];
-// let Subjects = SubjectList<[NonBitField, NormalVar, Tag]>;
let Args = [AlignedArgument<"Alignment", 1>];
let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
Accessor<"isC11", [Keyword<"_Alignas">]>,
def Cleanup : InheritableAttr {
let Spellings = [GCC<"cleanup">];
let Args = [FunctionArgument<"FunctionDecl">];
- let Subjects = SubjectList<[Var]>;
+ let Subjects = SubjectList<[LocalVar]>;
let Documentation = [Undocumented];
}
}
static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- VarDecl *VD = cast<VarDecl>(D);
- if (!VD->hasLocalStorage()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
- return;
- }
-
Expr *E = Attr.getArgAsExpr(0);
SourceLocation Loc = E->getExprLoc();
FunctionDecl *FD = nullptr;
// We're currently more strict than GCC about what function types we accept.
// If this ever proves to be a problem it should be easy to fix.
- QualType Ty = S.Context.getPointerType(VD->getType());
+ QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
QualType ParamTy = FD->getParamDecl(0)->getType();
if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
ParamTy, Ty) != Sema::Compatible) {
void c1(int *a);
-extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
-int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
-static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
+extern int g1 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
+int g2 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
+static int g3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
void t1()
{
int v1 __attribute((cleanup)); // expected-error {{'cleanup' attribute takes one argument}}
int v2 __attribute((cleanup(1, 2))); // expected-error {{'cleanup' attribute takes one argument}}
- static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute ignored}}
+ static int v3 __attribute((cleanup(c1))); // expected-warning {{'cleanup' attribute only applies to local variables}}
int v4 __attribute((cleanup(h))); // expected-error {{use of undeclared identifier 'h'}}
void t6(void) {
int i __attribute__((cleanup((void *)0))); // expected-error {{'cleanup' argument is not a function}}
}
+
+void t7(__attribute__((cleanup(c4))) int a) {} // expected-warning {{'cleanup' attribute only applies to local variables}}