зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
8268fe7c4b
Коммит
3d1125b27e
|
@ -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);
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче