blob: 0b66c68197d9fc6c49a56095af1eb0efdfa55d61 [file] [log] [blame]
Hal Finkel05e46482017-12-16 02:23:22 +00001// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-linux-gnu -fsyntax-only \
Roman Lebedevc5417aa2018-01-03 08:45:19 +00002// RUN: -Wtautological-unsigned-enum-zero-compare \
Hal Finkel05e46482017-12-16 02:23:22 +00003// RUN: -verify=unsigned,unsigned-signed %s
4// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \
Roman Lebedevc5417aa2018-01-03 08:45:19 +00005// RUN: -Wtautological-unsigned-enum-zero-compare \
Hal Finkel05e46482017-12-16 02:23:22 +00006// RUN: -verify=unsigned-signed %s
7// RUN: %clang_cc1 -std=c++11 -triple=x86_64-pc-win32 -fsyntax-only \
Hal Finkel05e46482017-12-16 02:23:22 +00008// RUN: -verify=silence %s
9
10// silence-no-diagnostics
Roman Lebedev30d26082017-09-20 13:50:01 +000011
Roman Lebedev30d26082017-09-20 13:50:01 +000012int main() {
Richard Smith371e9e8a2017-12-06 03:00:51 +000013 // 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.
Roman Lebedevca1aaac2017-10-21 16:44:03 +000017 enum A { A_foo = 0, A_bar, };
Roman Lebedev30d26082017-09-20 13:50:01 +000018 enum A a;
19
Roman Lebedevca1aaac2017-10-21 16:44:03 +000020 enum B : unsigned { B_foo = 0, B_bar, };
Roman Lebedev30d26082017-09-20 13:50:01 +000021 enum B b;
22
Roman Lebedevca1aaac2017-10-21 16:44:03 +000023 enum C : signed { C_foo = 0, C_bar, };
Roman Lebedev30d26082017-09-20 13:50:01 +000024 enum C c;
25
Hal Finkel05e46482017-12-16 02:23:22 +000026 if (a < 0) // unsigned-warning {{comparison of unsigned enum expression < 0 is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000027 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000028 if (0 >= a)
29 return 0;
30 if (a > 0)
Roman Lebedev30d26082017-09-20 13:50:01 +000031 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000032 if (0 <= a) // unsigned-warning {{comparison of 0 <= unsigned enum expression is always true}}
Roman Lebedev30d26082017-09-20 13:50:01 +000033 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000034 if (a <= 0)
35 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000036 if (0 > a) // unsigned-warning {{comparison of 0 > unsigned enum expression is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000037 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000038 if (a >= 0) // unsigned-warning {{comparison of unsigned enum expression >= 0 is always true}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +000039 return 0;
40 if (0 < a)
41 return 0;
42
Hal Finkel05e46482017-12-16 02:23:22 +000043 // 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}}
Roman Lebedev30d26082017-09-20 13:50:01 +000046 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000047 if (0U >= a)
48 return 0;
49 if (a > 0U)
Roman Lebedev30d26082017-09-20 13:50:01 +000050 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000051 if (0U <= a) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
Roman Lebedev30d26082017-09-20 13:50:01 +000052 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000053 if (a <= 0U)
54 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000055 if (0U > a) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000056 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000057 if (a >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +000058 return 0;
59 if (0U < a)
60 return 0;
Roman Lebedev30d26082017-09-20 13:50:01 +000061
Hal Finkel05e46482017-12-16 02:23:22 +000062 if (b < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000063 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000064 if (0 >= b)
65 return 0;
66 if (b > 0)
Roman Lebedev30d26082017-09-20 13:50:01 +000067 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000068 if (0 <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
Roman Lebedev30d26082017-09-20 13:50:01 +000069 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000070 if (b <= 0)
71 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000072 if (0 > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000073 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000074 if (b >= 0) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
Roman Lebedev30d26082017-09-20 13:50:01 +000075 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000076 if (0 < b)
Roman Lebedev30d26082017-09-20 13:50:01 +000077 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000078
Hal Finkel05e46482017-12-16 02:23:22 +000079 if (b < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000080 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000081 if (0U >= b)
82 return 0;
83 if (b > 0U)
Roman Lebedev30d26082017-09-20 13:50:01 +000084 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000085 if (0U <= b) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
Roman Lebedev30d26082017-09-20 13:50:01 +000086 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000087 if (b <= 0U)
88 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000089 if (0U > b) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
Roman Lebedev30d26082017-09-20 13:50:01 +000090 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +000091 if (b >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
Roman Lebedev30d26082017-09-20 13:50:01 +000092 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +000093 if (0U < b)
Roman Lebedev30d26082017-09-20 13:50:01 +000094 return 0;
95
96 if (c < 0)
97 return 0;
Richard Smith371e9e8a2017-12-06 03:00:51 +000098 if (0 >= c)
Roman Lebedevca1aaac2017-10-21 16:44:03 +000099 return 0;
Richard Smith371e9e8a2017-12-06 03:00:51 +0000100 if (c > 0)
Roman Lebedev30d26082017-09-20 13:50:01 +0000101 return 0;
102 if (0 <= c)
103 return 0;
Richard Smith371e9e8a2017-12-06 03:00:51 +0000104 if (c <= 0)
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000105 return 0;
Roman Lebedev30d26082017-09-20 13:50:01 +0000106 if (0 > c)
107 return 0;
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000108 if (c >= 0)
109 return 0;
Richard Smith371e9e8a2017-12-06 03:00:51 +0000110 if (0 < c)
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000111 return 0;
112
Richard Smith371e9e8a2017-12-06 03:00:51 +0000113 // FIXME: These diagnostics are terrible. The issue here is that the signed
114 // enumeration value was promoted to an unsigned type.
Hal Finkel05e46482017-12-16 02:23:22 +0000115 if (c < 0U) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000116 return 0;
117 if (0U >= c)
118 return 0;
119 if (c > 0U)
120 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +0000121 if (0U <= c) // unsigned-signed-warning {{comparison of 0 <= unsigned enum expression is always true}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000122 return 0;
123 if (c <= 0U)
124 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +0000125 if (0U > c) // unsigned-signed-warning {{comparison of 0 > unsigned enum expression is always false}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000126 return 0;
Hal Finkel05e46482017-12-16 02:23:22 +0000127 if (c >= 0U) // unsigned-signed-warning {{comparison of unsigned enum expression >= 0 is always true}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000128 return 0;
129 if (0U < c)
130 return 0;
Roman Lebedev30d26082017-09-20 13:50:01 +0000131
132 return 1;
133}
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000134
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()
Hal Finkel05e46482017-12-16 02:23:22 +0000143 if (a < 0) // unsigned-signed-warning {{comparison of unsigned enum expression < 0 is always false}}
Roman Lebedevca1aaac2017-10-21 16:44:03 +0000144 return 0;
145
146 return 1;
147}
148} // namespace crash_enum_zero_width