diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-08-24 07:42:09 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-08-24 07:42:09 +0000 |
commit | 3d1125b27e8006385a830f5b3748b7b44d227b4c (patch) | |
tree | 6606420ad0ddbd9cea40556bc359104311a4e6c6 | |
parent | 8268fe7c4bdfa341975a687a8a5e236c2c5b88a4 (diff) |
Teach CFG that 'if (x & 0)' and 'if (x * 0)' is an unfeasible branch.
Fixes <rdar://problem/11005770>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162545 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/CFG.cpp | 24 | ||||
-rw-r--r-- | test/Sema/warn-unreachable.c | 9 |
2 files changed, 33 insertions, 0 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 70ea990f55..f811fa3f0f 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -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); diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c index 636513f62c..2fbe1c78eb 100644 --- a/test/Sema/warn-unreachable.c +++ b/test/Sema/warn-unreachable.c @@ -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}} +} |