Clang Project

clang_source_code/test/Sema/tautological-unsigned-enum-zero-compare.cpp
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
12int 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
135namespace crash_enum_zero_width {
136int 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