]> granicus.if.org Git - clang/commitdiff
Teach -Wsign-compare to treat 1 << blah as "idiomatically non-negative".
authorJohn McCall <rjmccall@apple.com>
Wed, 7 Apr 2010 01:14:35 +0000 (01:14 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 7 Apr 2010 01:14:35 +0000 (01:14 +0000)
Fixes a spurious warning in LLVM.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100595 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/compare.c

index f2520fc5eb7f3b291caca00117fb3c1d5ec4f126..5091daf32355520d861651bced43d0a9c5e5ce7e 100644 (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());
 
index 7c8c36f0c145b44681f874884f1d41f33b79a865..631b69420293376aae5126491081087db53601d8 100644 (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;
+}