diff options
author | Ted Kremenek <kremenek@apple.com> | 2013-02-24 07:20:53 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2013-02-24 07:20:53 +0000 |
commit | 0dd15d78fb0c99faa5df724139ba4c16a9a345c6 (patch) | |
tree | b2c2e938776913263a1fd631f8ffa21db0ff594b | |
parent | 026cd1a273d16eaa9a66be92f38b1f907202e542 (diff) |
Add "KnownSVal" to represent SVals that cannot be UnknownSVal.
This provides a few sundry cleanups, and allows us to provide
a compile-time check for a case that was a runtime assertion.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175987 91177308-0d34-0410-b5e6-96231b3b80d8
4 files changed, 34 insertions, 26 deletions
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index 75bf9613e2..bef4b30a35 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -99,7 +99,7 @@ class FindLastStoreBRVisitor { const MemRegion *R; SVal V; - bool satisfied; + bool Satisfied; public: /// \brief Convenience method to create a visitor given only the MemRegion. @@ -112,13 +112,10 @@ public: /// the BugReport. static void registerStatementVarDecls(BugReport &BR, const Stmt *S); - FindLastStoreBRVisitor(SVal v, const MemRegion *r) - : R(r), V(v), satisfied(false) { - assert (!V.isUnknown() && "Cannot track unknown value."); - - // TODO: Does it make sense to allow undef values here? - // (If not, also see UndefCapturedBlockVarChecker)? - } + FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R) + : R(R), + V(V), + Satisfied(false) {} void Profile(llvm::FoldingSetNodeID &ID) const; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 31d02f51ea..03e84447e7 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -219,7 +219,7 @@ public: private: friend class SVal; - static bool isKind(const SVal& V) { + static bool isKind(const SVal &V) { return V.getBaseKind() == UnknownKind; } }; @@ -242,6 +242,19 @@ private: } }; + +/// \brief Represents an SVal that is guaranteed to not be UnknownVal. +class KnownSVal : public SVal { + KnownSVal() {} + friend class SVal; + static bool isKind(const SVal &V) { + return !V.isUnknown(); + } +public: + KnownSVal(const DefinedSVal &V) : SVal(V) {} + KnownSVal(const UndefinedVal &V) : SVal(V) {} +}; + class NonLoc : public DefinedSVal { protected: NonLoc() {} diff --git a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp index 3f8363762f..f0ca8a8312 100644 --- a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp @@ -75,9 +75,8 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE, continue; // Get the VarRegion associated with VD in the local stack frame. - SVal VRVal = state->getSVal(I.getOriginalRegion()); - - if (VRVal.isUndef()) + if (Optional<UndefinedVal> V = + state->getSVal(I.getOriginalRegion()).getAs<UndefinedVal>()) { if (ExplodedNode *N = C.generateSink()) { if (!BT) BT.reset(new BuiltinBug("uninitialized variable captured by block")); @@ -92,11 +91,12 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE, BugReport *R = new BugReport(*BT, os.str(), N); if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD)) R->addRange(Ex->getSourceRange()); - R->addVisitor(new FindLastStoreBRVisitor(VRVal, VR)); + R->addVisitor(new FindLastStoreBRVisitor(*V, VR)); R->disablePathPruning(); // need location of block C.emitReport(R); } + } } } diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 5dc8dfc8de..f59458ca6e 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -354,7 +354,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, BugReport &BR) { - if (satisfied) + if (Satisfied) return NULL; const ExplodedNode *StoreSite = 0; @@ -410,7 +410,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, if (!StoreSite) return NULL; - satisfied = true; + Satisfied = true; // If we have an expression that provided the value, try to track where it // came from. @@ -449,8 +449,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, if (const BlockDataRegion *BDR = dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) { if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) { - V = State->getSVal(OriginalR); - BR.addVisitor(new FindLastStoreBRVisitor(V, OriginalR)); + if (Optional<KnownSVal> KV = + State->getSVal(OriginalR).getAs<KnownSVal>()) + BR.addVisitor(new FindLastStoreBRVisitor(*KV, OriginalR)); } } } @@ -698,7 +699,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, report.addVisitor(ConstraintTracker); } - report.addVisitor(new FindLastStoreBRVisitor(V, R)); + if (Optional<KnownSVal> KV = V.getAs<KnownSVal>()) + report.addVisitor(new FindLastStoreBRVisitor(*KV, R)); return true; } } @@ -711,7 +713,6 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, // Uncomment this to find cases where we aren't properly getting the // base value that was dereferenced. // assert(!V.isUnknownOrUndef()); - // Is it a symbolic value? if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) { // At this point we are dealing with the region's LValue. @@ -743,14 +744,11 @@ FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N, assert(R && "The memory region is null."); ProgramStateRef state = N->getState(); - SVal V = state->getSVal(R); - if (V.isUnknown()) - return 0; - - return new FindLastStoreBRVisitor(V, R); + if (Optional<KnownSVal> KV = state->getSVal(R).getAs<KnownSVal>()) + return new FindLastStoreBRVisitor(*KV, R); + return 0; } - PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, @@ -808,7 +806,7 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR, if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) { // Register a new visitor with the BugReport. - BR.addVisitor(new FindLastStoreBRVisitor(V, R)); + BR.addVisitor(new FindLastStoreBRVisitor(V.castAs<KnownSVal>(), R)); } } } |