149 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only \2// RUN: -Wtautological-unsigned-enum-zero-compare \3// RUN: -verify=unsigned,unsigned-signed %s4// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \5// RUN: -Wtautological-unsigned-enum-zero-compare \6// RUN: -verify=unsigned-signed %s7// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \8// RUN: -verify=silence %s9 10// silence-no-diagnostics11 12int main() {13 // On Windows, all enumerations have a fixed underlying type, which is 'int'14 // if not otherwise specified, so A is identical to C on Windows. Otherwise,15 // we follow the C++ rules, which say that the only valid values of A are 016 // and 1.17 enum A { A_foo = 0, A_bar, };18 enum A a;19 20 enum B : unsigned { B_foo = 0, B_bar, };21 enum B b;22 23 enum C : signed { C_foo = 0, C_bar, };24 enum C c;25 26 if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}}27 return 0;28 if (0 >= a)29 return 0;30 if (a > 0)31 return 0;32 if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}}33 return 0;34 if (a <= 0)35 return 0;36 if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}}37 return 0;38 if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}}39 return 0;40 if (0 < a)41 return 0;42 43 // FIXME: As below, the issue here is that the enumeration is promoted to44 // unsigned.45 if (a < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}46 return 0;47 if (0U >= a)48 return 0;49 if (a > 0U)50 return 0;51 if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}52 return 0;53 if (a <= 0U)54 return 0;55 if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}56 return 0;57 if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}58 return 0;59 if (0U < a)60 return 0;61 62 if (b < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}63 return 0;64 if (0 >= b)65 return 0;66 if (b > 0)67 return 0;68 if (0 <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}69 return 0;70 if (b <= 0)71 return 0;72 if (0 > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}73 return 0;74 if (b >= 0) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}75 return 0;76 if (0 < b)77 return 0;78 79 if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}80 return 0;81 if (0U >= b)82 return 0;83 if (b > 0U)84 return 0;85 if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}86 return 0;87 if (b <= 0U)88 return 0;89 if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}90 return 0;91 if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}92 return 0;93 if (0U < b)94 return 0;95 96 if (c < 0)97 return 0;98 if (0 >= c)99 return 0;100 if (c > 0)101 return 0;102 if (0 <= c)103 return 0;104 if (c <= 0)105 return 0;106 if (0 > c)107 return 0;108 if (c >= 0)109 return 0;110 if (0 < c)111 return 0;112 113 // FIXME: These diagnostics are terrible. The issue here is that the signed114 // enumeration value was promoted to an unsigned type.115 if (c < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}116 return 0;117 if (0U >= c)118 return 0;119 if (c > 0U)120 return 0;121 if (0U <= c) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}122 return 0;123 if (c <= 0U)124 return 0;125 if (0U > c) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}126 return 0;127 if (c >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}128 return 0;129 if (0U < c)130 return 0;131 132 return 1;133}134 135namespace crash_enum_zero_width {136int test() {137 enum A : unsigned {138 A_foo = 0139 };140 enum A a;141 142 // used to crash in llvm::APSInt::getMaxValue()143 if (a < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}144 return 0;145 146 return 1;147}148} // namespace crash_enum_zero_width149