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
main()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 {
test()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