diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-10-13 19:38:02 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-10-13 19:38:02 +0000 |
commit | ab4f3cb21c8624913d7b7f676f66a86ce3dae1de (patch) | |
tree | c78e197bf1ae71353c5250abae632f465ef31379 /lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp | |
parent | 0d98bafc69f015df1bfa8466aff896c9714b4685 (diff) |
[analyzer] Check all 'nonnull' attributes, not just the first one.
Patch by Daniel Fahlgren!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219625 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index 650aa8b875..cb2d46b583 100644 --- a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -49,16 +49,27 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, if (!FD) return; - // FIXME: This is wrong; there can be multiple attributes with different sets - // of non-null parameter indices. - const NonNullAttr *Att = FD->getAttr<NonNullAttr>(); + // Merge all non-null attributes + unsigned NumArgs = Call.getNumArgs(); + llvm::SmallBitVector AttrNonNull(NumArgs); + for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) { + if (!NonNull->args_size()) { + AttrNonNull.set(0, NumArgs); + break; + } + for (unsigned Val : NonNull->args()) { + if (Val >= NumArgs) + continue; + AttrNonNull.set(Val); + } + } ProgramStateRef state = C.getState(); CallEvent::param_type_iterator TyI = Call.param_type_begin(), TyE = Call.param_type_end(); - for (unsigned idx = 0, count = Call.getNumArgs(); idx != count; ++idx){ + for (unsigned idx = 0; idx < NumArgs; ++idx) { // Check if the parameter is a reference. We want to report when reference // to a null pointer is passed as a paramter. @@ -68,7 +79,7 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, TyI++; } - bool haveAttrNonNull = Att && Att->isNonNull(idx); + bool haveAttrNonNull = AttrNonNull[idx]; if (!haveAttrNonNull) { // Check if the parameter is also marked 'nonnull'. ArrayRef<ParmVarDecl*> parms = Call.parameters(); |