Refactor static analyzer to use simpler interface to constant expression evaluation.

llvm-svn: 141983
This commit is contained in:
Richard Smith 2011-10-14 20:22:00 +00:00
parent 465841e48c
commit faa32a9b83
2 changed files with 17 additions and 42 deletions

View File

@ -437,20 +437,12 @@ private:
/// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
/// if we can evaluate to a known value, otherwise return -1.
TryResult tryEvaluateBool(Expr *S) {
Expr::EvalResult Result;
if (!tryEvaluate(S, Result))
bool Result;
if (!BuildOpts.PruneTriviallyFalseEdges ||
S->isTypeDependent() || S->isValueDependent() ||
!S->EvaluateAsBooleanCondition(Result, *Context))
return TryResult();
if (Result.Val.isInt())
return Result.Val.getInt().getBoolValue();
if (Result.Val.isLValue()) {
const Expr *e = Result.Val.getLValueBase();
const CharUnits &c = Result.Val.getLValueOffset();
if (!e && c.isZero())
return false;
}
return TryResult();
return Result;
}
};
@ -2343,11 +2335,8 @@ static bool shouldAddCase(bool &switchExclusivelyCovered,
if (!switchExclusivelyCovered) {
if (switchCond->Val.isInt()) {
// Evaluate the LHS of the case value.
Expr::EvalResult V1;
CS->getLHS()->Evaluate(V1, Ctx);
assert(V1.Val.isInt());
const llvm::APSInt &lhsInt = CS->getLHS()->EvaluateKnownConstInt(Ctx);
const llvm::APSInt &condInt = switchCond->Val.getInt();
const llvm::APSInt &lhsInt = V1.Val.getInt();
if (condInt == lhsInt) {
addCase = true;
@ -2356,10 +2345,8 @@ static bool shouldAddCase(bool &switchExclusivelyCovered,
else if (condInt < lhsInt) {
if (const Expr *RHS = CS->getRHS()) {
// Evaluate the RHS of the case value.
Expr::EvalResult V2;
RHS->Evaluate(V2, Ctx);
assert(V2.Val.isInt());
if (V2.Val.getInt() <= condInt) {
const llvm::APSInt &V2 = RHS->EvaluateKnownConstInt(Ctx);
if (V2 <= condInt) {
addCase = true;
switchExclusivelyCovered = true;
}

View File

@ -1086,25 +1086,13 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
const CaseStmt *Case = I.getCase();
// Evaluate the LHS of the case value.
Expr::EvalResult V1;
bool b = Case->getLHS()->Evaluate(V1, getContext());
// Sanity checks. These go away in Release builds.
assert(b && V1.Val.isInt() && !V1.HasSideEffects
&& "Case condition must evaluate to an integer constant.");
(void)b; // silence unused variable warning
assert(V1.Val.getInt().getBitWidth() ==
getContext().getTypeSize(CondE->getType()));
llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType()));
// Get the RHS of the case, if it exists.
Expr::EvalResult V2;
if (const Expr *E = Case->getRHS()) {
b = E->Evaluate(V2, getContext());
assert(b && V2.Val.isInt() && !V2.HasSideEffects
&& "Case condition must evaluate to an integer constant.");
(void)b; // silence unused variable warning
}
llvm::APSInt V2;
if (const Expr *E = Case->getRHS())
V2 = E->EvaluateKnownConstInt(getContext());
else
V2 = V1;
@ -1113,7 +1101,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
// This should be easy once we have "ranges" for NonLVals.
do {
nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1));
DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
CondV, CaseVal);
@ -1142,11 +1130,11 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
}
// Concretize the next value in the range.
if (V1.Val.getInt() == V2.Val.getInt())
if (V1 == V2)
break;
++V1.Val.getInt();
assert (V1.Val.getInt() <= V2.Val.getInt());
++V1;
assert (V1 <= V2);
} while (true);
}