diff options
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp | 8 | ||||
-rw-r--r-- | clang/test/Analysis/nonnull.m | 9 |
2 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index 273a7a38824..bde902707eb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -43,7 +43,7 @@ public: } // end anonymous namespace void NonNullParamChecker::checkPreCall(const CallEvent &Call, - CheckerContext &C) const { + CheckerContext &C) const { const Decl *FD = Call.getDecl(); if (!FD) return; @@ -66,6 +66,12 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, } bool haveAttrNonNull = Att && Att->isNonNull(idx); + if (!haveAttrNonNull) { + // Check if the parameter is also marked 'nonnull'. + ArrayRef<ParmVarDecl*> parms = Call.parameters(); + if (idx < parms.size()) + haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>(); + } if (!haveRefTypeParam && !haveAttrNonNull) continue; diff --git a/clang/test/Analysis/nonnull.m b/clang/test/Analysis/nonnull.m index c32a7f780ec..a4955ca0a45 100644 --- a/clang/test/Analysis/nonnull.m +++ b/clang/test/Analysis/nonnull.m @@ -2,6 +2,8 @@ @interface MyObject - (void)takePointer:(void *)ptr __attribute__((nonnull(1))); +- (void)takePointerArg:(void *)__attribute__((nonnull)) ptr; + @end void testNonNullMethod(int *p, MyObject *obj) { @@ -21,3 +23,10 @@ void testSubclass(int *p, Subclass *obj) { return; [obj takePointer:p]; // expected-warning{{nonnull}} } + +void testSubclassArg(int *p, Subclass *obj) { + if (p) + return; + [obj takePointerArg:p]; // expected-warning{{nonnull}} +} + |