Teach CFG that 'if (x & 0)' and 'if (x * 0)' is an unfeasible branch.

Fixes <rdar://problem/11005770>.

llvm-svn: 162545
This commit is contained in:
Ted Kremenek 2012-08-24 07:42:09 +00:00
parent 75c100b8e5
commit 64fea5fc8f
2 changed files with 33 additions and 0 deletions

View File

@ -467,6 +467,30 @@ private:
CachedBoolEvals[S] = Result; // update or insert
return Result;
}
else {
switch (Bop->getOpcode()) {
default: break;
// For 'x & 0' and 'x * 0', we can determine that
// the value is always false.
case BO_Mul:
case BO_And: {
// If either operand is zero, we know the value
// must be false.
llvm::APSInt IntVal;
if (Bop->getLHS()->EvaluateAsInt(IntVal, *Context)) {
if (IntVal.getBoolValue() == false) {
return TryResult(false);
}
}
if (Bop->getRHS()->EvaluateAsInt(IntVal, *Context)) {
if (IntVal.getBoolValue() == false) {
return TryResult(false);
}
}
}
break;
}
}
}
return evaluateAsBooleanConditionNoCache(S);

View File

@ -132,3 +132,12 @@ void PR9774(int *s) {
s[i] = 0;
}
// Test case for <rdar://problem/11005770>. We should treat code guarded
// by 'x & 0' and 'x * 0' as unreachable.
void calledFun();
void test_mul_and_zero(int x) {
if (x & 0) calledFun(); // expected-warning {{will never be executed}}
if (0 & x) calledFun(); // expected-warning {{will never be executed}}
if (x * 0) calledFun(); // expected-warning {{will never be executed}}
if (0 * x) calledFun(); // expected-warning {{will never be executed}}
}