diff options
| author | Ted Kremenek <kremenek@apple.com> | 2008-09-01 19:57:52 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2008-09-01 19:57:52 +0000 |
| commit | c4f6d90ba1973853295737b5ba179ee8ae4db37a (patch) | |
| tree | 4c64ee5348675a294e9b26292b3ca77e8c2c603a /clang | |
| parent | 2c5208c59fcdae2e47fe8f98e6506bb098ea2005 (diff) | |
| download | bcm5719-llvm-c4f6d90ba1973853295737b5ba179ee8ae4db37a.tar.gz bcm5719-llvm-c4f6d90ba1973853295737b5ba179ee8ae4db37a.zip | |
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.
llvm-svn: 55610
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 28 | ||||
| -rw-r--r-- | clang/test/Analysis/null-deref-ps.c | 7 | ||||
| -rw-r--r-- | clang/test/Sema/nonnull.c | 2 |
4 files changed, 28 insertions, 13 deletions
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 3510e7dee6b..95d21126500 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/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/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f94711e987c..eb9888e9a28 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/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/clang/test/Analysis/null-deref-ps.c b/clang/test/Analysis/null-deref-ps.c index 92e8daa57e2..06f67da45a6 100644 --- a/clang/test/Analysis/null-deref-ps.c +++ b/clang/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/clang/test/Sema/nonnull.c b/clang/test/Sema/nonnull.c index f8a2a0ed788..9a64ce4320b 100644 --- a/clang/test/Sema/nonnull.c +++ b/clang/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))); |

