summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h6
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h7
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h9
-rw-r--r--clang/lib/StaticAnalyzer/Core/ProgramState.cpp11
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp11
5 files changed, 42 insertions, 2 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index c01600d5c96..1e1bbc876b2 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -37,6 +37,12 @@ public:
/// Construct a ConstraintVal indicating the constraint is underconstrained.
ConditionTruthVal() {}
+ /// \return Stored value, assuming that the value is known.
+ /// Crashes otherwise.
+ bool getValue() const {
+ return *Val;
+ }
+
/// Return true if the constraint is perfectly constrained to 'true'.
bool isConstrainedTrue() const {
return Val.hasValue() && Val.getValue();
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index dd2564b0a3c..f1283996e56 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -212,10 +212,17 @@ public:
assumeInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
const llvm::APSInt &To) const;
+ /// \brief Check if the given SVal is not constrained to zero and is not
+ /// a zero constant.
+ ConditionTruthVal isNonNull(SVal V) const;
+
/// \brief Check if the given SVal is constrained to zero or is a zero
/// constant.
ConditionTruthVal isNull(SVal V) const;
+ /// \return Whether values \p Lhs and \p Rhs are equal.
+ ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const;
+
/// Utility method for getting regions.
const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index d58d0a690c8..dae5b5495b2 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -29,6 +29,8 @@ class CXXBoolLiteralExpr;
namespace ento {
+class ConditionTruthVal;
+
class SValBuilder {
virtual void anchor();
protected:
@@ -124,7 +126,12 @@ public:
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
SVal lhs, SVal rhs, QualType type);
-
+
+ /// \return Whether values in \p lhs and \p rhs are equal at \p state.
+ ConditionTruthVal areEqual(ProgramStateRef state, SVal lhs, SVal rhs);
+
+ SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs);
+
DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs,
DefinedOrUnknownSVal rhs);
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
index 871bbf0b6cb..34d4970df2d 100644
--- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -354,6 +354,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;
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 04452e3e7cc..f49995d50cc 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -413,10 +413,19 @@ SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
type);
}
+ConditionTruthVal SValBuilder::areEqual(ProgramStateRef state, SVal lhs,
+ SVal rhs) {
+ return state->isNonNull(evalEQ(state, lhs, rhs));
+}
+
+SVal SValBuilder::evalEQ(ProgramStateRef state, SVal lhs, SVal rhs) {
+ return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType());
+}
+
DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
DefinedOrUnknownSVal lhs,
DefinedOrUnknownSVal rhs) {
- return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType())
+ return evalEQ(state, static_cast<SVal>(lhs), static_cast<SVal>(rhs))
.castAs<DefinedOrUnknownSVal>();
}
OpenPOWER on IntegriCloud