On Tue, Oct 24, 2017 at 3:00 PM, Hans Wennborg <h...@chromium.org> wrote: > 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.
Ok, committed in https://reviews.llvm.org/rL316500 Roman. >> >> 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