Correctly propagate uninitialized values within logical expressions.

Fixes assertion failure reported in PR 14635 and
<rdar://problem/12902945> respectively.

llvm-svn: 172263
This commit is contained in:
Ted Kremenek 2013-01-11 22:35:39 +00:00
parent c57e503c48
commit 039fac0347
2 changed files with 25 additions and 15 deletions

View File

@ -537,12 +537,16 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
const Expr *RHS = cast<Expr>(Elem.getStmt()); const Expr *RHS = cast<Expr>(Elem.getStmt());
SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext()); SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
if (RHSVal.isUndef()) {
X = RHSVal;
} else {
DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal); DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
ProgramStateRef StTrue, StFalse; ProgramStateRef StTrue, StFalse;
llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS); llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
if (StTrue) { if (StTrue) {
if (StFalse) { if (StFalse) {
// We can't constrain the value to 0 or 1; the best we can do is a cast. // We can't constrain the value to 0 or 1.
// The best we can do is a cast.
X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType()); X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType());
} else { } else {
// The value is known to be true. // The value is known to be true.
@ -554,7 +558,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
X = getSValBuilder().makeIntVal(0, B->getType()); X = getSValBuilder().makeIntVal(0, B->getType());
} }
} }
}
Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X)); Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
} }

View File

@ -151,3 +151,9 @@ int rdar_12075238_(unsigned long count) {
return 0; return 0;
} }
// Test that we handle an uninitialized value within a logical expression.
void PR14635(int *p) {
int a = 0, b;
*p = a || b; // expected-warning {{Assigned value is garbage or undefined}}
}