r316268 - [Sema] Fixes for enum handling for tautological comparison diagnostics

Alex L via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 18 15:22:08 PST 2018


Hi Roman,

This commit has caused a regression in LLVM 6 which now triggers
-Wsign-compare for typeof(enum) and typeof(enumConstant). I filed
https://bugs.llvm.org/show_bug.cgi?id=36008. Could you please take a look
at it?

Thanks,
Alex

On 21 October 2017 at 09:44, Roman Lebedev via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: lebedevri
> Date: Sat Oct 21 09:44:03 2017
> New Revision: 316268
>
> URL: http://llvm.org/viewvc/llvm-project?rev=316268&view=rev
> Log:
> [Sema] Fixes for enum handling for tautological comparison diagnostics
>
> Summary:
> As Mattias Eriksson has reported in PR35009, in C, for enums, the
> underlying type should
> be used when checking for the tautological comparison, unlike C++, where
> the enumerator
> values define the value range. So if not in CPlusPlus mode, use the enum
> underlying type.
>
> Also, i have discovered a problem (a crash) when evaluating
> tautological-ness of the following comparison:
> ```
> enum A { A_a = 0 };
> if (a < 0) // expected-warning {{comparison of unsigned enum expression <
> 0 is always false}}
> return 0;
> ```
> This affects both the C and C++, but after the first fix, only C++ code
> was affected.
> That was also fixed, while preserving (i think?) the proper diagnostic
> output.
>
> And while there, attempt to enhance the test coverage.
> Yes, some tests got moved around, sorry about that :)
>
> Fixes PR35009
>
> Reviewers: aaron.ballman, rsmith, rjmccall
>
> Reviewed By: aaron.ballman
>
> Subscribers: Rakete1111, efriedma, materi, cfe-commits
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D39122
>
> Added:
>     cfe/trunk/test/Sema/outof-range-enum-constant-compare.c
>     cfe/trunk/test/Sema/tautological-constant-enum-compare.c
> Modified:
>     cfe/trunk/lib/Sema/SemaChecking.cpp
>     cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
>     cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaChecking.cpp?rev=316268&r1=316267&r2=316268&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Sat Oct 21 09:44:03 2017
> @@ -8181,8 +8181,12 @@ struct IntRange {
>      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 @@ bool isNonBooleanUnsignedValue(Expr *E)
>  }
>
>  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 @@ llvm::Optional<LimitType> IsTypeLimit(Se
>
>    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 @@ llvm::Optional<LimitType> IsTypeLimit(Se
>            Value))
>      return LimitType::Min;
>
> -  return llvm::Optional<LimitType>();
> +  return llvm::None;
>  }
>
>  bool HasEnumType(Expr *E) {
> @@ -8655,9 +8665,12 @@ bool CheckTautologicalComparison(Sema &S
>
>    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;
>
> Added: cfe/trunk/test/Sema/outof-range-enum-constant-compare.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/
> outof-range-enum-constant-compare.c?rev=316268&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/outof-range-enum-constant-compare.c (added)
> +++ cfe/trunk/test/Sema/outof-range-enum-constant-compare.c Sat Oct 21
> 09:44:03 2017
> @@ -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;
> +}
>
> Added: cfe/trunk/test/Sema/tautological-constant-enum-compare.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/
> tautological-constant-enum-compare.c?rev=316268&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/tautological-constant-enum-compare.c (added)
> +++ cfe/trunk/test/Sema/tautological-constant-enum-compare.c Sat Oct 21
> 09:44:03 2017
> @@ -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;
> +}
>
> Modified: cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/
> tautological-unsigned-enum-zero-compare.c?rev=316268&r1=
> 316267&r2=316268&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c
> (original)
> +++ cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.c Sat Oct
> 21 09:44:03 2017
> @@ -1,5 +1,5 @@
> -// 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.
> @@ -7,62 +7,254 @@
>  // 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;
>  }
>
> Modified: cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/
> tautological-unsigned-enum-zero-compare.cpp?rev=316268&
> r1=316267&r2=316268&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp
> (original)
> +++ cfe/trunk/test/Sema/tautological-unsigned-enum-zero-compare.cpp Sat
> Oct 21 09:44:03 2017
> @@ -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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180118/fd928221/attachment-0001.html>


More information about the cfe-commits mailing list