Enhance attribute 'nonnull' to be applicable to parameters directly (infix).
This allows the following syntax:
void baz(__attribute__((nonnull)) const char *str);
instead of:
void baz(const char *str) __attribute__((nonnull(1)));
This also extends to Objective-C methods.
The checking logic in Sema is not as clean as I would like. Effectively
now we need to check both the FunctionDecl/ObjCMethodDecl and the parameters,
so the point of truth is spread in two places, but the logic isn't that
cumbersome.
Implements <rdar://problem/14691443>.
llvm-svn: 199467
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 714e975..c3acd52 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -736,6 +736,7 @@
const NamedDecl *FDecl,
const Expr * const *ExprArgs,
SourceLocation CallSiteLoc) {
+ // Check the attributes attached to the method/function itself.
for (specific_attr_iterator<NonNullAttr>
I = FDecl->specific_attr_begin<NonNullAttr>(),
E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I) {
@@ -747,6 +748,21 @@
CheckNonNullArgument(S, ExprArgs[*i], CallSiteLoc);
}
}
+
+ // Check the attributes on the parameters.
+ ArrayRef<ParmVarDecl*> parms;
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
+ parms = FD->parameters();
+ else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(FDecl))
+ parms = MD->parameters();
+
+ unsigned argIndex = 0;
+ for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();
+ I != E; ++I, ++argIndex) {
+ const ParmVarDecl *PVD = *I;
+ if (PVD->hasAttr<NonNullAttr>())
+ CheckNonNullArgument(S, ExprArgs[argIndex], CallSiteLoc);
+ }
}
/// Handles the checks for format strings, non-POD arguments to vararg