Skip to content

Commit ca1aaac

Browse files
committedOct 21, 2017
[Sema] Fixes for enum handling for tautological comparison diagnostics
Summary: As Mattias Eriksson has reported in PR35009, in C, for enums, the underlying type should be used when checking for the tautological comparison, unlike C++, where the enumerator values define the value range. So if not in CPlusPlus mode, use the enum underlying type. Also, i have discovered a problem (a crash) when evaluating tautological-ness of the following comparison: ``` enum A { A_a = 0 }; if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}} return 0; ``` This affects both the C and C++, but after the first fix, only C++ code was affected. That was also fixed, while preserving (i think?) the proper diagnostic output. And while there, attempt to enhance the test coverage. Yes, some tests got moved around, sorry about that :) Fixes PR35009 Reviewers: aaron.ballman, rsmith, rjmccall Reviewed By: aaron.ballman Subscribers: Rakete1111, efriedma, materi, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D39122 llvm-svn: 316268
1 parent f45629d commit ca1aaac

5 files changed

+1232
-58
lines changed
 

‎clang/lib/Sema/SemaChecking.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8181,8 +8181,12 @@ struct IntRange {
81818181
if (const AtomicType *AT = dyn_cast<AtomicType>(T))
81828182
T = AT->getValueType().getTypePtr();
81838183

8184-
// For enum types, use the known bit width of the enumerators.
8185-
if (const EnumType *ET = dyn_cast<EnumType>(T)) {
8184+
if (!C.getLangOpts().CPlusPlus) {
8185+
// For enum types in C code, use the underlying datatype.
8186+
if (const EnumType *ET = dyn_cast<EnumType>(T))
8187+
T = ET->getDecl()->getIntegerType().getDesugaredType(C).getTypePtr();
8188+
} else if (const EnumType *ET = dyn_cast<EnumType>(T)) {
8189+
// For enum types in C++, use the known bit width of the enumerators.
81868190
EnumDecl *Enum = ET->getDecl();
81878191
// In C++11, enums without definitions can have an explicitly specified
81888192
// underlying type. Use this type to compute the range.
@@ -8584,8 +8588,10 @@ bool isNonBooleanUnsignedValue(Expr *E) {
85848588
}
85858589

85868590
enum class LimitType {
8587-
Max, // e.g. 32767 for short
8588-
Min // e.g. -32768 for short
8591+
Max = 1U << 0U, // e.g. 32767 for short
8592+
Min = 1U << 1U, // e.g. -32768 for short
8593+
Both = Max | Min // When the value is both the Min and the Max limit at the
8594+
// same time; e.g. in C++, A::a in enum A { a = 0 };
85898595
};
85908596

85918597
/// Checks whether Expr 'Constant' may be the
@@ -8608,6 +8614,10 @@ llvm::Optional<LimitType> IsTypeLimit(Sema &S, Expr *Constant, Expr *Other,
86088614

86098615
IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT);
86108616

8617+
// Special-case for C++ for enum with one enumerator with value of 0.
8618+
if (OtherRange.Width == 0)
8619+
return Value == 0 ? LimitType::Both : llvm::Optional<LimitType>();
8620+
86118621
if (llvm::APSInt::isSameValue(
86128622
llvm::APSInt::getMaxValue(OtherRange.Width,
86138623
OtherT->isUnsignedIntegerType()),
@@ -8620,7 +8630,7 @@ llvm::Optional<LimitType> IsTypeLimit(Sema &S, Expr *Constant, Expr *Other,
86208630
Value))
86218631
return LimitType::Min;
86228632

8623-
return llvm::Optional<LimitType>();
8633+
return llvm::None;
86248634
}
86258635

86268636
bool HasEnumType(Expr *E) {
@@ -8655,9 +8665,12 @@ bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant,
86558665

86568666
bool ConstIsLowerBound = (Op == BO_LT || Op == BO_LE) ^ RhsConstant;
86578667
bool ResultWhenConstEqualsOther = (Op == BO_LE || Op == BO_GE);
8658-
bool ResultWhenConstNeOther =
8659-
ConstIsLowerBound ^ (ValueType == LimitType::Max);
8660-
if (ResultWhenConstEqualsOther != ResultWhenConstNeOther)
8668+
if (ValueType != LimitType::Both) {
8669+
bool ResultWhenConstNeOther =
8670+
ConstIsLowerBound ^ (ValueType == LimitType::Max);
8671+
if (ResultWhenConstEqualsOther != ResultWhenConstNeOther)
8672+
return false; // The comparison is not tautological.
8673+
} else if (ResultWhenConstEqualsOther == ConstIsLowerBound)
86618674
return false; // The comparison is not tautological.
86628675

86638676
const bool Result = ResultWhenConstEqualsOther;
Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
3+
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s
4+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-out-of-range-compare -verify %s
5+
6+
int main() {
7+
enum A { A_a = 2 };
8+
enum A a;
9+
10+
#ifdef SILENCE
11+
// expected-no-diagnostics
12+
#endif
13+
14+
#ifdef UNSIGNED
15+
#ifndef SILENCE
16+
if (a < 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
17+
return 0;
18+
if (4294967296 >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
19+
return 0;
20+
if (a > 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
21+
return 0;
22+
if (4294967296 <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
23+
return 0;
24+
if (a <= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
25+
return 0;
26+
if (4294967296 > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
27+
return 0;
28+
if (a >= 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
29+
return 0;
30+
if (4294967296 < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
31+
return 0;
32+
if (a == 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
33+
return 0;
34+
if (4294967296 != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
35+
return 0;
36+
if (a != 4294967296) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
37+
return 0;
38+
if (4294967296 == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
39+
return 0;
40+
41+
if (a < 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
42+
return 0;
43+
if (4294967296U >= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
44+
return 0;
45+
if (a > 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
46+
return 0;
47+
if (4294967296U <= a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
48+
return 0;
49+
if (a <= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
50+
return 0;
51+
if (4294967296U > a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
52+
return 0;
53+
if (a >= 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
54+
return 0;
55+
if (4294967296U < a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
56+
return 0;
57+
if (a == 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
58+
return 0;
59+
if (4294967296U != a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
60+
return 0;
61+
if (a != 4294967296U) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always true}}
62+
return 0;
63+
if (4294967296U == a) // expected-warning {{comparison of constant 4294967296 with expression of type 'enum A' is always false}}
64+
return 0;
65+
#else // SILENCE
66+
if (a < 4294967296)
67+
return 0;
68+
if (4294967296 >= a)
69+
return 0;
70+
if (a > 4294967296)
71+
return 0;
72+
if (4294967296 <= a)
73+
return 0;
74+
if (a <= 4294967296)
75+
return 0;
76+
if (4294967296 > a)
77+
return 0;
78+
if (a >= 4294967296)
79+
return 0;
80+
if (4294967296 < a)
81+
return 0;
82+
if (a == 4294967296)
83+
return 0;
84+
if (4294967296 != a)
85+
return 0;
86+
if (a != 4294967296)
87+
return 0;
88+
if (4294967296 == a)
89+
return 0;
90+
91+
if (a < 4294967296U)
92+
return 0;
93+
if (4294967296U >= a)
94+
return 0;
95+
if (a > 4294967296U)
96+
return 0;
97+
if (4294967296U <= a)
98+
return 0;
99+
if (a <= 4294967296U)
100+
return 0;
101+
if (4294967296U > a)
102+
return 0;
103+
if (a >= 4294967296U)
104+
return 0;
105+
if (4294967296U < a)
106+
return 0;
107+
if (a == 4294967296U)
108+
return 0;
109+
if (4294967296U != a)
110+
return 0;
111+
if (a != 4294967296U)
112+
return 0;
113+
if (4294967296U == a)
114+
return 0;
115+
#endif
116+
#elif defined(SIGNED)
117+
#ifndef SILENCE
118+
if (a < -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
119+
return 0;
120+
if (-2147483649 >= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
121+
return 0;
122+
if (a > -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
123+
return 0;
124+
if (-2147483649 <= a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
125+
return 0;
126+
if (a <= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
127+
return 0;
128+
if (-2147483649 > a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
129+
return 0;
130+
if (a >= -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
131+
return 0;
132+
if (-2147483649 < a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
133+
return 0;
134+
if (a == -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
135+
return 0;
136+
if (-2147483649 != a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
137+
return 0;
138+
if (a != -2147483649) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always true}}
139+
return 0;
140+
if (-2147483649 == a) // expected-warning {{comparison of constant -2147483649 with expression of type 'enum A' is always false}}
141+
return 0;
142+
143+
if (a < 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
144+
return 0;
145+
if (2147483648 >= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
146+
return 0;
147+
if (a > 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
148+
return 0;
149+
if (2147483648 <= a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
150+
return 0;
151+
if (a <= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
152+
return 0;
153+
if (2147483648 > a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
154+
return 0;
155+
if (a >= 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
156+
return 0;
157+
if (2147483648 < a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
158+
return 0;
159+
if (a == 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
160+
return 0;
161+
if (2147483648 != a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
162+
return 0;
163+
if (a != 2147483648) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always true}}
164+
return 0;
165+
if (2147483648 == a) // expected-warning {{comparison of constant 2147483648 with expression of type 'enum A' is always false}}
166+
return 0;
167+
#else // SILENCE
168+
if (a < -2147483649)
169+
return 0;
170+
if (-2147483649 >= a)
171+
return 0;
172+
if (a > -2147483649)
173+
return 0;
174+
if (-2147483649 <= a)
175+
return 0;
176+
if (a <= -2147483649)
177+
return 0;
178+
if (-2147483649 > a)
179+
return 0;
180+
if (a >= -2147483649)
181+
return 0;
182+
if (-2147483649 < a)
183+
return 0;
184+
if (a == -2147483649)
185+
return 0;
186+
if (-2147483649 != a)
187+
return 0;
188+
if (a != -2147483649)
189+
return 0;
190+
if (-2147483649 == a)
191+
return 0;
192+
193+
if (a < 2147483648)
194+
return 0;
195+
if (2147483648 >= a)
196+
return 0;
197+
if (a > 2147483648)
198+
return 0;
199+
if (2147483648 <= a)
200+
return 0;
201+
if (a <= 2147483648)
202+
return 0;
203+
if (2147483648 > a)
204+
return 0;
205+
if (a >= 2147483648)
206+
return 0;
207+
if (2147483648 < a)
208+
return 0;
209+
if (a == 2147483648)
210+
return 0;
211+
if (2147483648 != a)
212+
return 0;
213+
if (a != 2147483648)
214+
return 0;
215+
if (2147483648 == a)
216+
return 0;
217+
#endif
218+
#endif
219+
}
220+
221+
// https://bugs.llvm.org/show_bug.cgi?id=35009
222+
int PR35009() {
223+
enum A { A_a = 2 };
224+
enum A a;
225+
226+
// in C, this should not warn.
227+
228+
if (a < 1)
229+
return 0;
230+
if (1 >= a)
231+
return 0;
232+
if (a > 1)
233+
return 0;
234+
if (1 <= a)
235+
return 0;
236+
if (a <= 1)
237+
return 0;
238+
if (1 > a)
239+
return 0;
240+
if (a >= 1)
241+
return 0;
242+
if (1 < a)
243+
return 0;
244+
if (a == 1)
245+
return 0;
246+
if (1 != a)
247+
return 0;
248+
if (a != 1)
249+
return 0;
250+
if (1 == a)
251+
return 0;
252+
253+
if (a < 1U)
254+
return 0;
255+
if (1U >= a)
256+
return 0;
257+
if (a > 1U)
258+
return 0;
259+
if (1U <= a)
260+
return 0;
261+
if (a <= 1U)
262+
return 0;
263+
if (1U > a)
264+
return 0;
265+
if (a >= 1U)
266+
return 0;
267+
if (1U < a)
268+
return 0;
269+
if (a == 1U)
270+
return 0;
271+
if (1U != a)
272+
return 0;
273+
if (a != 1U)
274+
return 0;
275+
if (1U == a)
276+
return 0;
277+
278+
if (a < 2)
279+
return 0;
280+
if (2 >= a)
281+
return 0;
282+
if (a > 2)
283+
return 0;
284+
if (2 <= a)
285+
return 0;
286+
if (a <= 2)
287+
return 0;
288+
if (2 > a)
289+
return 0;
290+
if (a >= 2)
291+
return 0;
292+
if (2 < a)
293+
return 0;
294+
if (a == 2)
295+
return 0;
296+
if (2 != a)
297+
return 0;
298+
if (a != 2)
299+
return 0;
300+
if (2 == a)
301+
return 0;
302+
303+
if (a < 2U)
304+
return 0;
305+
if (2U >= a)
306+
return 0;
307+
if (a > 2U)
308+
return 0;
309+
if (2U <= a)
310+
return 0;
311+
if (a <= 2U)
312+
return 0;
313+
if (2U > a)
314+
return 0;
315+
if (a >= 2U)
316+
return 0;
317+
if (2U < a)
318+
return 0;
319+
if (a == 2U)
320+
return 0;
321+
if (2U != a)
322+
return 0;
323+
if (a != 2U)
324+
return 0;
325+
if (2U == a)
326+
return 0;
327+
328+
if (a < 3)
329+
return 0;
330+
if (3 >= a)
331+
return 0;
332+
if (a > 3)
333+
return 0;
334+
if (3 <= a)
335+
return 0;
336+
if (a <= 3)
337+
return 0;
338+
if (3 > a)
339+
return 0;
340+
if (a >= 3)
341+
return 0;
342+
if (3 < a)
343+
return 0;
344+
if (a == 3)
345+
return 0;
346+
if (3 != a)
347+
return 0;
348+
if (a != 3)
349+
return 0;
350+
if (3 == a)
351+
return 0;
352+
353+
if (a < 3U)
354+
return 0;
355+
if (3U >= a)
356+
return 0;
357+
if (a > 3U)
358+
return 0;
359+
if (3U <= a)
360+
return 0;
361+
if (a <= 3U)
362+
return 0;
363+
if (3U > a)
364+
return 0;
365+
if (a >= 3U)
366+
return 0;
367+
if (3U < a)
368+
return 0;
369+
if (a == 3U)
370+
return 0;
371+
if (3U != a)
372+
return 0;
373+
if (a != 3U)
374+
return 0;
375+
if (3U == a)
376+
return 0;
377+
378+
return 1;
379+
}
Lines changed: 419 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,419 @@
1+
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
3+
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
4+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
5+
6+
int main() {
7+
enum A { A_a = 2 };
8+
enum A a;
9+
10+
#ifdef SILENCE
11+
// expected-no-diagnostics
12+
#endif
13+
14+
#ifdef UNSIGNED
15+
#ifndef SILENCE
16+
if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
17+
return 0;
18+
if (0 >= a)
19+
return 0;
20+
if (a > 0)
21+
return 0;
22+
if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
23+
return 0;
24+
if (a <= 0)
25+
return 0;
26+
if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
27+
return 0;
28+
if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
29+
return 0;
30+
if (0 < a)
31+
return 0;
32+
33+
if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
34+
return 0;
35+
if (0U >= a)
36+
return 0;
37+
if (a > 0U)
38+
return 0;
39+
if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
40+
return 0;
41+
if (a <= 0U)
42+
return 0;
43+
if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
44+
return 0;
45+
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
46+
return 0;
47+
if (0U < a)
48+
return 0;
49+
50+
if (a < 4294967295)
51+
return 0;
52+
if (4294967295 >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}}
53+
return 0;
54+
if (a > 4294967295) // expected-warning {{comparison 'enum A' > 4294967295 is always false}}
55+
return 0;
56+
if (4294967295 <= a)
57+
return 0;
58+
if (a <= 4294967295) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}}
59+
return 0;
60+
if (4294967295 > a)
61+
return 0;
62+
if (a >= 4294967295)
63+
return 0;
64+
if (4294967295 < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}}
65+
return 0;
66+
67+
if (a < 4294967295U)
68+
return 0;
69+
if (4294967295U >= a) // expected-warning {{comparison 4294967295 >= 'enum A' is always true}}
70+
return 0;
71+
if (a > 4294967295U) // expected-warning {{comparison 'enum A' > 4294967295 is always false}}
72+
return 0;
73+
if (4294967295U <= a)
74+
return 0;
75+
if (a <= 4294967295U) // expected-warning {{comparison 'enum A' <= 4294967295 is always true}}
76+
return 0;
77+
if (4294967295U > a)
78+
return 0;
79+
if (a >= 4294967295U)
80+
return 0;
81+
if (4294967295U < a) // expected-warning {{comparison 4294967295 < 'enum A' is always false}}
82+
return 0;
83+
#else // SILENCE
84+
if (a < 0)
85+
return 0;
86+
if (0 >= a)
87+
return 0;
88+
if (a > 0)
89+
return 0;
90+
if (0 <= a)
91+
return 0;
92+
if (a <= 0)
93+
return 0;
94+
if (0 > a)
95+
return 0;
96+
if (a >= 0)
97+
return 0;
98+
if (0 < a)
99+
return 0;
100+
101+
if (a < 0U)
102+
return 0;
103+
if (0U >= a)
104+
return 0;
105+
if (a > 0U)
106+
return 0;
107+
if (0U <= a)
108+
return 0;
109+
if (a <= 0U)
110+
return 0;
111+
if (0U > a)
112+
return 0;
113+
if (a >= 0U)
114+
return 0;
115+
if (0U < a)
116+
return 0;
117+
118+
if (a < 4294967295)
119+
return 0;
120+
if (4294967295 >= a)
121+
return 0;
122+
if (a > 4294967295)
123+
return 0;
124+
if (4294967295 <= a)
125+
return 0;
126+
if (a <= 4294967295)
127+
return 0;
128+
if (4294967295 > a)
129+
return 0;
130+
if (a >= 4294967295)
131+
return 0;
132+
if (4294967295 < a)
133+
return 0;
134+
135+
if (a < 4294967295U)
136+
return 0;
137+
if (4294967295U >= a)
138+
return 0;
139+
if (a > 4294967295U)
140+
return 0;
141+
if (4294967295U <= a)
142+
return 0;
143+
if (a <= 4294967295U)
144+
return 0;
145+
if (4294967295U > a)
146+
return 0;
147+
if (a >= 4294967295U)
148+
return 0;
149+
if (4294967295U < a)
150+
return 0;
151+
#endif
152+
#elif defined(SIGNED)
153+
#ifndef SILENCE
154+
if (a < -2147483648) // expected-warning {{comparison 'enum A' < -2147483648 is always false}}
155+
return 0;
156+
if (-2147483648 >= a)
157+
return 0;
158+
if (a > -2147483648)
159+
return 0;
160+
if (-2147483648 <= a) // expected-warning {{comparison -2147483648 <= 'enum A' is always true}}
161+
return 0;
162+
if (a <= -2147483648)
163+
return 0;
164+
if (-2147483648 > a) // expected-warning {{comparison -2147483648 > 'enum A' is always false}}
165+
return 0;
166+
if (a >= -2147483648) // expected-warning {{comparison 'enum A' >= -2147483648 is always true}}
167+
return 0;
168+
if (-2147483648 < a)
169+
return 0;
170+
171+
if (a < 2147483647)
172+
return 0;
173+
if (2147483647 >= a) // expected-warning {{comparison 2147483647 >= 'enum A' is always true}}
174+
return 0;
175+
if (a > 2147483647) // expected-warning {{comparison 'enum A' > 2147483647 is always false}}
176+
return 0;
177+
if (2147483647 <= a)
178+
return 0;
179+
if (a <= 2147483647) // expected-warning {{comparison 'enum A' <= 2147483647 is always true}}
180+
return 0;
181+
if (2147483647 > a)
182+
return 0;
183+
if (a >= 2147483647)
184+
return 0;
185+
if (2147483647 < a) // expected-warning {{comparison 2147483647 < 'enum A' is always false}}
186+
return 0;
187+
188+
if (a < 2147483647U)
189+
return 0;
190+
if (2147483647U >= a) // expected-warning {{comparison 2147483647 >= 'enum A' is always true}}
191+
return 0;
192+
if (a > 2147483647U) // expected-warning {{comparison 'enum A' > 2147483647 is always false}}
193+
return 0;
194+
if (2147483647U <= a)
195+
return 0;
196+
if (a <= 2147483647U) // expected-warning {{comparison 'enum A' <= 2147483647 is always true}}
197+
return 0;
198+
if (2147483647U > a)
199+
return 0;
200+
if (a >= 2147483647U)
201+
return 0;
202+
if (2147483647U < a) // expected-warning {{comparison 2147483647 < 'enum A' is always false}}
203+
return 0;
204+
#else // SILENCE
205+
if (a < -2147483648)
206+
return 0;
207+
if (-2147483648 >= a)
208+
return 0;
209+
if (a > -2147483648)
210+
return 0;
211+
if (-2147483648 <= a)
212+
return 0;
213+
if (a <= -2147483648)
214+
return 0;
215+
if (-2147483648 > a)
216+
return 0;
217+
if (a >= -2147483648)
218+
return 0;
219+
if (-2147483648 < a)
220+
return 0;
221+
222+
if (a < 2147483647)
223+
return 0;
224+
if (2147483647 >= a)
225+
return 0;
226+
if (a > 2147483647)
227+
return 0;
228+
if (2147483647 <= a)
229+
return 0;
230+
if (a <= 2147483647)
231+
return 0;
232+
if (2147483647 > a)
233+
return 0;
234+
if (a >= 2147483647)
235+
return 0;
236+
if (2147483647 < a)
237+
return 0;
238+
239+
if (a < 2147483647U)
240+
return 0;
241+
if (2147483647U >= a)
242+
return 0;
243+
if (a > 2147483647U)
244+
return 0;
245+
if (2147483647U <= a)
246+
return 0;
247+
if (a <= 2147483647U)
248+
return 0;
249+
if (2147483647U > a)
250+
return 0;
251+
if (a >= 2147483647U)
252+
return 0;
253+
if (2147483647U < a)
254+
return 0;
255+
#endif
256+
#endif
257+
258+
return 1;
259+
}
260+
261+
// https://bugs.llvm.org/show_bug.cgi?id=35009
262+
int PR35009() {
263+
enum A { A_a = 2 };
264+
enum A a;
265+
266+
// in C, this should not warn.
267+
268+
if (a < 1)
269+
return 0;
270+
if (1 >= a)
271+
return 0;
272+
if (a > 1)
273+
return 0;
274+
if (1 <= a)
275+
return 0;
276+
if (a <= 1)
277+
return 0;
278+
if (1 > a)
279+
return 0;
280+
if (a >= 1)
281+
return 0;
282+
if (1 < a)
283+
return 0;
284+
if (a == 1)
285+
return 0;
286+
if (1 != a)
287+
return 0;
288+
if (a != 1)
289+
return 0;
290+
if (1 == a)
291+
return 0;
292+
293+
if (a < 1U)
294+
return 0;
295+
if (1U >= a)
296+
return 0;
297+
if (a > 1U)
298+
return 0;
299+
if (1U <= a)
300+
return 0;
301+
if (a <= 1U)
302+
return 0;
303+
if (1U > a)
304+
return 0;
305+
if (a >= 1U)
306+
return 0;
307+
if (1U < a)
308+
return 0;
309+
if (a == 1U)
310+
return 0;
311+
if (1U != a)
312+
return 0;
313+
if (a != 1U)
314+
return 0;
315+
if (1U == a)
316+
return 0;
317+
318+
if (a < 2)
319+
return 0;
320+
if (2 >= a)
321+
return 0;
322+
if (a > 2)
323+
return 0;
324+
if (2 <= a)
325+
return 0;
326+
if (a <= 2)
327+
return 0;
328+
if (2 > a)
329+
return 0;
330+
if (a >= 2)
331+
return 0;
332+
if (2 < a)
333+
return 0;
334+
if (a == 2)
335+
return 0;
336+
if (2 != a)
337+
return 0;
338+
if (a != 2)
339+
return 0;
340+
if (2 == a)
341+
return 0;
342+
343+
if (a < 2U)
344+
return 0;
345+
if (2U >= a)
346+
return 0;
347+
if (a > 2U)
348+
return 0;
349+
if (2U <= a)
350+
return 0;
351+
if (a <= 2U)
352+
return 0;
353+
if (2U > a)
354+
return 0;
355+
if (a >= 2U)
356+
return 0;
357+
if (2U < a)
358+
return 0;
359+
if (a == 2U)
360+
return 0;
361+
if (2U != a)
362+
return 0;
363+
if (a != 2U)
364+
return 0;
365+
if (2U == a)
366+
return 0;
367+
368+
if (a < 3)
369+
return 0;
370+
if (3 >= a)
371+
return 0;
372+
if (a > 3)
373+
return 0;
374+
if (3 <= a)
375+
return 0;
376+
if (a <= 3)
377+
return 0;
378+
if (3 > a)
379+
return 0;
380+
if (a >= 3)
381+
return 0;
382+
if (3 < a)
383+
return 0;
384+
if (a == 3)
385+
return 0;
386+
if (3 != a)
387+
return 0;
388+
if (a != 3)
389+
return 0;
390+
if (3 == a)
391+
return 0;
392+
393+
if (a < 3U)
394+
return 0;
395+
if (3U >= a)
396+
return 0;
397+
if (a > 3U)
398+
return 0;
399+
if (3U <= a)
400+
return 0;
401+
if (a <= 3U)
402+
return 0;
403+
if (3U > a)
404+
return 0;
405+
if (a >= 3U)
406+
return 0;
407+
if (3U < a)
408+
return 0;
409+
if (a == 3U)
410+
return 0;
411+
if (3U != a)
412+
return 0;
413+
if (a != 3U)
414+
return 0;
415+
if (3U == a)
416+
return 0;
417+
418+
return 1;
419+
}
Lines changed: 206 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,260 @@
1-
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DALL_WARN -verify %s
2-
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGN_WARN -verify %s
1+
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -verify %s
2+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -verify %s
33
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -Wno-tautological-unsigned-enum-zero-compare -verify %s
44

55
// Okay, this is where it gets complicated.
66
// Then default enum sigdness is target-specific.
77
// On windows, it is signed by default. We do not want to warn in that case.
88

99
int main() {
10-
enum A { A_foo, A_bar };
10+
enum A { A_a = 0 };
1111
enum A a;
12+
enum B { B_a = -1 };
13+
enum B b;
1214

13-
#ifdef ALL_WARN
15+
#ifdef UNSIGNED
1416
if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
1517
return 0;
16-
if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
18+
if (0 >= a)
19+
return 0;
20+
if (a > 0)
1721
return 0;
1822
if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
1923
return 0;
24+
if (a <= 0)
25+
return 0;
2026
if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
2127
return 0;
28+
if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
29+
return 0;
30+
if (0 < a)
31+
return 0;
32+
2233
if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
2334
return 0;
24-
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
35+
if (0U >= a)
36+
return 0;
37+
if (a > 0U)
2538
return 0;
2639
if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
2740
return 0;
41+
if (a <= 0U)
42+
return 0;
2843
if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
2944
return 0;
30-
#elif defined(SIGN_WARN)
31-
if (a < 0) // ok
45+
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
46+
return 0;
47+
if (0U < a)
48+
return 0;
49+
50+
if (b < 0)
51+
return 0;
52+
if (0 >= b)
53+
return 0;
54+
if (b > 0)
55+
return 0;
56+
if (0 <= b)
57+
return 0;
58+
if (b <= 0)
59+
return 0;
60+
if (0 > b)
61+
return 0;
62+
if (b >= 0)
63+
return 0;
64+
if (0 < b)
65+
return 0;
66+
67+
if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
68+
return 0;
69+
if (0U >= b)
70+
return 0;
71+
if (b > 0U)
72+
return 0;
73+
if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
74+
return 0;
75+
if (b <= 0U)
76+
return 0;
77+
if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
78+
return 0;
79+
if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
3280
return 0;
33-
if (a >= 0) // ok
81+
if (0U < b)
3482
return 0;
35-
if (0 <= a) // ok
83+
#elif defined(SIGNED)
84+
if (a < 0)
85+
return 0;
86+
if (0 >= a)
87+
return 0;
88+
if (a > 0)
89+
return 0;
90+
if (0 <= a)
91+
return 0;
92+
if (a <= 0)
3693
return 0;
37-
if (0 > a) // ok
94+
if (0 > a)
3895
return 0;
96+
if (a >= 0)
97+
return 0;
98+
if (0 < a)
99+
return 0;
100+
39101
if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
40102
return 0;
41-
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
103+
if (0U >= a)
104+
return 0;
105+
if (a > 0U)
42106
return 0;
43107
if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
44108
return 0;
109+
if (a <= 0U)
110+
return 0;
45111
if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
46112
return 0;
113+
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
114+
return 0;
115+
if (0U < a)
116+
return 0;
117+
118+
if (b < 0)
119+
return 0;
120+
if (0 >= b)
121+
return 0;
122+
if (b > 0)
123+
return 0;
124+
if (0 <= b)
125+
return 0;
126+
if (b <= 0)
127+
return 0;
128+
if (0 > b)
129+
return 0;
130+
if (b >= 0)
131+
return 0;
132+
if (0 < b)
133+
return 0;
134+
135+
if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
136+
return 0;
137+
if (0U >= b)
138+
return 0;
139+
if (b > 0U)
140+
return 0;
141+
if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
142+
return 0;
143+
if (b <= 0U)
144+
return 0;
145+
if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
146+
return 0;
147+
if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
148+
return 0;
149+
if (0U < b)
150+
return 0;
47151
#else
48152
// expected-no-diagnostics
153+
49154
if (a < 0)
50155
return 0;
51-
if (a >= 0)
156+
if (0 >= a)
157+
return 0;
158+
if (a > 0)
52159
return 0;
53160
if (0 <= a)
54161
return 0;
162+
if (a <= 0)
163+
return 0;
55164
if (0 > a)
56165
return 0;
166+
if (a >= 0)
167+
return 0;
168+
if (0 < a)
169+
return 0;
170+
57171
if (a < 0U)
58172
return 0;
59-
if (a >= 0U)
173+
if (0U >= a)
174+
return 0;
175+
if (a > 0U)
60176
return 0;
61177
if (0U <= a)
62178
return 0;
179+
if (a <= 0U)
180+
return 0;
63181
if (0U > a)
64182
return 0;
183+
if (a >= 0U)
184+
return 0;
185+
if (0U < a)
186+
return 0;
187+
188+
if (b < 0)
189+
return 0;
190+
if (0 >= b)
191+
return 0;
192+
if (b > 0)
193+
return 0;
194+
if (0 <= b)
195+
return 0;
196+
if (b <= 0)
197+
return 0;
198+
if (0 > b)
199+
return 0;
200+
if (b >= 0)
201+
return 0;
202+
if (0 < b)
203+
return 0;
204+
205+
if (b < 0U)
206+
return 0;
207+
if (0U >= b)
208+
return 0;
209+
if (b > 0U)
210+
return 0;
211+
if (0U <= b)
212+
return 0;
213+
if (b <= 0U)
214+
return 0;
215+
if (0U > b)
216+
return 0;
217+
if (b >= 0U)
218+
return 0;
219+
if (0U < b)
220+
return 0;
65221
#endif
66222

223+
if (a == 0)
224+
return 0;
225+
if (0 != a)
226+
return 0;
227+
if (a != 0)
228+
return 0;
229+
if (0 == a)
230+
return 0;
231+
232+
if (a == 0U)
233+
return 0;
234+
if (0U != a)
235+
return 0;
236+
if (a != 0U)
237+
return 0;
238+
if (0U == a)
239+
return 0;
240+
241+
if (b == 0)
242+
return 0;
243+
if (0 != b)
244+
return 0;
245+
if (b != 0)
246+
return 0;
247+
if (0 == b)
248+
return 0;
249+
250+
if (b == 0U)
251+
return 0;
252+
if (0U != b)
253+
return 0;
254+
if (b != 0U)
255+
return 0;
256+
if (0U == b)
257+
return 0;
258+
67259
return 1;
68260
}
Lines changed: 207 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,347 @@
1-
// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only -DALL_WARN -verify %s
2-
// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -DSIGN_WARN -verify %s
3-
// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only -Wno-tautological-unsigned-enum-zero-compare -verify %s
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
44

55
// Okay, this is where it gets complicated.
66
// Then default enum sigdness is target-specific.
77
// On windows, it is signed by default. We do not want to warn in that case.
88

99
int main() {
10-
enum A { A_foo, A_bar };
10+
enum A { A_foo = 0, A_bar, };
1111
enum A a;
1212

13-
enum B : unsigned { B_foo, B_bar };
13+
enum B : unsigned { B_foo = 0, B_bar, };
1414
enum B b;
1515

16-
enum C : signed { c_foo, c_bar };
16+
enum C : signed { C_foo = 0, C_bar, };
1717
enum C c;
1818

19-
#ifdef ALL_WARN
19+
#ifdef UNSIGNED
2020
if (a < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
2121
return 0;
22-
if (a >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
22+
if (0 >= a)
23+
return 0;
24+
if (a > 0)
2325
return 0;
2426
if (0 <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
2527
return 0;
28+
if (a <= 0)
29+
return 0;
2630
if (0 > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
2731
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+
2837
if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
2938
return 0;
30-
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
39+
if (0U >= a)
40+
return 0;
41+
if (a > 0U)
3142
return 0;
3243
if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
3344
return 0;
45+
if (a <= 0U)
46+
return 0;
3447
if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
3548
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;
3653

3754
if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
3855
return 0;
39-
if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
56+
if (0 >= b)
57+
return 0;
58+
if (b > 0)
4059
return 0;
4160
if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
4261
return 0;
62+
if (b <= 0)
63+
return 0;
4364
if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
4465
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+
4571
if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
4672
return 0;
47-
if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
73+
if (0U >= b)
74+
return 0;
75+
if (b > 0U)
4876
return 0;
4977
if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
5078
return 0;
79+
if (b <= 0U)
80+
return 0;
5181
if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
5282
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;
5387

54-
if (c < 0) // ok
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}}
5597
return 0;
56-
if (c >= 0) // ok
98+
if (0 > c)
5799
return 0;
58-
if (0 <= c) // ok
100+
if (c >= 0)
59101
return 0;
60-
if (0 > c) // ok
102+
if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
61103
return 0;
104+
62105
if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
63106
return 0;
64-
if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
107+
if (0U >= c)
108+
return 0;
109+
if (c > 0U)
65110
return 0;
66111
if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
67112
return 0;
113+
if (c <= 0U)
114+
return 0;
68115
if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
69116
return 0;
70-
#elif defined(SIGN_WARN)
71-
if (a < 0) // ok
117+
if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
72118
return 0;
73-
if (a >= 0) // ok
119+
if (0U < c)
74120
return 0;
75-
if (0 <= a) // ok
121+
#elif defined(SIGNED)
122+
if (a < 0)
123+
return 0;
124+
if (0 >= a) // expected-warning {{comparison 0 >= 'enum A' is always true}}
76125
return 0;
77-
if (0 > a) // ok
126+
if (a > 0) // expected-warning {{comparison 'enum A' > 0 is always false}}
127+
return 0;
128+
if (0 <= a)
78129
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+
79139
if (a < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
80140
return 0;
81-
if (a >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
141+
if (0U >= a)
142+
return 0;
143+
if (a > 0U)
82144
return 0;
83145
if (0U <= a) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
84146
return 0;
147+
if (a <= 0U)
148+
return 0;
85149
if (0U > a) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
86150
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;
87155

88156
if (b < 0) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
89157
return 0;
90-
if (b >= 0) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
158+
if (0 >= b)
159+
return 0;
160+
if (b > 0)
91161
return 0;
92162
if (0 <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
93163
return 0;
164+
if (b <= 0)
165+
return 0;
94166
if (0 > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
95167
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+
96173
if (b < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
97174
return 0;
98-
if (b >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
175+
if (0U >= b)
176+
return 0;
177+
if (b > 0U)
99178
return 0;
100179
if (0U <= b) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
101180
return 0;
181+
if (b <= 0U)
182+
return 0;
102183
if (0U > b) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
103184
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;
104189

105-
if (c < 0) // ok
190+
if (c < 0)
106191
return 0;
107-
if (c >= 0) // ok
192+
if (0 >= c) // expected-warning {{comparison 0 >= 'enum C' is always true}}
108193
return 0;
109-
if (0 <= c) // ok
194+
if (c > 0) // expected-warning {{comparison 'enum C' > 0 is always false}}
195+
return 0;
196+
if (0 <= c)
110197
return 0;
111-
if (0 > c) // ok
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)
112203
return 0;
204+
if (0 < c) // expected-warning {{0 < 'enum C' is always false}}
205+
return 0;
206+
113207
if (c < 0U) // expected-warning {{comparison of unsigned enum expression < 0 is always false}}
114208
return 0;
115-
if (c >= 0U) // expected-warning {{comparison of unsigned enum expression >= 0 is always true}}
209+
if (0U >= c)
210+
return 0;
211+
if (c > 0U)
116212
return 0;
117213
if (0U <= c) // expected-warning {{comparison of 0 <= unsigned enum expression is always true}}
118214
return 0;
215+
if (c <= 0U)
216+
return 0;
119217
if (0U > c) // expected-warning {{comparison of 0 > unsigned enum expression is always false}}
120218
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;
121223
#else
122-
// expected-no-diagnostics
123224
if (a < 0)
124225
return 0;
125-
if (a >= 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}}
126229
return 0;
127230
if (0 <= a)
128231
return 0;
232+
if (a <= 0) // expected-warning {{comparison 'enum A' <= 0 is always true}}
233+
return 0;
129234
if (0 > a)
130235
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+
131241
if (a < 0U)
132242
return 0;
133-
if (a >= 0U)
243+
if (0U >= a)
244+
return 0;
245+
if (a > 0U)
134246
return 0;
135247
if (0U <= a)
136248
return 0;
249+
if (a <= 0U)
250+
return 0;
137251
if (0U > a)
138252
return 0;
253+
if (a >= 0U)
254+
return 0;
255+
if (0U < a)
256+
return 0;
139257

140258
if (b < 0)
141259
return 0;
142-
if (b >= 0)
260+
if (0 >= b)
261+
return 0;
262+
if (b > 0)
143263
return 0;
144264
if (0 <= b)
145265
return 0;
266+
if (b <= 0)
267+
return 0;
146268
if (0 > b)
147269
return 0;
270+
if (b >= 0)
271+
return 0;
272+
if (0 < b)
273+
return 0;
274+
148275
if (b < 0U)
149276
return 0;
150-
if (b >= 0U)
277+
if (0U >= b)
278+
return 0;
279+
if (b > 0U)
151280
return 0;
152281
if (0U <= b)
153282
return 0;
283+
if (b <= 0U)
284+
return 0;
154285
if (0U > b)
155286
return 0;
287+
if (b >= 0U)
288+
return 0;
289+
if (0U < b)
290+
return 0;
156291

157292
if (c < 0)
158293
return 0;
159-
if (c >= 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}}
160297
return 0;
161298
if (0 <= c)
162299
return 0;
300+
if (c <= 0) // expected-warning {{comparison 'enum C' <= 0 is always true}}
301+
return 0;
163302
if (0 > c)
164303
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+
165309
if (c < 0U)
166310
return 0;
167-
if (c >= 0U)
311+
if (0U >= c)
312+
return 0;
313+
if (c > 0U)
168314
return 0;
169315
if (0U <= c)
170316
return 0;
317+
if (c <= 0U)
318+
return 0;
171319
if (0U > c)
172320
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)
173342
#endif
343+
return 0;
174344

175345
return 1;
176346
}
347+
} // namespace crash_enum_zero_width

0 commit comments

Comments
 (0)
Please sign in to comment.