Tidy up sema processing of attribute "nonull":
- warn about nonnull being applied to functions with no pointer arguments
- continue processing argument list in the attribute when we encounter a non-pointer parameter being marked as nonnull
- when no argument list is specified, only mark pointers as nonnull. This fixes PR 2732 and radar 6188814.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55610 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f94711e..eb9888e 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -282,20 +282,32 @@
// FIXME: Should also highlight argument in decl.
S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only,
"nonnull", Ex->getSourceRange());
- return;
+ continue;
}
NonNullArgs.push_back(x);
}
- if (!NonNullArgs.empty()) {
- unsigned* start = &NonNullArgs[0];
- unsigned size = NonNullArgs.size();
- std::sort(start, start + size);
- d->addAttr(new NonNullAttr(start, size));
+ // If no arguments were specified to __attribute__((nonnull)) then all
+ // pointer arguments have a nonnull attribute.
+ if (NonNullArgs.empty()) {
+ unsigned idx = 0;
+
+ for (FunctionTypeProto::arg_type_iterator
+ I=proto->arg_type_begin(), E=proto->arg_type_end(); I!=E; ++I, ++idx)
+ if ((*I)->isPointerType())
+ NonNullArgs.push_back(idx);
+
+ if (NonNullArgs.empty()) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
+ return;
+ }
}
- else
- d->addAttr(new NonNullAttr());
+
+ unsigned* start = &NonNullArgs[0];
+ unsigned size = NonNullArgs.size();
+ std::sort(start, start + size);
+ d->addAttr(new NonNullAttr(start, size));
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {