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) > 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? 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