summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaChecking.cpp11
-rw-r--r--clang/test/Sema/compare.c5
2 files changed, 16 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f2520fc5eb7..5091daf3235 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/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<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());
diff --git a/clang/test/Sema/compare.c b/clang/test/Sema/compare.c
index 7c8c36f0c14..631b6942029 100644
--- a/clang/test/Sema/compare.c
+++ b/clang/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;
+}
OpenPOWER on IntegriCloud