From: John McCall Date: Wed, 7 Apr 2010 01:14:35 +0000 (+0000) Subject: Teach -Wsign-compare to treat 1 << blah as "idiomatically non-negative". X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3aae6093dd8f3aecb66d7ff1f4b44e6a86765db4;p=clang Teach -Wsign-compare to treat 1 << blah as "idiomatically non-negative". Fixes a spurious warning in LLVM. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100595 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index f2520fc5eb..5091daf323 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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(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()); diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 7c8c36f0c1..631b694202 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -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; +}