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 %s 4 // 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 %s 7 // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \ 8 // RUN: -verify=silence %s 9 10 // silence-no-diagnostics 11 12 int 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 0 16 // 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 to 44 // 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 signed 114 // 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 135 namespace crash_enum_zero_width { 136 int test() { 137 enum A : unsigned { 138 A_foo = 0 139 }; 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_width 149