@@ -22,6 +22,13 @@ using namespace ento;
22
22
namespace {
23
23
class SimpleSValBuilder : public SValBuilder {
24
24
25
+ // Query the constraint manager whether the SVal has only one possible
26
+ // (integer) value. If that is the case, the value is returned. Otherwise,
27
+ // returns NULL.
28
+ // This is an implementation detail. Checkers should use `getKnownValue()`
29
+ // instead.
30
+ const llvm::APSInt *getConstValue (ProgramStateRef state, SVal V);
31
+
25
32
// With one `simplifySValOnce` call, a compound symbols might collapse to
26
33
// simpler symbol tree that is still possible to further simplify. Thus, we
27
34
// do the simplification on a new symbol tree until we reach the simplest
@@ -45,7 +52,7 @@ class SimpleSValBuilder : public SValBuilder {
45
52
SVal simplifyUntilFixpoint (ProgramStateRef State, SVal Val);
46
53
47
54
// Recursively descends into symbolic expressions and replaces symbols
48
- // with their known values (in the sense of the getKnownValue () method).
55
+ // with their known values (in the sense of the getConstValue () method).
49
56
// We traverse the symbol tree and query the constraint values for the
50
57
// sub-trees and if a value is a constant we do the constant folding.
51
58
SVal simplifySValOnce (ProgramStateRef State, SVal V);
@@ -65,8 +72,9 @@ class SimpleSValBuilder : public SValBuilder {
65
72
SVal evalBinOpLN (ProgramStateRef state, BinaryOperator::Opcode op,
66
73
Loc lhs, NonLoc rhs, QualType resultTy) override ;
67
74
68
- // / getKnownValue - evaluates a given SVal. If the SVal has only one possible
69
- // / (integer) value, that value is returned. Otherwise, returns NULL.
75
+ // / Evaluates a given SVal by recursively evaluating and
76
+ // / simplifying the children SVals. If the SVal has only one possible
77
+ // / (integer) value, that value is returned. Otherwise, returns NULL.
70
78
const llvm::APSInt *getKnownValue (ProgramStateRef state, SVal V) override ;
71
79
72
80
SVal simplifySVal (ProgramStateRef State, SVal V) override ;
@@ -532,7 +540,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
532
540
llvm::APSInt LHSValue = lhs.castAs <nonloc::ConcreteInt>().getValue ();
533
541
534
542
// If we're dealing with two known constants, just perform the operation.
535
- if (const llvm::APSInt *KnownRHSValue = getKnownValue (state, rhs)) {
543
+ if (const llvm::APSInt *KnownRHSValue = getConstValue (state, rhs)) {
536
544
llvm::APSInt RHSValue = *KnownRHSValue;
537
545
if (BinaryOperator::isComparisonOp (op)) {
538
546
// We're looking for a type big enough to compare the two values.
@@ -652,7 +660,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
652
660
}
653
661
654
662
// For now, only handle expressions whose RHS is a constant.
655
- if (const llvm::APSInt *RHSValue = getKnownValue (state, rhs)) {
663
+ if (const llvm::APSInt *RHSValue = getConstValue (state, rhs)) {
656
664
// If both the LHS and the current expression are additive,
657
665
// fold their constants and try again.
658
666
if (BinaryOperator::isAdditiveOp (op)) {
@@ -699,7 +707,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
699
707
}
700
708
701
709
// Is the RHS a constant?
702
- if (const llvm::APSInt *RHSValue = getKnownValue (state, rhs))
710
+ if (const llvm::APSInt *RHSValue = getConstValue (state, rhs))
703
711
return MakeSymIntVal (Sym, op, *RHSValue, resultTy);
704
712
705
713
if (Optional<NonLoc> V = tryRearrange (state, op, lhs, rhs, resultTy))
@@ -1187,8 +1195,8 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
1187
1195
return UnknownVal ();
1188
1196
}
1189
1197
1190
- const llvm::APSInt *SimpleSValBuilder::getKnownValue (ProgramStateRef state,
1191
- SVal V) {
1198
+ const llvm::APSInt *SimpleSValBuilder::getConstValue (ProgramStateRef state,
1199
+ SVal V) {
1192
1200
if (V.isUnknownOrUndef ())
1193
1201
return nullptr ;
1194
1202
@@ -1204,6 +1212,11 @@ const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
1204
1212
return nullptr ;
1205
1213
}
1206
1214
1215
+ const llvm::APSInt *SimpleSValBuilder::getKnownValue (ProgramStateRef state,
1216
+ SVal V) {
1217
+ return getConstValue (state, simplifySVal (state, V));
1218
+ }
1219
+
1207
1220
SVal SimpleSValBuilder::simplifyUntilFixpoint (ProgramStateRef State, SVal Val) {
1208
1221
SVal SimplifiedVal = simplifySValOnce (State, Val);
1209
1222
while (SimplifiedVal != Val) {
@@ -1270,7 +1283,7 @@ SVal SimpleSValBuilder::simplifySValOnce(ProgramStateRef State, SVal V) {
1270
1283
SVal VisitSymbolData (const SymbolData *S) {
1271
1284
// No cache here.
1272
1285
if (const llvm::APSInt *I =
1273
- SVB. getKnownValue (State, SVB. makeSymbolVal (S) ))
1286
+ State-> getConstraintManager (). getSymVal (State, S ))
1274
1287
return Loc::isLocType (S->getType ()) ? (SVal)SVB.makeIntLocVal (*I)
1275
1288
: (SVal)SVB.makeIntVal (*I);
1276
1289
return SVB.makeSymbolVal (S);
0 commit comments