1 | // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s |
2 | |
3 | enum class E1 { |
4 | Val1 = 1L |
5 | }; |
6 | |
7 | enum struct E2 { |
8 | Val1 = '\0' |
9 | }; |
10 | |
11 | E1 v1 = Val1; // expected-error{{undeclared identifier}} |
12 | E1 v2 = E1::Val1; |
13 | |
14 | static_assert(sizeof(E1) == sizeof(int), "bad size"); |
15 | static_assert(sizeof(E1::Val1) == sizeof(int), "bad size"); |
16 | static_assert(sizeof(E2) == sizeof(int), "bad size"); |
17 | static_assert(sizeof(E2::Val1) == sizeof(int), "bad size"); |
18 | |
19 | E1 v3 = E2::Val1; // expected-error{{cannot initialize a variable}} |
20 | int x1 = E1::Val1; // expected-error{{cannot initialize a variable}} |
21 | |
22 | enum E3 : char { |
23 | Val2 = 1 |
24 | }; |
25 | |
26 | E3 v4 = Val2; |
27 | E1 v5 = Val2; // expected-error{{cannot initialize a variable}} |
28 | |
29 | static_assert(sizeof(E3) == 1, "bad size"); |
30 | |
31 | int x2 = Val2; |
32 | |
33 | int a1[Val2]; |
34 | int a2[E1::Val1]; // expected-error{{size of array has non-integer type}} |
35 | |
36 | int* p1 = new int[Val2]; |
37 | int* p2 = new int[E1::Val1]; // expected-error{{array size expression must have integral or unscoped enumeration type, not 'E1'}} |
38 | |
39 | enum class E4 { |
40 | e1 = -2147483648, // ok |
41 | e2 = 2147483647, // ok |
42 | e3 = 2147483648 // expected-error{{enumerator value evaluates to 2147483648, which cannot be narrowed to type 'int'}} |
43 | }; |
44 | |
45 | enum class E5 { |
46 | e1 = 2147483647, // ok |
47 | e2 // expected-error{{2147483648 is not representable in the underlying}} |
48 | }; |
49 | |
50 | enum class E6 : bool { |
51 | e1 = false, e2 = true, |
52 | e3 // expected-error{{2 is not representable in the underlying}} |
53 | }; |
54 | |
55 | enum E7 : bool { |
56 | e1 = false, e2 = true, |
57 | e3 // expected-error{{2 is not representable in the underlying}} |
58 | }; |
59 | |
60 | template <class T> |
61 | struct X { |
62 | enum E : T { |
63 | e1, e2, |
64 | e3 // expected-error{{2 is not representable in the underlying}} |
65 | }; |
66 | }; |
67 | |
68 | X<bool> X2; // expected-note{{in instantiation of template}} |
69 | |
70 | enum Incomplete1; // expected-error{{C++ forbids forward references}} |
71 | |
72 | enum Complete1 : int; |
73 | Complete1 complete1; |
74 | |
75 | enum class Complete2; |
76 | Complete2 complete2; |
77 | |
78 | // All the redeclarations below are done twice on purpose. Tests that the type |
79 | // of the declaration isn't changed. |
80 | |
81 | enum class Redeclare2; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}} |
82 | enum Redeclare2; // expected-error{{previously declared as scoped}} |
83 | enum Redeclare2; // expected-error{{previously declared as scoped}} |
84 | |
85 | enum Redeclare3 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}} |
86 | enum Redeclare3; // expected-error{{previously declared with fixed underlying type}} |
87 | enum Redeclare3; // expected-error{{previously declared with fixed underlying type}} |
88 | |
89 | enum class Redeclare5; |
90 | enum class Redeclare5 : int; // ok |
91 | |
92 | enum Redeclare6 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}} |
93 | enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}} |
94 | enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}} |
95 | |
96 | enum class Redeclare7; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}} |
97 | enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}} |
98 | enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}} |
99 | |
100 | enum : long { |
101 | long_enum_val = 10000 |
102 | }; |
103 | |
104 | enum : long x; // expected-error{{unnamed enumeration must be a definition}} \ |
105 | // expected-warning{{declaration does not declare anything}} |
106 | |
107 | void PR9333() { |
108 | enum class scoped_enum { yes, no, maybe }; |
109 | scoped_enum e = scoped_enum::yes; |
110 | if (e == scoped_enum::no) { } |
111 | } |
112 | |
113 | // <rdar://problem/9366066> |
114 | namespace rdar9366066 { |
115 | enum class X : unsigned { value }; |
116 | |
117 | void f(X x) { |
118 | x % X::value; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'rdar9366066::X')}} |
119 | x % 8; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'int')}} |
120 | } |
121 | } |
122 | |
123 | // Part 1 of PR10264 |
124 | namespace test5 { |
125 | namespace ns { |
126 | typedef unsigned Atype; |
127 | enum A : Atype; |
128 | } |
129 | enum ns::A : ns::Atype { |
130 | x, y, z |
131 | }; |
132 | } |
133 | |
134 | // Part 2 of PR10264 |
135 | namespace test6 { |
136 | enum A : unsigned; |
137 | struct A::a; // expected-error {{incomplete type 'test6::A' named in nested name specifier}} |
138 | enum A::b; // expected-error {{incomplete type 'test6::A' named in nested name specifier}} |
139 | int A::c; // expected-error {{incomplete type 'test6::A' named in nested name specifier}} |
140 | void A::d(); // expected-error {{incomplete type 'test6::A' named in nested name specifier}} |
141 | void test() { |
142 | (void) A::e; // expected-error {{incomplete type 'test6::A' named in nested name specifier}} |
143 | } |
144 | } |
145 | |
146 | namespace PR11484 { |
147 | const int val = 104; |
148 | enum class test1 { owner_dead = val, }; |
149 | } |
150 | |
151 | namespace N2764 { |
152 | enum class E { a, b }; |
153 | enum E x1 = E::a; // ok |
154 | enum class E x2 = E::a; // expected-error {{reference to scoped enumeration must use 'enum' not 'enum class'}} |
155 | |
156 | enum F { a, b }; |
157 | enum F y1 = a; // ok |
158 | enum class F y2 = a; // expected-error {{reference to enumeration must use 'enum' not 'enum class'}} |
159 | |
160 | struct S { |
161 | friend enum class E; // expected-error {{reference to scoped enumeration must use 'enum' not 'enum class'}} |
162 | friend enum class F; // expected-error {{reference to enumeration must use 'enum' not 'enum class'}} |
163 | |
164 | friend enum G {}; // expected-error {{forward reference}} expected-error {{cannot define a type in a friend declaration}} |
165 | friend enum class H {}; // expected-error {{cannot define a type in a friend declaration}} |
166 | |
167 | enum A : int; |
168 | A a; |
169 | } s; |
170 | |
171 | enum S::A : int {}; |
172 | |
173 | enum class B; |
174 | } |
175 | |
176 | enum class N2764::B {}; |
177 | |
178 | namespace PR12106 { |
179 | template<typename E> struct Enum { |
180 | Enum() : m_e(E::Last) {} |
181 | E m_e; |
182 | }; |
183 | |
184 | enum eCOLORS { Last }; |
185 | Enum<eCOLORS> e; |
186 | } |
187 | |
188 | namespace test7 { |
189 | enum class E { e = (struct S*)0 == (struct S*)0 }; |
190 | S *p; |
191 | } |
192 | |
193 | namespace test8 { |
194 | template<typename T> struct S { |
195 | enum A : int; // expected-note {{here}} |
196 | enum class B; // expected-note {{here}} |
197 | enum class C : int; // expected-note {{here}} |
198 | enum class D : int; // expected-note {{here}} |
199 | }; |
200 | template<typename T> enum S<T>::A { a }; // expected-error {{previously declared with fixed underlying type}} |
201 | template<typename T> enum class S<T>::B : char { b }; // expected-error {{redeclared with different underlying}} |
202 | template<typename T> enum S<T>::C : int { c }; // expected-error {{previously declared as scoped}} |
203 | template<typename T> enum class S<T>::D : char { d }; // expected-error {{redeclared with different underlying}} |
204 | } |
205 | |
206 | namespace test9 { |
207 | template<typename T> struct S { |
208 | enum class ET : T; // expected-note 2{{here}} |
209 | enum class Eint : int; // expected-note 2{{here}} |
210 | }; |
211 | template<> enum class S<int>::ET : int {}; |
212 | template<> enum class S<char>::ET : short {}; // expected-error {{different underlying type}} |
213 | template<> enum class S<int>::Eint : short {}; // expected-error {{different underlying type}} |
214 | template<> enum class S<char>::Eint : int {}; |
215 | |
216 | template<typename T> enum class S<T>::ET : int {}; // expected-error {{different underlying type 'int' (was 'short')}} |
217 | template<typename T> enum class S<T>::Eint : T {}; // expected-error {{different underlying type 'short' (was 'int')}} |
218 | |
219 | // The implicit instantiation of S<short> causes the implicit instantiation of |
220 | // all declarations of member enumerations, so is ill-formed, even though we |
221 | // never instantiate the definitions of S<short>::ET nor S<short>::Eint. |
222 | S<short> s; // expected-note {{in instantiation of}} |
223 | } |
224 | |
225 | namespace test10 { |
226 | template<typename T> int f() { |
227 | enum E : int; |
228 | enum E : T; // expected-note {{here}} |
229 | E x; |
230 | enum E : int { e }; // expected-error {{different underlying}} |
231 | x = e; |
232 | return x; |
233 | } |
234 | int k = f<int>(); |
235 | int l = f<short>(); // expected-note {{here}} |
236 | |
237 | template<typename T> int g() { |
238 | enum class E : int; |
239 | enum class E : T; // expected-note {{here}} |
240 | E x; |
241 | enum class E : int { e }; // expected-error {{different underlying}} |
242 | x = E::e; |
243 | return (int)x; |
244 | } |
245 | int m = g<int>(); |
246 | int n = g<short>(); // expected-note {{here}} |
247 | } |
248 | |
249 | namespace pr13128 { |
250 | // This should compile cleanly |
251 | class C { |
252 | enum class E { C }; |
253 | }; |
254 | } |
255 | |
256 | namespace PR15633 { |
257 | template<typename T> struct A { |
258 | struct B { |
259 | enum class E : T; |
260 | enum class E2 : T; |
261 | }; |
262 | }; |
263 | template<typename T> enum class A<T>::B::E { e }; |
264 | template class A<int>; |
265 | |
266 | struct B { enum class E; }; |
267 | template<typename T> enum class B::E { e }; // expected-error {{enumeration cannot be a template}} |
268 | } |
269 | |
270 | namespace PR16900 { |
271 | enum class A; |
272 | A f(A a) { return -a; } // expected-error {{invalid argument type 'PR16900::A' to unary expression}} |
273 | } |
274 | |
275 | namespace PR18551 { |
276 | enum class A { A }; |
277 | bool f() { return !A::A; } // expected-error {{invalid argument type 'PR18551::A' to unary expression}} |
278 | } |
279 | |
280 | namespace rdar15124329 { |
281 | enum class B : bool { F, T }; |
282 | |
283 | const rdar15124329::B T1 = B::T; |
284 | typedef B C; const C T2 = B::T; |
285 | |
286 | static_assert(T1 != B::F, ""); |
287 | static_assert(T2 == B::T, ""); |
288 | } |
289 | |
290 | namespace PR18044 { |
291 | enum class E { a }; |
292 | |
293 | int E::e = 0; // expected-error {{does not refer into a class}} |
294 | void E::f() {} // expected-error {{does not refer into a class}} |
295 | struct E::S {}; // expected-error {{no struct named 'S'}} |
296 | struct T : E::S {}; // expected-error {{expected class name}} |
297 | enum E::E {}; // expected-error {{no enum named 'E'}} |
298 | int E::*p; // expected-error {{does not point into a class}} |
299 | using E::f; // expected-error {{no member named 'f'}} |
300 | |
301 | using E::a; // expected-error {{using declaration cannot refer to a scoped enumerator}} |
302 | E b = a; // expected-error {{undeclared}} |
303 | } |
304 | |
305 | namespace test11 { |
306 | enum class E { a }; |
307 | typedef E E2; |
308 | E2 f1() { return E::a; } |
309 | |
310 | bool f() { return !f1(); } // expected-error {{invalid argument type 'test11::E2' (aka 'test11::E') to unary expression}} |
311 | } |
312 | |
313 | namespace PR35586 { |
314 | enum C { R, G, B }; |
315 | enum B { F = (enum C) -1, T}; // this should compile cleanly, it used to assert. |
316 | }; |
317 | |