xref: /llvm-project/clang/test/SemaCXX/enum.cpp (revision df9769e14b79048331c33deeda1a93acc9a4a73e)
1 // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++98 -verify -triple x86_64-apple-darwin %s
2 // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s
3 
4 // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++98 -verify -triple x86_64-apple-darwin %s -fexperimental-new-constant-interpreter
5 // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s -fexperimental-new-constant-interpreter
6 
7 enum E { // expected-note{{previous definition is here}}
8   Val1,
9   Val2
10 };
11 
12 enum E; // expected-warning{{redeclaration of already-defined enum 'E' is a GNU extension}}
13 
14 int& enumerator_type(int);
15 float& enumerator_type(E);
16 
17 void f() {
18   E e = Val1;
19   float& fr = enumerator_type(Val2);
20 }
21 
22 typedef enum Foo {
23   A = 0,
24   B = 1
25 } Foo;
26 
27 void bar() {
28   Foo myvar = A;
29   myvar = B;
30 }
31 
32 /// PR3688
33 struct s1 {
34   enum e1 (*bar)(void); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
35 };
36 
37 enum e1 { YES, NO };
38 
39 static enum e1 badfunc(struct s1 *q) {
40   return q->bar();
41 }
42 
43 enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}}
44 
45 namespace test1 {
46   template <class A, class B> struct is_same { static const int value = -1; };
47   template <class A> struct is_same<A,A> { static const int value = 1; };
48 
49   enum enum0 { v0 };
50   int test0[is_same<__typeof(+v0), int>::value];
51 
52   enum enum1 { v1 = __INT_MAX__ };
53   int test1[is_same<__typeof(+v1), int>::value];
54 
55   enum enum2 { v2 = __INT_MAX__ * 2U };
56   int test2[is_same<__typeof(+v2), unsigned int>::value];
57 
58   enum enum3 { v3 = __LONG_MAX__ };
59   int test3[is_same<__typeof(+v3), long>::value];
60 
61   enum enum4 { v4 = __LONG_MAX__ * 2UL };
62   int test4[is_same<__typeof(+v4), unsigned long>::value];
63 }
64 
65 // PR6061
66 namespace PR6061 {
67   struct A { enum { id }; };
68   struct B { enum { id }; };
69 
70   struct C : public A, public B
71   {
72     enum { id };
73   };
74 }
75 
76 namespace Conditional {
77   enum a { A }; a x(const enum a x) { return 1?x:A; }
78 }
79 
80 namespace PR7051 {
81   enum E { e0 };
82   void f() {
83     E e;
84     e = 1; // expected-error{{assigning to 'E' from incompatible type 'int'}}
85     e |= 1; // expected-error{{assigning to 'E' from incompatible type 'int'}}
86   }
87 }
88 
89 // PR7466
90 enum { }; // expected-warning{{declaration does not declare anything}}
91 typedef enum { }; // expected-warning{{typedef requires a name}}
92 
93 // PR7921
94 enum PR7921E { // expected-note {{not complete until the closing '}'}}
95     PR7921V = (PR7921E)(123) // expected-error {{'PR7921E' is an incomplete type}}
96 };
97 
98 void PR8089() {
99   enum E; // expected-error{{ISO C++ forbids forward references to 'enum' types}} expected-note {{forward declaration}}
100   int a = (E)3; // expected-error {{'E' is an incomplete type}}
101 }
102 
103 // This is accepted as a GNU extension. In C++98, there was no provision for
104 // expressions with UB to be non-constant.
105 enum { overflow = 123456 * 234567 };
106 // expected-error@-1 {{expression is not an integral constant expression}}
107 // expected-note@-2 {{value 28958703552 is outside the range of representable values of type 'int'}}
108 #if __cplusplus < 201103L
109 // expected-warning@-4 {{overflow in expression; result is -1'106'067'520 with type 'int'}}
110 #endif
111 enum { overflow_shift = 1 << 32 };
112 // expected-error@-1 {{expression is not an integral constant expression}}
113 // expected-note@-2 {{shift count 32 >= width of type 'int' (32 bits)}}
114 
115 // FIXME: This is not consistent with the above case.
116 enum NoFold : int { overflow2 = 123456 * 234567 };
117 #if __cplusplus >= 201103L
118 // expected-error@-2 {{enumerator value is not a constant expression}}
119 // expected-note@-3 {{value 28958703552 is outside the range of representable values}}
120 #else
121 // expected-warning@-5 {{enumeration types with a fixed underlying type are a C++11 extension}}
122 // expected-warning@-6 {{overflow in expression; result is -1'106'067'520 with type 'int'}}
123 // expected-error@-7 {{expression is not an integral constant expression}}
124 // expected-note@-8 {{value 28958703552 is outside the range of representable values of type 'int'}}
125 #endif
126 enum : int { overflow2_shift = 1 << 32 };
127 #if __cplusplus >= 201103L
128 // expected-error@-2 {{enumerator value is not a constant expression}}
129 // expected-note@-3 {{shift count 32 >= width of type 'int' (32 bits)}}
130 #else
131 // expected-error@-5 {{expression is not an integral constant expression}}
132 // expected-note@-6 {{shift count 32 >= width of type 'int' (32 bits)}}
133 // expected-warning@-7 {{enumeration types with a fixed underlying type are a C++11 extension}}
134 #endif
135 
136 
137 // PR28903
138 struct PR28903 {
139   enum {
140     PR28903_A = (enum { // expected-error-re {{'PR28903::(unnamed enum at {{.*}})' cannot be defined in an enumeration}}
141       PR28903_B,
142       PR28903_C = PR28903_B
143     })
144   };
145 };
146 
147 namespace GH112208 {
148 class C {
149   enum E { e = 0 };
150   void f(int, enum E;); // expected-error {{ISO C++ forbids forward references to 'enum' types}} \
151                         // expected-error {{unexpected ';' before ')'}}
152 };
153 }
154