namespace {
class SimpleSValBuilder : public SValBuilder {
+ // Query the constraint manager whether the SVal has only one possible
+ // (integer) value. If that is the case, the value is returned. Otherwise,
+ // returns NULL.
+ // This is an implementation detail. Checkers should use `getKnownValue()`
+ // instead.
+ const llvm::APSInt *getConstValue(ProgramStateRef state, SVal V);
+
// With one `simplifySValOnce` call, a compound symbols might collapse to
// simpler symbol tree that is still possible to further simplify. Thus, we
// do the simplification on a new symbol tree until we reach the simplest
SVal simplifyUntilFixpoint(ProgramStateRef State, SVal Val);
// Recursively descends into symbolic expressions and replaces symbols
- // with their known values (in the sense of the getKnownValue() method).
+ // with their known values (in the sense of the getConstValue() method).
// We traverse the symbol tree and query the constraint values for the
// sub-trees and if a value is a constant we do the constant folding.
SVal simplifySValOnce(ProgramStateRef State, SVal V);
SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
Loc lhs, NonLoc rhs, QualType resultTy) override;
- /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
- /// (integer) value, that value is returned. Otherwise, returns NULL.
+ /// Evaluates a given SVal by recursively evaluating and
+ /// simplifying the children SVals. If the SVal has only one possible
+ /// (integer) value, that value is returned. Otherwise, returns NULL.
const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal V) override;
SVal simplifySVal(ProgramStateRef State, SVal V) override;
llvm::APSInt LHSValue = lhs.castAs<nonloc::ConcreteInt>().getValue();
// If we're dealing with two known constants, just perform the operation.
- if (const llvm::APSInt *KnownRHSValue = getKnownValue(state, rhs)) {
+ if (const llvm::APSInt *KnownRHSValue = getConstValue(state, rhs)) {
llvm::APSInt RHSValue = *KnownRHSValue;
if (BinaryOperator::isComparisonOp(op)) {
// We're looking for a type big enough to compare the two values.
}
// For now, only handle expressions whose RHS is a constant.
- if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) {
+ if (const llvm::APSInt *RHSValue = getConstValue(state, rhs)) {
// If both the LHS and the current expression are additive,
// fold their constants and try again.
if (BinaryOperator::isAdditiveOp(op)) {
}
// Is the RHS a constant?
- if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
+ if (const llvm::APSInt *RHSValue = getConstValue(state, rhs))
return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
if (Optional<NonLoc> V = tryRearrange(state, op, lhs, rhs, resultTy))
return UnknownVal();
}
-const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
- SVal V) {
+const llvm::APSInt *SimpleSValBuilder::getConstValue(ProgramStateRef state,
+ SVal V) {
if (V.isUnknownOrUndef())
return nullptr;
return nullptr;
}
+const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
+ SVal V) {
+ return getConstValue(state, simplifySVal(state, V));
+}
+
SVal SimpleSValBuilder::simplifyUntilFixpoint(ProgramStateRef State, SVal Val) {
SVal SimplifiedVal = simplifySValOnce(State, Val);
while (SimplifiedVal != Val) {
SVal VisitSymbolData(const SymbolData *S) {
// No cache here.
if (const llvm::APSInt *I =
- SVB.getKnownValue(State, SVB.makeSymbolVal(S)))
+ State->getConstraintManager().getSymVal(State, S))
return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
: (SVal)SVB.makeIntVal(*I);
return SVB.makeSymbolVal(S);