On Mon, Oct 23, 2017 at 2:02 PM, Roman Lebedev <lebedev...@gmail.com> wrote: > On Mon, Oct 23, 2017 at 2:13 PM, Hans Wennborg <h...@chromium.org> wrote: > Hi. > >> This seems to have had the side effect of introducing a new warning in >> Chromium builds: >> >> ../../third_party/expat/files/lib/xmlparse.c(2429,24): error: >> comparison of integers of different signs: 'enum XML_Error' and >> 'unsigned int' [-Werror,-Wsign-compare] >> if (code > 0 && code < sizeof(message)/sizeof(message[0])) >> ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > (I guess this is on windows)
Yes. > >> I'm not sure if this was intentional or not. >> >> The warning seems technically correct here, though not very useful in >> this specific case. > I *believe* that was caused by the fix for IntRange::forValueOfCanonicalType() > to use enum's underlying type for C code. That fix was absolutely intentional. > > However that new -Wsign-compare diagnostic (and i suspect there may be > more repercussions) was not really intentional. > However as you have said, and i think i agree, the diagnostic valid. > > So perhaps i simply should add a test and release notes entry? Sounds reasonable. It turns out we only got this single extra -Wsign-compare warning, so it didn't turn out to be a big problem for us. > > Roman. > >> On Sat, Oct 21, 2017 at 6:44 PM, Roman Lebedev via cfe-commits >> <cfe-commits@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@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits