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