aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2013-02-24 07:20:53 +0000
committerTed Kremenek <kremenek@apple.com>2013-02-24 07:20:53 +0000
commit0dd15d78fb0c99faa5df724139ba4c16a9a345c6 (patch)
treeb2c2e938776913263a1fd631f8ffa21db0ff594b
parent026cd1a273d16eaa9a66be92f38b1f907202e542 (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
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h13
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h15
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp24
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));
}
}
}