diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index 273a7a3..61d2b87 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -29,8 +29,9 @@ using namespace ento; namespace { class NonNullParamChecker : public Checker< check::PreCall > { - mutable OwningPtr<BugType> BTAttrNonNull; - mutable OwningPtr<BugType> BTNullRefArg; + mutable std::unique_ptr<BugType> BTAttrNonNull; + mutable std::unique_ptr<BugType> BTNullRefArg; + public: void checkPreCall(const CallEvent &Call, CheckerContext &C) const; @@ -43,7 +44,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 +67,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; @@ -98,7 +105,9 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, V = *CSV_I; DV = V.getAs<DefinedSVal>(); assert(++CSV_I == CSV->end()); - if (!DV) + // FIXME: Handle (some_union){ some_other_union_val }, which turns into + // a LazyCompoundVal inside a CompoundVal. + if (!V.getAs<Loc>()) continue; // Retrieve the corresponding expression. if (const CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(ArgE)) @@ -114,14 +123,14 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, ConstraintManager &CM = C.getConstraintManager(); ProgramStateRef stateNotNull, stateNull; - llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV); + std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV); if (stateNull && !stateNotNull) { // Generate an error node. Check for a null node in case // we cache out. if (ExplodedNode *errorNode = C.generateSink(stateNull)) { - BugReport *R = 0; + BugReport *R = nullptr; if (haveAttrNonNull) R = genReportNullAttrNonNull(errorNode, ArgE); else if (haveRefTypeParam) @@ -156,8 +165,7 @@ BugReport *NonNullParamChecker::genReportNullAttrNonNull( // the BugReport is passed to 'EmitWarning'. if (!BTAttrNonNull) BTAttrNonNull.reset(new BugType( - "Argument with 'nonnull' attribute passed null", - "API")); + this, "Argument with 'nonnull' attribute passed null", "API")); BugReport *R = new BugReport(*BTAttrNonNull, "Null pointer passed as an argument to a 'nonnull' parameter", @@ -171,14 +179,14 @@ BugReport *NonNullParamChecker::genReportNullAttrNonNull( BugReport *NonNullParamChecker::genReportReferenceToNullPointer( const ExplodedNode *ErrorNode, const Expr *ArgE) const { if (!BTNullRefArg) - BTNullRefArg.reset(new BuiltinBug("Dereference of null pointer")); + BTNullRefArg.reset(new BuiltinBug(this, "Dereference of null pointer")); BugReport *R = new BugReport(*BTNullRefArg, "Forming reference to null pointer", ErrorNode); if (ArgE) { const Expr *ArgEDeref = bugreporter::getDerefExpr(ArgE); - if (ArgEDeref == 0) + if (!ArgEDeref) ArgEDeref = ArgE; bugreporter::trackNullOrUndefValue(ErrorNode, ArgEDeref, |