1 // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s 2 // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s 3 // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -DSILENCE -Wno-tautological-unsigned-enum-zero-compare -verify %s 4 5 int main() { 6 // On Windows, all enumerations have a fixed underlying type, which is 'int' 7 // if not otherwise specified, so A is identical to C on Windows. Otherwise, 8 // we follow the C++ rules, which say that the only valid values of A are 0 9 // and 1. 10 enum A { A_foo = 0, A_bar, }; 11 enum A a; 12 13 enum B : unsigned { B_foo = 0, B_bar, }; 14 enum B b; 15 16 enum C : signed { C_foo = 0, C_bar, }; 17 enum C c; 18 19 #ifdef UNSIGNED 20 if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 21 return 0; 22 if (0 >= a) 23 return 0; 24 if (a > 0) 25 return 0; 26 if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 27 return 0; 28 if (a <= 0) 29 return 0; 30 if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 31 return 0; 32 if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 33 return 0; 34 if (0 < a) 35 return 0; 36 37 if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 38 return 0; 39 if (0U >= a) 40 return 0; 41 if (a > 0U) 42 return 0; 43 if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 44 return 0; 45 if (a <= 0U) 46 return 0; 47 if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 48 return 0; 49 if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 50 return 0; 51 if (0U < a) 52 return 0; 53 54 if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 55 return 0; 56 if (0 >= b) 57 return 0; 58 if (b > 0) 59 return 0; 60 if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 61 return 0; 62 if (b <= 0) 63 return 0; 64 if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 65 return 0; 66 if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 67 return 0; 68 if (0 < b) 69 return 0; 70 71 if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 72 return 0; 73 if (0U >= b) 74 return 0; 75 if (b > 0U) 76 return 0; 77 if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 78 return 0; 79 if (b <= 0U) 80 return 0; 81 if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 82 return 0; 83 if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 84 return 0; 85 if (0U < b) 86 return 0; 87 88 if (c < 0) 89 return 0; 90 if (0 >= c) 91 return 0; 92 if (c > 0) 93 return 0; 94 if (0 <= c) 95 return 0; 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 105 // FIXME: These diagnostics are terrible. The issue here is that the signed 106 // enumeration value was promoted to an unsigned type. 107 if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 108 return 0; 109 if (0U >= c) 110 return 0; 111 if (c > 0U) 112 return 0; 113 if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 114 return 0; 115 if (c <= 0U) 116 return 0; 117 if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 118 return 0; 119 if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 120 return 0; 121 if (0U < c) 122 return 0; 123 #elif defined(SIGNED) 124 if (a < 0) 125 return 0; 126 if (0 >= a) 127 return 0; 128 if (a > 0) 129 return 0; 130 if (0 <= a) 131 return 0; 132 if (a <= 0) 133 return 0; 134 if (0 > a) 135 return 0; 136 if (a >= 0) 137 return 0; 138 if (0 < a) 139 return 0; 140 141 // FIXME: As above, the issue here is that the enumeration is promoted to 142 // unsigned. 143 if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 144 return 0; 145 if (0U >= a) 146 return 0; 147 if (a > 0U) 148 return 0; 149 if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 150 return 0; 151 if (a <= 0U) 152 return 0; 153 if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 154 return 0; 155 if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 156 return 0; 157 if (0U < a) 158 return 0; 159 160 if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 161 return 0; 162 if (0 >= b) 163 return 0; 164 if (b > 0) 165 return 0; 166 if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 167 return 0; 168 if (b <= 0) 169 return 0; 170 if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 171 return 0; 172 if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 173 return 0; 174 if (0 < b) 175 return 0; 176 177 if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 178 return 0; 179 if (0U >= b) 180 return 0; 181 if (b > 0U) 182 return 0; 183 if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 184 return 0; 185 if (b <= 0U) 186 return 0; 187 if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 188 return 0; 189 if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 190 return 0; 191 if (0U < b) 192 return 0; 193 194 if (c < 0) 195 return 0; 196 if (0 >= c) 197 return 0; 198 if (c > 0) 199 return 0; 200 if (0 <= c) 201 return 0; 202 if (c <= 0) 203 return 0; 204 if (0 > c) 205 return 0; 206 if (c >= 0) 207 return 0; 208 if (0 < c) 209 return 0; 210 211 if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 212 return 0; 213 if (0U >= c) 214 return 0; 215 if (c > 0U) 216 return 0; 217 if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}} 218 return 0; 219 if (c <= 0U) 220 return 0; 221 if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}} 222 return 0; 223 if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}} 224 return 0; 225 if (0U < c) 226 return 0; 227 #else 228 // expected-no-diagnostics 229 if (a < 0) 230 return 0; 231 if (0 >= a) 232 return 0; 233 if (a > 0) 234 return 0; 235 if (0 <= a) 236 return 0; 237 if (a <= 0) 238 return 0; 239 if (0 > a) 240 return 0; 241 if (a >= 0) 242 return 0; 243 if (0 < a) 244 return 0; 245 246 if (a < 0U) 247 return 0; 248 if (0U >= a) 249 return 0; 250 if (a > 0U) 251 return 0; 252 if (0U <= a) 253 return 0; 254 if (a <= 0U) 255 return 0; 256 if (0U > a) 257 return 0; 258 if (a >= 0U) 259 return 0; 260 if (0U < a) 261 return 0; 262 263 if (b < 0) 264 return 0; 265 if (0 >= b) 266 return 0; 267 if (b > 0) 268 return 0; 269 if (0 <= b) 270 return 0; 271 if (b <= 0) 272 return 0; 273 if (0 > b) 274 return 0; 275 if (b >= 0) 276 return 0; 277 if (0 < b) 278 return 0; 279 280 if (b < 0U) 281 return 0; 282 if (0U >= b) 283 return 0; 284 if (b > 0U) 285 return 0; 286 if (0U <= b) 287 return 0; 288 if (b <= 0U) 289 return 0; 290 if (0U > b) 291 return 0; 292 if (b >= 0U) 293 return 0; 294 if (0U < b) 295 return 0; 296 297 if (c < 0) 298 return 0; 299 if (0 >= c) 300 return 0; 301 if (c > 0) 302 return 0; 303 if (0 <= c) 304 return 0; 305 if (c <= 0) 306 return 0; 307 if (0 > c) 308 return 0; 309 if (c >= 0) 310 return 0; 311 if (0 < c) 312 return 0; 313 314 if (c < 0U) 315 return 0; 316 if (0U >= c) 317 return 0; 318 if (c > 0U) 319 return 0; 320 if (0U <= c) 321 return 0; 322 if (c <= 0U) 323 return 0; 324 if (0U > c) 325 return 0; 326 if (c >= 0U) 327 return 0; 328 if (0U < c) 329 return 0; 330 #endif 331 332 return 1; 333 } 334 335 namespace crash_enum_zero_width { 336 int test() { 337 enum A : unsigned { 338 A_foo = 0 339 }; 340 enum A a; 341 342 // used to crash in llvm::APSInt::getMaxValue() 343 #ifndef SILENCE 344 if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} 345 #else 346 if (a > 0) 347 #endif 348 return 0; 349 350 return 1; 351 } 352 } // namespace crash_enum_zero_width 353