105e46484SHal Finkel // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only \
2*c5417aafSRoman Lebedev // RUN:            -Wtautological-unsigned-enum-zero-compare \
305e46484SHal Finkel // RUN:            -verify=unsigned,unsigned-signed %s
405e46484SHal Finkel // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \
5*c5417aafSRoman Lebedev // RUN:            -Wtautological-unsigned-enum-zero-compare \
605e46484SHal Finkel // RUN:            -verify=unsigned-signed %s
705e46484SHal Finkel // RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \
805e46484SHal Finkel // RUN:            -verify=silence %s
905e46484SHal Finkel 
1005e46484SHal Finkel // silence-no-diagnostics
1130d26086SRoman Lebedev 
main()1230d26086SRoman Lebedev int main() {
13371e9e8aSRichard Smith   // On Windows, all enumerations have a fixed underlying type, which is 'int'
14371e9e8aSRichard Smith   // if not otherwise specified, so A is identical to C on Windows. Otherwise,
15371e9e8aSRichard Smith   // we follow the C++ rules, which say that the only valid values of A are 0
16371e9e8aSRichard Smith   // and 1.
17ca1aaaccSRoman Lebedev   enum A { A_foo = 0, A_bar, };
1830d26086SRoman Lebedev   enum A a;
1930d26086SRoman Lebedev 
20ca1aaaccSRoman Lebedev   enum B : unsigned { B_foo = 0, B_bar, };
2130d26086SRoman Lebedev   enum B b;
2230d26086SRoman Lebedev 
23ca1aaaccSRoman Lebedev   enum C : signed { C_foo = 0, C_bar, };
2430d26086SRoman Lebedev   enum C c;
2530d26086SRoman Lebedev 
2605e46484SHal Finkel   if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}}
2730d26086SRoman Lebedev     return 0;
28ca1aaaccSRoman Lebedev   if (0 >= a)
29ca1aaaccSRoman Lebedev     return 0;
30ca1aaaccSRoman Lebedev   if (a > 0)
3130d26086SRoman Lebedev     return 0;
3205e46484SHal Finkel   if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}}
3330d26086SRoman Lebedev     return 0;
34ca1aaaccSRoman Lebedev   if (a <= 0)
35ca1aaaccSRoman Lebedev     return 0;
3605e46484SHal Finkel   if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}}
3730d26086SRoman Lebedev     return 0;
3805e46484SHal Finkel   if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}}
39ca1aaaccSRoman Lebedev     return 0;
40ca1aaaccSRoman Lebedev   if (0 < a)
41ca1aaaccSRoman Lebedev     return 0;
42ca1aaaccSRoman Lebedev 
4305e46484SHal Finkel   // FIXME: As below, the issue here is that the enumeration is promoted to
4405e46484SHal Finkel   // unsigned.
4505e46484SHal Finkel   if (a < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
4630d26086SRoman Lebedev     return 0;
47ca1aaaccSRoman Lebedev   if (0U >= a)
48ca1aaaccSRoman Lebedev     return 0;
49ca1aaaccSRoman Lebedev   if (a > 0U)
5030d26086SRoman Lebedev     return 0;
5105e46484SHal Finkel   if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
5230d26086SRoman Lebedev     return 0;
53ca1aaaccSRoman Lebedev   if (a <= 0U)
54ca1aaaccSRoman Lebedev     return 0;
5505e46484SHal Finkel   if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
5630d26086SRoman Lebedev     return 0;
5705e46484SHal Finkel   if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
58ca1aaaccSRoman Lebedev     return 0;
59ca1aaaccSRoman Lebedev   if (0U < a)
60ca1aaaccSRoman Lebedev     return 0;
6130d26086SRoman Lebedev 
6205e46484SHal Finkel   if (b < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
6330d26086SRoman Lebedev     return 0;
64ca1aaaccSRoman Lebedev   if (0 >= b)
65ca1aaaccSRoman Lebedev     return 0;
66ca1aaaccSRoman Lebedev   if (b > 0)
6730d26086SRoman Lebedev     return 0;
6805e46484SHal Finkel   if (0 <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
6930d26086SRoman Lebedev     return 0;
70ca1aaaccSRoman Lebedev   if (b <= 0)
71ca1aaaccSRoman Lebedev     return 0;
7205e46484SHal Finkel   if (0 > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
7330d26086SRoman Lebedev     return 0;
7405e46484SHal Finkel   if (b >= 0) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
7530d26086SRoman Lebedev     return 0;
76ca1aaaccSRoman Lebedev   if (0 < b)
7730d26086SRoman Lebedev     return 0;
78ca1aaaccSRoman Lebedev 
7905e46484SHal Finkel   if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
8030d26086SRoman Lebedev     return 0;
81ca1aaaccSRoman Lebedev   if (0U >= b)
82ca1aaaccSRoman Lebedev     return 0;
83ca1aaaccSRoman Lebedev   if (b > 0U)
8430d26086SRoman Lebedev     return 0;
8505e46484SHal Finkel   if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
8630d26086SRoman Lebedev     return 0;
87ca1aaaccSRoman Lebedev   if (b <= 0U)
88ca1aaaccSRoman Lebedev     return 0;
8905e46484SHal Finkel   if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
9030d26086SRoman Lebedev     return 0;
9105e46484SHal Finkel   if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
9230d26086SRoman Lebedev     return 0;
93ca1aaaccSRoman Lebedev   if (0U < b)
9430d26086SRoman Lebedev     return 0;
9530d26086SRoman Lebedev 
9630d26086SRoman Lebedev   if (c < 0)
9730d26086SRoman Lebedev     return 0;
98371e9e8aSRichard Smith   if (0 >= c)
99ca1aaaccSRoman Lebedev     return 0;
100371e9e8aSRichard Smith   if (c > 0)
10130d26086SRoman Lebedev     return 0;
10230d26086SRoman Lebedev   if (0 <= c)
10330d26086SRoman Lebedev     return 0;
104371e9e8aSRichard Smith   if (c <= 0)
105ca1aaaccSRoman Lebedev     return 0;
10630d26086SRoman Lebedev   if (0 > c)
10730d26086SRoman Lebedev     return 0;
108ca1aaaccSRoman Lebedev   if (c >= 0)
109ca1aaaccSRoman Lebedev     return 0;
110371e9e8aSRichard Smith   if (0 < c)
111ca1aaaccSRoman Lebedev     return 0;
112ca1aaaccSRoman Lebedev 
113371e9e8aSRichard Smith   // FIXME: These diagnostics are terrible. The issue here is that the signed
114371e9e8aSRichard Smith   // enumeration value was promoted to an unsigned type.
11505e46484SHal Finkel   if (c < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
116ca1aaaccSRoman Lebedev     return 0;
117ca1aaaccSRoman Lebedev   if (0U >= c)
118ca1aaaccSRoman Lebedev     return 0;
119ca1aaaccSRoman Lebedev   if (c > 0U)
120ca1aaaccSRoman Lebedev     return 0;
12105e46484SHal Finkel   if (0U <= c) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
122ca1aaaccSRoman Lebedev     return 0;
123ca1aaaccSRoman Lebedev   if (c <= 0U)
124ca1aaaccSRoman Lebedev     return 0;
12505e46484SHal Finkel   if (0U > c) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
126ca1aaaccSRoman Lebedev     return 0;
12705e46484SHal Finkel   if (c >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
128ca1aaaccSRoman Lebedev     return 0;
129ca1aaaccSRoman Lebedev   if (0U < c)
130ca1aaaccSRoman Lebedev     return 0;
13130d26086SRoman Lebedev 
13230d26086SRoman Lebedev   return 1;
13330d26086SRoman Lebedev }
134ca1aaaccSRoman Lebedev 
135ca1aaaccSRoman Lebedev namespace crash_enum_zero_width {
test()136ca1aaaccSRoman Lebedev int test() {
137ca1aaaccSRoman Lebedev   enum A : unsigned {
138ca1aaaccSRoman Lebedev     A_foo = 0
139ca1aaaccSRoman Lebedev   };
140ca1aaaccSRoman Lebedev   enum A a;
141ca1aaaccSRoman Lebedev 
142ca1aaaccSRoman Lebedev   // used to crash in llvm::APSInt::getMaxValue()
14305e46484SHal Finkel   if (a < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
144ca1aaaccSRoman Lebedev     return 0;
145ca1aaaccSRoman Lebedev 
146ca1aaaccSRoman Lebedev   return 1;
147ca1aaaccSRoman Lebedev }
148ca1aaaccSRoman Lebedev } // namespace crash_enum_zero_width
149