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,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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue