This revision was automatically updated to reflect the committed changes.
Closed by commit rL316268: [Sema] Fixes for enum handling for tautological 
comparison diagnostics (authored by lebedevri).

Changed prior to commit:
  https://reviews.llvm.org/D39122?vs=119759&id=119760#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D39122

Files:
  cfe/trunk/lib/Sema/SemaChecking.cpp
  cfe/trunk/test/Sema/outof-range-enum-constant-compare.c
  cfe/trunk/test/Sema/tautological-constant-enum-compare.c
  cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
  cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp

Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -8181,8 +8181,12 @@
     if (const AtomicType *AT = dyn_cast<AtomicType>(T))
       T = AT->getValueType().getTypePtr();
 
-    // For enum types, use the known bit width of the enumerators.
-    if (const EnumType *ET = dyn_cast<EnumType>(T)) {
+    if (!C.getLangOpts().CPlusPlus) {
+      // For enum types in C code, use the underlying datatype.
+      if (const EnumType *ET = dyn_cast<EnumType>(T))
+        T = ET->getDecl()->getIntegerType().getDesugaredType(C).getTypePtr();
+    } else if (const EnumType *ET = dyn_cast<EnumType>(T)) {
+      // For enum types in C++, use the known bit width of the enumerators.
       EnumDecl *Enum = ET->getDecl();
       // In C++11, enums without definitions can have an explicitly specified
       // underlying type.  Use this type to compute the range.
@@ -8584,8 +8588,10 @@
 }
 
 enum class LimitType {
-  Max, // e.g. 32767 for short
-  Min  // e.g. -32768 for short
+  Max = 1U << 0U,  // e.g. 32767 for short
+  Min = 1U << 1U,  // e.g. -32768 for short
+  Both = Max | Min // When the value is both the Min and the Max limit at the
+                   // same time; e.g. in C++, A::a in enum A { a = 0 };
 };
 
 /// Checks whether Expr 'Constant' may be the
@@ -8608,6 +8614,10 @@
 
   IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT);
 
+  // Special-case for C++ for enum with one enumerator with value of 0.
+  if (OtherRange.Width == 0)
+    return Value == 0 ? LimitType::Both : llvm::Optional<LimitType>();
+
   if (llvm::APSInt::isSameValue(
           llvm::APSInt::getMaxValue(OtherRange.Width,
                                     OtherT->isUnsignedIntegerType()),
@@ -8620,7 +8630,7 @@
           Value))
     return LimitType::Min;
 
-  return llvm::Optional<LimitType>();
+  return llvm::None;
 }
 
 bool HasEnumType(Expr *E) {
@@ -8655,9 +8665,12 @@
 
   bool ConstIsLowerBound = (Op == BO_LT || Op == BO_LE) ^ RhsConstant;
   bool ResultWhenConstEqualsOther = (Op == BO_LE || Op == BO_GE);
-  bool ResultWhenConstNeOther =
-      ConstIsLowerBound ^ (ValueType == LimitType::Max);
-  if (ResultWhenConstEqualsOther != ResultWhenConstNeOther)
+  if (ValueType != LimitType::Both) {
+    bool ResultWhenConstNeOther =
+        ConstIsLowerBound ^ (ValueType == LimitType::Max);
+    if (ResultWhenConstEqualsOther != ResultWhenConstNeOther)
+      return false; // The comparison is not tautological.
+  } else if (ResultWhenConstEqualsOther == ConstIsLowerBound)
     return false; // The comparison is not tautological.
 
   const bool Result = ResultWhenConstEqualsOther;
Index: cfe/trunk/test/Sema/outof-range-enum-constant-compare.c
===================================================================
--- cfe/trunk/test/Sema/outof-range-enum-constant-compare.c
+++ cfe/trunk/test/Sema/outof-range-enum-constant-compare.c
@@ -0,0 +1,379 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s
+
+int main() {
+  enum A { A_a = 2 };
+  enum A a;
+
+#ifdef SILENCE
+  // expected-no-diagnostics
+#endif
+
+#ifdef UNSIGNED
+#ifndef SILENCE
+  if (a < 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (4294967296 >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a > 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (4294967296 <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a <= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (4294967296 > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a >= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (4294967296 < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a == 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (4294967296 != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a != 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (4294967296 == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+
+  if (a < 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (4294967296U >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a > 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (4294967296U <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a <= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (4294967296U > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a >= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (4294967296U < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a == 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+  if (4294967296U != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a != 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
+    return 0;
+  if (4294967296U == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
+    return 0;
+#else // SILENCE
+  if (a < 4294967296)
+    return 0;
+  if (4294967296 >= a)
+    return 0;
+  if (a > 4294967296)
+    return 0;
+  if (4294967296 <= a)
+    return 0;
+  if (a <= 4294967296)
+    return 0;
+  if (4294967296 > a)
+    return 0;
+  if (a >= 4294967296)
+    return 0;
+  if (4294967296 < a)
+    return 0;
+  if (a == 4294967296)
+    return 0;
+  if (4294967296 != a)
+    return 0;
+  if (a != 4294967296)
+    return 0;
+  if (4294967296 == a)
+    return 0;
+
+  if (a < 4294967296U)
+    return 0;
+  if (4294967296U >= a)
+    return 0;
+  if (a > 4294967296U)
+    return 0;
+  if (4294967296U <= a)
+    return 0;
+  if (a <= 4294967296U)
+    return 0;
+  if (4294967296U > a)
+    return 0;
+  if (a >= 4294967296U)
+    return 0;
+  if (4294967296U < a)
+    return 0;
+  if (a == 4294967296U)
+    return 0;
+  if (4294967296U != a)
+    return 0;
+  if (a != 4294967296U)
+    return 0;
+  if (4294967296U == a)
+    return 0;
+#endif
+#elif defined(SIGNED)
+#ifndef SILENCE
+  if (a < -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+    return 0;
+  if (-2147483649 >= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a > -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+    return 0;
+  if (-2147483649 <= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a <= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+    return 0;
+  if (-2147483649 > a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a >= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+    return 0;
+  if (-2147483649 < a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a == -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+    return 0;
+  if (-2147483649 != a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a != -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
+    return 0;
+  if (-2147483649 == a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
+    return 0;
+
+  if (a < 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+    return 0;
+  if (2147483648 >= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a > 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+    return 0;
+  if (2147483648 <= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a <= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+    return 0;
+  if (2147483648 > a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a >= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+    return 0;
+  if (2147483648 < a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+    return 0;
+  if (a == 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+    return 0;
+  if (2147483648 != a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+    return 0;
+  if (a != 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
+    return 0;
+  if (2147483648 == a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
+    return 0;
+#else // SILENCE
+  if (a < -2147483649)
+    return 0;
+  if (-2147483649 >= a)
+    return 0;
+  if (a > -2147483649)
+    return 0;
+  if (-2147483649 <= a)
+    return 0;
+  if (a <= -2147483649)
+    return 0;
+  if (-2147483649 > a)
+    return 0;
+  if (a >= -2147483649)
+    return 0;
+  if (-2147483649 < a)
+    return 0;
+  if (a == -2147483649)
+    return 0;
+  if (-2147483649 != a)
+    return 0;
+  if (a != -2147483649)
+    return 0;
+  if (-2147483649 == a)
+    return 0;
+
+  if (a < 2147483648)
+    return 0;
+  if (2147483648 >= a)
+    return 0;
+  if (a > 2147483648)
+    return 0;
+  if (2147483648 <= a)
+    return 0;
+  if (a <= 2147483648)
+    return 0;
+  if (2147483648 > a)
+    return 0;
+  if (a >= 2147483648)
+    return 0;
+  if (2147483648 < a)
+    return 0;
+  if (a == 2147483648)
+    return 0;
+  if (2147483648 != a)
+    return 0;
+  if (a != 2147483648)
+    return 0;
+  if (2147483648 == a)
+    return 0;
+#endif
+#endif
+}
+
+// https://bugs.llvm.org/show_bug.cgi?id=35009
+int PR35009() {
+  enum A { A_a = 2 };
+  enum A a;
+
+  // in C, this should not warn.
+
+  if (a < 1)
+    return 0;
+  if (1 >= a)
+    return 0;
+  if (a > 1)
+    return 0;
+  if (1 <= a)
+    return 0;
+  if (a <= 1)
+    return 0;
+  if (1 > a)
+    return 0;
+  if (a >= 1)
+    return 0;
+  if (1 < a)
+    return 0;
+  if (a == 1)
+    return 0;
+  if (1 != a)
+    return 0;
+  if (a != 1)
+    return 0;
+  if (1 == a)
+    return 0;
+
+  if (a < 1U)
+    return 0;
+  if (1U >= a)
+    return 0;
+  if (a > 1U)
+    return 0;
+  if (1U <= a)
+    return 0;
+  if (a <= 1U)
+    return 0;
+  if (1U > a)
+    return 0;
+  if (a >= 1U)
+    return 0;
+  if (1U < a)
+    return 0;
+  if (a == 1U)
+    return 0;
+  if (1U != a)
+    return 0;
+  if (a != 1U)
+    return 0;
+  if (1U == a)
+    return 0;
+
+  if (a < 2)
+    return 0;
+  if (2 >= a)
+    return 0;
+  if (a > 2)
+    return 0;
+  if (2 <= a)
+    return 0;
+  if (a <= 2)
+    return 0;
+  if (2 > a)
+    return 0;
+  if (a >= 2)
+    return 0;
+  if (2 < a)
+    return 0;
+  if (a == 2)
+    return 0;
+  if (2 != a)
+    return 0;
+  if (a != 2)
+    return 0;
+  if (2 == a)
+    return 0;
+
+  if (a < 2U)
+    return 0;
+  if (2U >= a)
+    return 0;
+  if (a > 2U)
+    return 0;
+  if (2U <= a)
+    return 0;
+  if (a <= 2U)
+    return 0;
+  if (2U > a)
+    return 0;
+  if (a >= 2U)
+    return 0;
+  if (2U < a)
+    return 0;
+  if (a == 2U)
+    return 0;
+  if (2U != a)
+    return 0;
+  if (a != 2U)
+    return 0;
+  if (2U == a)
+    return 0;
+
+  if (a < 3)
+    return 0;
+  if (3 >= a)
+    return 0;
+  if (a > 3)
+    return 0;
+  if (3 <= a)
+    return 0;
+  if (a <= 3)
+    return 0;
+  if (3 > a)
+    return 0;
+  if (a >= 3)
+    return 0;
+  if (3 < a)
+    return 0;
+  if (a == 3)
+    return 0;
+  if (3 != a)
+    return 0;
+  if (a != 3)
+    return 0;
+  if (3 == a)
+    return 0;
+
+  if (a < 3U)
+    return 0;
+  if (3U >= a)
+    return 0;
+  if (a > 3U)
+    return 0;
+  if (3U <= a)
+    return 0;
+  if (a <= 3U)
+    return 0;
+  if (3U > a)
+    return 0;
+  if (a >= 3U)
+    return 0;
+  if (3U < a)
+    return 0;
+  if (a == 3U)
+    return 0;
+  if (3U != a)
+    return 0;
+  if (a != 3U)
+    return 0;
+  if (3U == a)
+    return 0;
+
+  return 1;
+}
Index: cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
===================================================================
--- cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
+++ cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
@@ -1,68 +1,260 @@
-// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DALL_WARN -verify %s
-// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGN_WARN -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
 // RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -Wno-tautological-unsigned-enum-zero-compare -verify %s
 
 // Okay, this is where it gets complicated.
 // Then default enum sigdness is target-specific.
 // On windows, it is signed by default. We do not want to warn in that case.
 
 int main() {
-  enum A { A_foo, A_bar };
+  enum A { A_a = 0 };
   enum A a;
+  enum B { B_a = -1 };
+  enum B b;
 
-#ifdef ALL_WARN
+#ifdef UNSIGNED
   if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0 >= a)
+    return 0;
+  if (a > 0)
     return 0;
   if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (a <= 0)
+    return 0;
   if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0 < a)
+    return 0;
+
   if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
     return 0;
   if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (a <= 0U)
+    return 0;
   if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
-#elif defined(SIGN_WARN)
-  if (a < 0) // ok
+  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < a)
+    return 0;
+
+  if (b < 0)
+    return 0;
+  if (0 >= b)
+    return 0;
+  if (b > 0)
+    return 0;
+  if (0 <= b)
+    return 0;
+  if (b <= 0)
+    return 0;
+  if (0 > b)
+    return 0;
+  if (b >= 0)
+    return 0;
+  if (0 < b)
+    return 0;
+
+  if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+    return 0;
+  if (0U >= b)
+    return 0;
+  if (b > 0U)
+    return 0;
+  if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+    return 0;
+  if (b <= 0U)
+    return 0;
+  if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+    return 0;
+  if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
     return 0;
-  if (a >= 0) // ok
+  if (0U < b)
     return 0;
-  if (0 <= a) // ok
+#elif defined(SIGNED)
+  if (a < 0)
+    return 0;
+  if (0 >= a)
+    return 0;
+  if (a > 0)
+    return 0;
+  if (0 <= a)
+    return 0;
+  if (a <= 0)
     return 0;
-  if (0 > a) // ok
+  if (0 > a)
     return 0;
+  if (a >= 0)
+    return 0;
+  if (0 < a)
+    return 0;
+
   if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
     return 0;
   if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (a <= 0U)
+    return 0;
   if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < a)
+    return 0;
+
+  if (b < 0)
+    return 0;
+  if (0 >= b)
+    return 0;
+  if (b > 0)
+    return 0;
+  if (0 <= b)
+    return 0;
+  if (b <= 0)
+    return 0;
+  if (0 > b)
+    return 0;
+  if (b >= 0)
+    return 0;
+  if (0 < b)
+    return 0;
+
+  if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+    return 0;
+  if (0U >= b)
+    return 0;
+  if (b > 0U)
+    return 0;
+  if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+    return 0;
+  if (b <= 0U)
+    return 0;
+  if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+    return 0;
+  if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < b)
+    return 0;
 #else
   // expected-no-diagnostics
+
   if (a < 0)
     return 0;
-  if (a >= 0)
+  if (0 >= a)
+    return 0;
+  if (a > 0)
     return 0;
   if (0 <= a)
     return 0;
+  if (a <= 0)
+    return 0;
   if (0 > a)
     return 0;
+  if (a >= 0)
+    return 0;
+  if (0 < a)
+    return 0;
+
   if (a < 0U)
     return 0;
-  if (a >= 0U)
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
     return 0;
   if (0U <= a)
     return 0;
+  if (a <= 0U)
+    return 0;
   if (0U > a)
     return 0;
+  if (a >= 0U)
+    return 0;
+  if (0U < a)
+    return 0;
+
+  if (b < 0)
+    return 0;
+  if (0 >= b)
+    return 0;
+  if (b > 0)
+    return 0;
+  if (0 <= b)
+    return 0;
+  if (b <= 0)
+    return 0;
+  if (0 > b)
+    return 0;
+  if (b >= 0)
+    return 0;
+  if (0 < b)
+    return 0;
+
+  if (b < 0U)
+    return 0;
+  if (0U >= b)
+    return 0;
+  if (b > 0U)
+    return 0;
+  if (0U <= b)
+    return 0;
+  if (b <= 0U)
+    return 0;
+  if (0U > b)
+    return 0;
+  if (b >= 0U)
+    return 0;
+  if (0U < b)
+    return 0;
 #endif
 
+  if (a == 0)
+    return 0;
+  if (0 != a)
+    return 0;
+  if (a != 0)
+    return 0;
+  if (0 == a)
+    return 0;
+
+  if (a == 0U)
+    return 0;
+  if (0U != a)
+    return 0;
+  if (a != 0U)
+    return 0;
+  if (0U == a)
+    return 0;
+
+  if (b == 0)
+    return 0;
+  if (0 != b)
+    return 0;
+  if (b != 0)
+    return 0;
+  if (0 == b)
+    return 0;
+
+  if (b == 0U)
+    return 0;
+  if (0U != b)
+    return 0;
+  if (b != 0U)
+    return 0;
+  if (0U == b)
+    return 0;
+
   return 1;
 }
Index: cfe/trunk/test/Sema/tautological-constant-enum-compare.c
===================================================================
--- cfe/trunk/test/Sema/tautological-constant-enum-compare.c
+++ cfe/trunk/test/Sema/tautological-constant-enum-compare.c
@@ -0,0 +1,419 @@
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
+
+int main() {
+  enum A { A_a = 2 };
+  enum A a;
+
+#ifdef SILENCE
+  // expected-no-diagnostics
+#endif
+
+#ifdef UNSIGNED
+#ifndef SILENCE
+  if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+    return 0;
+  if (0 >= a)
+    return 0;
+  if (a > 0)
+    return 0;
+  if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+    return 0;
+  if (a <= 0)
+    return 0;
+  if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+    return 0;
+  if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0 < a)
+    return 0;
+
+  if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+    return 0;
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
+    return 0;
+  if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
+    return 0;
+  if (a <= 0U)
+    return 0;
+  if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
+    return 0;
+  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < a)
+    return 0;
+
+  if (a < 4294967295)
+    return 0;
+  if (4294967295 >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}}
+    return 0;
+  if (a > 4294967295) // expected-warning {{comparison 'enum A' > 4294967295 is always false}}
+    return 0;
+  if (4294967295 <= a)
+    return 0;
+  if (a <= 4294967295) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}}
+    return 0;
+  if (4294967295 > a)
+    return 0;
+  if (a >= 4294967295)
+    return 0;
+  if (4294967295 < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}}
+    return 0;
+
+  if (a < 4294967295U)
+    return 0;
+  if (4294967295U >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}}
+    return 0;
+  if (a > 4294967295U) // expected-warning {{comparison 'enum A' > 4294967295 is always false}}
+    return 0;
+  if (4294967295U <= a)
+    return 0;
+  if (a <= 4294967295U) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}}
+    return 0;
+  if (4294967295U > a)
+    return 0;
+  if (a >= 4294967295U)
+    return 0;
+  if (4294967295U < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}}
+    return 0;
+#else // SILENCE
+  if (a < 0)
+    return 0;
+  if (0 >= a)
+    return 0;
+  if (a > 0)
+    return 0;
+  if (0 <= a)
+    return 0;
+  if (a <= 0)
+    return 0;
+  if (0 > a)
+    return 0;
+  if (a >= 0)
+    return 0;
+  if (0 < a)
+    return 0;
+
+  if (a < 0U)
+    return 0;
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
+    return 0;
+  if (0U <= a)
+    return 0;
+  if (a <= 0U)
+    return 0;
+  if (0U > a)
+    return 0;
+  if (a >= 0U)
+    return 0;
+  if (0U < a)
+    return 0;
+
+  if (a < 4294967295)
+    return 0;
+  if (4294967295 >= a)
+    return 0;
+  if (a > 4294967295)
+    return 0;
+  if (4294967295 <= a)
+    return 0;
+  if (a <= 4294967295)
+    return 0;
+  if (4294967295 > a)
+    return 0;
+  if (a >= 4294967295)
+    return 0;
+  if (4294967295 < a)
+    return 0;
+
+  if (a < 4294967295U)
+    return 0;
+  if (4294967295U >= a)
+    return 0;
+  if (a > 4294967295U)
+    return 0;
+  if (4294967295U <= a)
+    return 0;
+  if (a <= 4294967295U)
+    return 0;
+  if (4294967295U > a)
+    return 0;
+  if (a >= 4294967295U)
+    return 0;
+  if (4294967295U < a)
+    return 0;
+#endif
+#elif defined(SIGNED)
+#ifndef SILENCE
+  if (a < -2147483648) // expected-warning {{comparison 'enum A' < -2147483648 is always false}}
+    return 0;
+  if (-2147483648 >= a)
+    return 0;
+  if (a > -2147483648)
+    return 0;
+  if (-2147483648 <= a) // expected-warning {{comparison -2147483648 <= 'enum A' is always true}}
+    return 0;
+  if (a <= -2147483648)
+    return 0;
+  if (-2147483648 > a) // expected-warning {{comparison -2147483648 > 'enum A' is always false}}
+    return 0;
+  if (a >= -2147483648) // expected-warning {{comparison 'enum A' >= -2147483648 is always true}}
+    return 0;
+  if (-2147483648 < a)
+    return 0;
+
+  if (a < 2147483647)
+    return 0;
+  if (2147483647 >= a) // expected-warning {{comparison 2147483647 >= 'enum A' is always true}}
+    return 0;
+  if (a > 2147483647) // expected-warning {{comparison 'enum A' > 2147483647 is always false}}
+    return 0;
+  if (2147483647 <= a)
+    return 0;
+  if (a <= 2147483647) // expected-warning {{comparison 'enum A' <= 2147483647 is always true}}
+    return 0;
+  if (2147483647 > a)
+    return 0;
+  if (a >= 2147483647)
+    return 0;
+  if (2147483647 < a) // expected-warning {{comparison 2147483647 < 'enum A' is always false}}
+    return 0;
+
+  if (a < 2147483647U)
+    return 0;
+  if (2147483647U >= a) // expected-warning {{comparison 2147483647 >= 'enum A' is always true}}
+    return 0;
+  if (a > 2147483647U) // expected-warning {{comparison 'enum A' > 2147483647 is always false}}
+    return 0;
+  if (2147483647U <= a)
+    return 0;
+  if (a <= 2147483647U) // expected-warning {{comparison 'enum A' <= 2147483647 is always true}}
+    return 0;
+  if (2147483647U > a)
+    return 0;
+  if (a >= 2147483647U)
+    return 0;
+  if (2147483647U < a) // expected-warning {{comparison 2147483647 < 'enum A' is always false}}
+    return 0;
+#else // SILENCE
+  if (a < -2147483648)
+    return 0;
+  if (-2147483648 >= a)
+    return 0;
+  if (a > -2147483648)
+    return 0;
+  if (-2147483648 <= a)
+    return 0;
+  if (a <= -2147483648)
+    return 0;
+  if (-2147483648 > a)
+    return 0;
+  if (a >= -2147483648)
+    return 0;
+  if (-2147483648 < a)
+    return 0;
+
+  if (a < 2147483647)
+    return 0;
+  if (2147483647 >= a)
+    return 0;
+  if (a > 2147483647)
+    return 0;
+  if (2147483647 <= a)
+    return 0;
+  if (a <= 2147483647)
+    return 0;
+  if (2147483647 > a)
+    return 0;
+  if (a >= 2147483647)
+    return 0;
+  if (2147483647 < a)
+    return 0;
+
+  if (a < 2147483647U)
+    return 0;
+  if (2147483647U >= a)
+    return 0;
+  if (a > 2147483647U)
+    return 0;
+  if (2147483647U <= a)
+    return 0;
+  if (a <= 2147483647U)
+    return 0;
+  if (2147483647U > a)
+    return 0;
+  if (a >= 2147483647U)
+    return 0;
+  if (2147483647U < a)
+    return 0;
+#endif
+#endif
+
+  return 1;
+}
+
+// https://bugs.llvm.org/show_bug.cgi?id=35009
+int PR35009() {
+  enum A { A_a = 2 };
+  enum A a;
+
+  // in C, this should not warn.
+
+  if (a < 1)
+    return 0;
+  if (1 >= a)
+    return 0;
+  if (a > 1)
+    return 0;
+  if (1 <= a)
+    return 0;
+  if (a <= 1)
+    return 0;
+  if (1 > a)
+    return 0;
+  if (a >= 1)
+    return 0;
+  if (1 < a)
+    return 0;
+  if (a == 1)
+    return 0;
+  if (1 != a)
+    return 0;
+  if (a != 1)
+    return 0;
+  if (1 == a)
+    return 0;
+
+  if (a < 1U)
+    return 0;
+  if (1U >= a)
+    return 0;
+  if (a > 1U)
+    return 0;
+  if (1U <= a)
+    return 0;
+  if (a <= 1U)
+    return 0;
+  if (1U > a)
+    return 0;
+  if (a >= 1U)
+    return 0;
+  if (1U < a)
+    return 0;
+  if (a == 1U)
+    return 0;
+  if (1U != a)
+    return 0;
+  if (a != 1U)
+    return 0;
+  if (1U == a)
+    return 0;
+
+  if (a < 2)
+    return 0;
+  if (2 >= a)
+    return 0;
+  if (a > 2)
+    return 0;
+  if (2 <= a)
+    return 0;
+  if (a <= 2)
+    return 0;
+  if (2 > a)
+    return 0;
+  if (a >= 2)
+    return 0;
+  if (2 < a)
+    return 0;
+  if (a == 2)
+    return 0;
+  if (2 != a)
+    return 0;
+  if (a != 2)
+    return 0;
+  if (2 == a)
+    return 0;
+
+  if (a < 2U)
+    return 0;
+  if (2U >= a)
+    return 0;
+  if (a > 2U)
+    return 0;
+  if (2U <= a)
+    return 0;
+  if (a <= 2U)
+    return 0;
+  if (2U > a)
+    return 0;
+  if (a >= 2U)
+    return 0;
+  if (2U < a)
+    return 0;
+  if (a == 2U)
+    return 0;
+  if (2U != a)
+    return 0;
+  if (a != 2U)
+    return 0;
+  if (2U == a)
+    return 0;
+
+  if (a < 3)
+    return 0;
+  if (3 >= a)
+    return 0;
+  if (a > 3)
+    return 0;
+  if (3 <= a)
+    return 0;
+  if (a <= 3)
+    return 0;
+  if (3 > a)
+    return 0;
+  if (a >= 3)
+    return 0;
+  if (3 < a)
+    return 0;
+  if (a == 3)
+    return 0;
+  if (3 != a)
+    return 0;
+  if (a != 3)
+    return 0;
+  if (3 == a)
+    return 0;
+
+  if (a < 3U)
+    return 0;
+  if (3U >= a)
+    return 0;
+  if (a > 3U)
+    return 0;
+  if (3U <= a)
+    return 0;
+  if (a <= 3U)
+    return 0;
+  if (3U > a)
+    return 0;
+  if (a >= 3U)
+    return 0;
+  if (3U < a)
+    return 0;
+  if (a == 3U)
+    return 0;
+  if (3U != a)
+    return 0;
+  if (a != 3U)
+    return 0;
+  if (3U == a)
+    return 0;
+
+  return 1;
+}
Index: cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp
===================================================================
--- cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp
+++ cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp
@@ -1,176 +1,347 @@
-// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only -DALL_WARN -verify %s
-// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -DSIGN_WARN -verify %s
-// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -Wno-tautological-unsigned-enum-zero-compare -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -DSILENCE -Wno-tautological-unsigned-enum-zero-compare -verify %s
 
 // Okay, this is where it gets complicated.
 // Then default enum sigdness is target-specific.
 // On windows, it is signed by default. We do not want to warn in that case.
 
 int main() {
-  enum A { A_foo, A_bar };
+  enum A { A_foo = 0, A_bar, };
   enum A a;
 
-  enum B : unsigned { B_foo, B_bar };
+  enum B : unsigned { B_foo = 0, B_bar, };
   enum B b;
 
-  enum C : signed { c_foo, c_bar };
+  enum C : signed { C_foo = 0, C_bar, };
   enum C c;
 
-#ifdef ALL_WARN
+#ifdef UNSIGNED
   if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0 >= a)
+    return 0;
+  if (a > 0)
     return 0;
   if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (a <= 0)
+    return 0;
   if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0 < a)
+    return 0;
+
   if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
     return 0;
   if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (a <= 0U)
+    return 0;
   if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < a)
+    return 0;
 
   if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0 >= b)
+    return 0;
+  if (b > 0)
     return 0;
   if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (b <= 0)
+    return 0;
   if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0 < b)
+    return 0;
+
   if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= b)
+    return 0;
+  if (b > 0U)
     return 0;
   if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (b <= 0U)
+    return 0;
   if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < b)
+    return 0;
 
-  if (c < 0) // ok
+  if (c < 0)
+    return 0;
+  if (0 >= c) // expected-warning {{comparison 0 >= 'enum C' is always true}}
+    return 0;
+  if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
+    return 0;
+  if (0 <= c)
+    return 0;
+  if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
     return 0;
-  if (c >= 0) // ok
+  if (0 > c)
     return 0;
-  if (0 <= c) // ok
+  if (c >= 0)
     return 0;
-  if (0 > c) // ok
+  if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
     return 0;
+
   if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= c)
+    return 0;
+  if (c > 0U)
     return 0;
   if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (c <= 0U)
+    return 0;
   if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
-#elif defined(SIGN_WARN)
-  if (a < 0) // ok
+  if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
     return 0;
-  if (a >= 0) // ok
+  if (0U < c)
     return 0;
-  if (0 <= a) // ok
+#elif defined(SIGNED)
+  if (a < 0)
+    return 0;
+  if (0 >= a) // expected-warning {{comparison 0 >= 'enum A' is always true}}
     return 0;
-  if (0 > a) // ok
+  if (a > 0) // expected-warning {{comparison 'enum A' > 0 is always false}}
+    return 0;
+  if (0 <= a)
     return 0;
+  if (a <= 0) // expected-warning {{comparison 'enum A' <= 0 is always true}}
+    return 0;
+  if (0 > a)
+    return 0;
+  if (a >= 0)
+    return 0;
+  if (0 < a) // expected-warning {{comparison 0 < 'enum A' is always false}}
+    return 0;
+
   if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
     return 0;
   if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (a <= 0U)
+    return 0;
   if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < a)
+    return 0;
 
   if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0 >= b)
+    return 0;
+  if (b > 0)
     return 0;
   if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (b <= 0)
+    return 0;
   if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0 < b)
+    return 0;
+
   if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= b)
+    return 0;
+  if (b > 0U)
     return 0;
   if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (b <= 0U)
+    return 0;
   if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < b)
+    return 0;
 
-  if (c < 0) // ok
+  if (c < 0)
     return 0;
-  if (c >= 0) // ok
+  if (0 >= c) // expected-warning {{comparison 0 >= 'enum C' is always true}}
     return 0;
-  if (0 <= c) // ok
+  if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
+    return 0;
+  if (0 <= c)
     return 0;
-  if (0 > c) // ok
+  if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
+    return 0;
+  if (0 > c)
+    return 0;
+  if (c >= 0)
     return 0;
+  if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
+    return 0;
+
   if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
     return 0;
-  if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+  if (0U >= c)
+    return 0;
+  if (c > 0U)
     return 0;
   if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
     return 0;
+  if (c <= 0U)
+    return 0;
   if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
     return 0;
+  if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
+    return 0;
+  if (0U < c)
+    return 0;
 #else
-  // expected-no-diagnostics
   if (a < 0)
     return 0;
-  if (a >= 0)
+  if (0 >= a) // expected-warning {{comparison 0 >= 'enum A' is always true}}
+    return 0;
+  if (a > 0) // expected-warning {{comparison 'enum A' > 0 is always false}}
     return 0;
   if (0 <= a)
     return 0;
+  if (a <= 0) // expected-warning {{comparison 'enum A' <= 0 is always true}}
+    return 0;
   if (0 > a)
     return 0;
+  if (a >= 0)
+    return 0;
+  if (0 < a) // expected-warning {{comparison 0 < 'enum A' is always false}}
+    return 0;
+
   if (a < 0U)
     return 0;
-  if (a >= 0U)
+  if (0U >= a)
+    return 0;
+  if (a > 0U)
     return 0;
   if (0U <= a)
     return 0;
+  if (a <= 0U)
+    return 0;
   if (0U > a)
     return 0;
+  if (a >= 0U)
+    return 0;
+  if (0U < a)
+    return 0;
 
   if (b < 0)
     return 0;
-  if (b >= 0)
+  if (0 >= b)
+    return 0;
+  if (b > 0)
     return 0;
   if (0 <= b)
     return 0;
+  if (b <= 0)
+    return 0;
   if (0 > b)
     return 0;
+  if (b >= 0)
+    return 0;
+  if (0 < b)
+    return 0;
+
   if (b < 0U)
     return 0;
-  if (b >= 0U)
+  if (0U >= b)
+    return 0;
+  if (b > 0U)
     return 0;
   if (0U <= b)
     return 0;
+  if (b <= 0U)
+    return 0;
   if (0U > b)
     return 0;
+  if (b >= 0U)
+    return 0;
+  if (0U < b)
+    return 0;
 
   if (c < 0)
     return 0;
-  if (c >= 0)
+  if (0 >= c) // expected-warning {{comparison 0 >= 'enum C' is always true}}
+    return 0;
+  if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
     return 0;
   if (0 <= c)
     return 0;
+  if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
+    return 0;
   if (0 > c)
     return 0;
+  if (c >= 0)
+    return 0;
+  if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
+    return 0;
+
   if (c < 0U)
     return 0;
-  if (c >= 0U)
+  if (0U >= c)
+    return 0;
+  if (c > 0U)
     return 0;
   if (0U <= c)
     return 0;
+  if (c <= 0U)
+    return 0;
   if (0U > c)
     return 0;
+  if (c >= 0U)
+    return 0;
+  if (0U < c)
+    return 0;
+#endif
+
+  return 1;
+}
+
+namespace crash_enum_zero_width {
+int test() {
+  enum A : unsigned {
+    A_foo = 0
+  };
+  enum A a;
+
+  // used to crash in llvm::APSInt::getMaxValue()
+#ifndef SILENCE
+  if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
+#else
+  if (a > 0)
 #endif
+    return 0;
 
   return 1;
 }
+} // namespace crash_enum_zero_width
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to