aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ProgramState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp65
1 files changed, 46 insertions, 19 deletions
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 5b6b7339697f..2b401607293b 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -17,6 +17,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -125,16 +126,27 @@ ProgramStateRef ProgramState::bindLoc(Loc LV,
return newState;
}
-ProgramStateRef ProgramState::bindDefault(SVal loc,
- SVal V,
- const LocationContext *LCtx) const {
+ProgramStateRef
+ProgramState::bindDefaultInitial(SVal loc, SVal V,
+ const LocationContext *LCtx) const {
+ ProgramStateManager &Mgr = getStateManager();
+ const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
+ const StoreRef &newStore = Mgr.StoreMgr->BindDefaultInitial(getStore(), R, V);
+ ProgramStateRef new_state = makeWithStore(newStore);
+ return Mgr.getOwningEngine()
+ ? Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx)
+ : new_state;
+}
+
+ProgramStateRef
+ProgramState::bindDefaultZero(SVal loc, const LocationContext *LCtx) const {
ProgramStateManager &Mgr = getStateManager();
const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
- const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
+ const StoreRef &newStore = Mgr.StoreMgr->BindDefaultZero(getStore(), R);
ProgramStateRef new_state = makeWithStore(newStore);
- return Mgr.getOwningEngine() ?
- Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) :
- new_state;
+ return Mgr.getOwningEngine()
+ ? Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx)
+ : new_state;
}
typedef ArrayRef<const MemRegion *> RegionList;
@@ -254,7 +266,7 @@ SVal ProgramState::getSValAsScalarOrLoc(const MemRegion *R) const {
}
SVal ProgramState::getSVal(Loc location, QualType T) const {
- SVal V = getRawSVal(cast<Loc>(location), T);
+ SVal V = getRawSVal(location, T);
// If 'V' is a symbolic value that is *perfectly* constrained to
// be a constant value, use that value instead to lessen the burden
@@ -324,9 +336,8 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
// Get the offset: the minimum value of the array index type.
BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
- // FIXME: This should be using ValueManager::ArrayindexTy...somehow.
if (indexTy.isNull())
- indexTy = Ctx.IntTy;
+ indexTy = svalBuilder.getArrayIndexType();
nonloc::ConcreteInt Min(BVF.getMinValue(indexTy));
// Adjust the index.
@@ -354,6 +365,17 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
return CM.assume(this, inBound.castAs<DefinedSVal>(), Assumption);
}
+ConditionTruthVal ProgramState::isNonNull(SVal V) const {
+ ConditionTruthVal IsNull = isNull(V);
+ if (IsNull.isUnderconstrained())
+ return IsNull;
+ return ConditionTruthVal(!IsNull.getValue());
+}
+
+ConditionTruthVal ProgramState::areEqual(SVal Lhs, SVal Rhs) const {
+ return stateMgr->getSValBuilder().areEqual(this, Lhs, Rhs);
+}
+
ConditionTruthVal ProgramState::isNull(SVal V) const {
if (V.isZeroConstant())
return true;
@@ -426,24 +448,30 @@ void ProgramState::setStore(const StoreRef &newStore) {
// State pretty-printing.
//===----------------------------------------------------------------------===//
-void ProgramState::print(raw_ostream &Out,
- const char *NL, const char *Sep) const {
+void ProgramState::print(raw_ostream &Out, const char *NL, const char *Sep,
+ const LocationContext *LC) const {
// Print the store.
ProgramStateManager &Mgr = getStateManager();
Mgr.getStoreManager().print(getStore(), Out, NL, Sep);
// Print out the environment.
- Env.print(Out, NL, Sep);
+ Env.print(Out, NL, Sep, LC);
// Print out the constraints.
Mgr.getConstraintManager().print(this, Out, NL, Sep);
+ // Print out the tracked dynamic types.
+ printDynamicTypeInfo(this, Out, NL, Sep);
+
+ // Print out tainted symbols.
+ printTaint(Out, NL, Sep);
+
// Print checker-specific data.
- Mgr.getOwningEngine()->printState(Out, this, NL, Sep);
+ Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC);
}
-void ProgramState::printDOT(raw_ostream &Out) const {
- print(Out, "\\l", "\\|");
+void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LC) const {
+ print(Out, "\\l", "\\|", LC);
}
LLVM_DUMP_METHOD void ProgramState::dump() const {
@@ -455,7 +483,7 @@ void ProgramState::printTaint(raw_ostream &Out,
TaintMapImpl TM = get<TaintMap>();
if (!TM.isEmpty())
- Out <<"Tainted Symbols:" << NL;
+ Out <<"Tainted symbols:" << NL;
for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
Out << I->first << " : " << I->second << NL;
@@ -781,8 +809,7 @@ bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const {
// complete. For example, this would not currently identify
// overlapping fields in a union as tainted. To identify this we can
// check for overlapping/nested byte offsets.
- if (Kind == I.second &&
- (R == I.first || R->isSubRegionOf(I.first)))
+ if (Kind == I.second && R->isSubRegionOf(I.first))
return true;
}
}