Teach -Wsign-compare to treat 1 << blah as "idiomatically non-negative".

Fixes a spurious warning in LLVM.

llvm-svn: 100595
This commit is contained in:
John McCall 2010-04-07 01:14:35 +00:00
parent 6e95bfc6a5
commit 1bff99322a
2 changed files with 16 additions and 0 deletions

View File

@ -1885,6 +1885,17 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
// Left shift gets black-listed based on a judgement call.
case BinaryOperator::Shl:
// ...except that we want to treat '1 << (blah)' as logically
// positive. It's an important idiom.
if (IntegerLiteral *I
= dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
if (I->getValue() == 1) {
IntRange R = IntRange::forType(C, E->getType());
return IntRange(R.Width, /*NonNegative*/ true);
}
}
// fallthrough
case BinaryOperator::ShlAssign:
return IntRange::forType(C, E->getType());

View File

@ -282,3 +282,8 @@ int test5(unsigned int x) {
&& (x >= 0) // expected-warning {{comparison of unsigned expression >= 0 is always true}}
&& (0 <= x); // expected-warning {{comparison of 0 <= unsigned expression is always true}}
}
int test6(unsigned i, unsigned power) {
unsigned x = (i < (1 << power) ? i : 0);
return x != 3 ? 1 << power : i;
}