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 // Okay, this is where it gets complicated.
6 // Then default enum sigdness is target-specific.
7 // On windows, it is signed by default. We do not want to warn in that case.
8 
9 int main() {
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) // expected-warning {{comparison 0 >= 'enum C' is always true}}
91     return 0;
92   if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
93     return 0;
94   if (0 <= c)
95     return 0;
96   if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
97     return 0;
98   if (0 > c)
99     return 0;
100   if (c >= 0)
101     return 0;
102   if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
103     return 0;
104 
105   if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
106     return 0;
107   if (0U >= c)
108     return 0;
109   if (c > 0U)
110     return 0;
111   if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
112     return 0;
113   if (c <= 0U)
114     return 0;
115   if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
116     return 0;
117   if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
118     return 0;
119   if (0U < c)
120     return 0;
121 #elif defined(SIGNED)
122   if (a < 0)
123     return 0;
124   if (0 >= a) // expected-warning {{comparison 0 >= 'enum A' is always true}}
125     return 0;
126   if (a > 0) // expected-warning {{comparison 'enum A' > 0 is always false}}
127     return 0;
128   if (0 <= a)
129     return 0;
130   if (a <= 0) // expected-warning {{comparison 'enum A' <= 0 is always true}}
131     return 0;
132   if (0 > a)
133     return 0;
134   if (a >= 0)
135     return 0;
136   if (0 < a) // expected-warning {{comparison 0 < 'enum A' is always false}}
137     return 0;
138 
139   if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
140     return 0;
141   if (0U >= a)
142     return 0;
143   if (a > 0U)
144     return 0;
145   if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
146     return 0;
147   if (a <= 0U)
148     return 0;
149   if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
150     return 0;
151   if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
152     return 0;
153   if (0U < a)
154     return 0;
155 
156   if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
157     return 0;
158   if (0 >= b)
159     return 0;
160   if (b > 0)
161     return 0;
162   if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
163     return 0;
164   if (b <= 0)
165     return 0;
166   if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
167     return 0;
168   if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
169     return 0;
170   if (0 < b)
171     return 0;
172 
173   if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
174     return 0;
175   if (0U >= b)
176     return 0;
177   if (b > 0U)
178     return 0;
179   if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
180     return 0;
181   if (b <= 0U)
182     return 0;
183   if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
184     return 0;
185   if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
186     return 0;
187   if (0U < b)
188     return 0;
189 
190   if (c < 0)
191     return 0;
192   if (0 >= c) // expected-warning {{comparison 0 >= 'enum C' is always true}}
193     return 0;
194   if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
195     return 0;
196   if (0 <= c)
197     return 0;
198   if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
199     return 0;
200   if (0 > c)
201     return 0;
202   if (c >= 0)
203     return 0;
204   if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
205     return 0;
206 
207   if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
208     return 0;
209   if (0U >= c)
210     return 0;
211   if (c > 0U)
212     return 0;
213   if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
214     return 0;
215   if (c <= 0U)
216     return 0;
217   if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
218     return 0;
219   if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
220     return 0;
221   if (0U < c)
222     return 0;
223 #else
224   if (a < 0)
225     return 0;
226   if (0 >= a) // expected-warning {{comparison 0 >= 'enum A' is always true}}
227     return 0;
228   if (a > 0) // expected-warning {{comparison 'enum A' > 0 is always false}}
229     return 0;
230   if (0 <= a)
231     return 0;
232   if (a <= 0) // expected-warning {{comparison 'enum A' <= 0 is always true}}
233     return 0;
234   if (0 > a)
235     return 0;
236   if (a >= 0)
237     return 0;
238   if (0 < a) // expected-warning {{comparison 0 < 'enum A' is always false}}
239     return 0;
240 
241   if (a < 0U)
242     return 0;
243   if (0U >= a)
244     return 0;
245   if (a > 0U)
246     return 0;
247   if (0U <= a)
248     return 0;
249   if (a <= 0U)
250     return 0;
251   if (0U > a)
252     return 0;
253   if (a >= 0U)
254     return 0;
255   if (0U < a)
256     return 0;
257 
258   if (b < 0)
259     return 0;
260   if (0 >= b)
261     return 0;
262   if (b > 0)
263     return 0;
264   if (0 <= b)
265     return 0;
266   if (b <= 0)
267     return 0;
268   if (0 > b)
269     return 0;
270   if (b >= 0)
271     return 0;
272   if (0 < b)
273     return 0;
274 
275   if (b < 0U)
276     return 0;
277   if (0U >= b)
278     return 0;
279   if (b > 0U)
280     return 0;
281   if (0U <= b)
282     return 0;
283   if (b <= 0U)
284     return 0;
285   if (0U > b)
286     return 0;
287   if (b >= 0U)
288     return 0;
289   if (0U < b)
290     return 0;
291 
292   if (c < 0)
293     return 0;
294   if (0 >= c) // expected-warning {{comparison 0 >= 'enum C' is always true}}
295     return 0;
296   if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
297     return 0;
298   if (0 <= c)
299     return 0;
300   if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
301     return 0;
302   if (0 > c)
303     return 0;
304   if (c >= 0)
305     return 0;
306   if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
307     return 0;
308 
309   if (c < 0U)
310     return 0;
311   if (0U >= c)
312     return 0;
313   if (c > 0U)
314     return 0;
315   if (0U <= c)
316     return 0;
317   if (c <= 0U)
318     return 0;
319   if (0U > c)
320     return 0;
321   if (c >= 0U)
322     return 0;
323   if (0U < c)
324     return 0;
325 #endif
326 
327   return 1;
328 }
329 
330 namespace crash_enum_zero_width {
331 int test() {
332   enum A : unsigned {
333     A_foo = 0
334   };
335   enum A a;
336 
337   // used to crash in llvm::APSInt::getMaxValue()
338 #ifndef SILENCE
339   if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
340 #else
341   if (a > 0)
342 #endif
343     return 0;
344 
345   return 1;
346 }
347 } // namespace crash_enum_zero_width
348