aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-09-01 19:57:52 +0000
committerTed Kremenek <kremenek@apple.com>2008-09-01 19:57:52 +0000
commit7fb43c17eb2b4102f40a80a355629aacd70589ad (patch)
treef429575b93e6201e8d581b8b468bf2c7e08af8a2
parent73419bf6cbf8e5f7a0f9b8855d6531db264ae899 (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticKinds.def4
-rw-r--r--lib/Sema/SemaDeclAttr.cpp28
-rw-r--r--test/Analysis/null-deref-ps.c7
-rw-r--r--test/Sema/nonnull.c2
4 files changed, 28 insertions, 13 deletions
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index 3510e7dee6..95d2112650 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -692,7 +692,9 @@ DIAG(err_mode_wrong_type, ERROR,
"type of machine mode does not match type of base type")
DIAG(err_attr_wrong_decl, ERROR,
"'%0' attribute invalid on this declaration, requires typedef or value")
-
+DIAG(warn_attribute_nonnull_no_pointers, WARNING,
+ "'nonnull' attribute applied to function with no pointer arguments")
+
// Clang-Specific Attributes
DIAG(err_attribute_iboutlet_non_ivar, ERROR,
"'iboutlet' attribute can only be applied to instance variables")
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f94711e987..eb9888e9a2 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -282,20 +282,32 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// 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) {
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 92e8daa57e..06f67da45a 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -56,11 +56,12 @@ int f5() {
return s[0]; // no-warning
}
-int bar(int* p) __attribute__((nonnull));
+int bar(int* p, int q) __attribute__((nonnull));
int f6(int *p) {
- return !p ? bar(p) : *p; // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
-}
+ return !p ? bar(p, 1) // expected-warning {{Null pointer passed as an argument to a 'nonnull' parameter}}
+ : bar(p, 0); // no-warning
+}
int* qux();
diff --git a/test/Sema/nonnull.c b/test/Sema/nonnull.c
index f8a2a0ed78..9a64ce4320 100644
--- a/test/Sema/nonnull.c
+++ b/test/Sema/nonnull.c
@@ -1,6 +1,6 @@
// RUN: clang -fsyntax-only -verify %s
-int f1(int x) __attribute__((nonnull));
+int f1(int x) __attribute__((nonnull)); // expected-warning{{'nonnull' attribute applied to function with no pointer arguments}}
int f2(int *x) __attribute__ ((nonnull (1)));
int f3(int *x) __attribute__ ((nonnull (0))); // expected-error {{'nonnull' attribute parameter 1 is out of bounds}}
int f4(int *x, int *y) __attribute__ ((nonnull (1,2)));