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:
parent
c57e503c48
commit
039fac0347
|
@ -537,24 +537,28 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
|||
const Expr *RHS = cast<Expr>(Elem.getStmt());
|
||||
SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
|
||||
|
||||
DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
|
||||
ProgramStateRef StTrue, StFalse;
|
||||
llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
|
||||
if (StTrue) {
|
||||
if (StFalse) {
|
||||
// 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());
|
||||
} else {
|
||||
// The value is known to be true.
|
||||
X = getSValBuilder().makeIntVal(1, B->getType());
|
||||
}
|
||||
if (RHSVal.isUndef()) {
|
||||
X = RHSVal;
|
||||
} else {
|
||||
// The value is known to be false.
|
||||
assert(StFalse && "Infeasible path!");
|
||||
X = getSValBuilder().makeIntVal(0, B->getType());
|
||||
DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
|
||||
ProgramStateRef StTrue, StFalse;
|
||||
llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
|
||||
if (StTrue) {
|
||||
if (StFalse) {
|
||||
// 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());
|
||||
} else {
|
||||
// The value is known to be true.
|
||||
X = getSValBuilder().makeIntVal(1, B->getType());
|
||||
}
|
||||
} else {
|
||||
// The value is known to be false.
|
||||
assert(StFalse && "Infeasible path!");
|
||||
X = getSValBuilder().makeIntVal(0, B->getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
|
||||
}
|
||||
|
||||
|
|
|
@ -151,3 +151,9 @@ int rdar_12075238_(unsigned long count) {
|
|||
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}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue