summaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/enum-scoped.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/enum-scoped.cpp')
-rw-r--r--clang/test/SemaCXX/enum-scoped.cpp247
1 files changed, 247 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/enum-scoped.cpp b/clang/test/SemaCXX/enum-scoped.cpp
new file mode 100644
index 0000000..ebe9245
--- /dev/null
+++ b/clang/test/SemaCXX/enum-scoped.cpp
@@ -0,0 +1,247 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s
+
+enum class E1 {
+ Val1 = 1L
+};
+
+enum struct E2 {
+ Val1 = '\0'
+};
+
+E1 v1 = Val1; // expected-error{{undeclared identifier}}
+E1 v2 = E1::Val1;
+
+static_assert(sizeof(E1) == sizeof(int), "bad size");
+static_assert(sizeof(E1::Val1) == sizeof(int), "bad size");
+static_assert(sizeof(E2) == sizeof(int), "bad size");
+static_assert(sizeof(E2::Val1) == sizeof(int), "bad size");
+
+E1 v3 = E2::Val1; // expected-error{{cannot initialize a variable}}
+int x1 = E1::Val1; // expected-error{{cannot initialize a variable}}
+
+enum E3 : char {
+ Val2 = 1
+};
+
+E3 v4 = Val2;
+E1 v5 = Val2; // expected-error{{cannot initialize a variable}}
+
+static_assert(sizeof(E3) == 1, "bad size");
+
+int x2 = Val2;
+
+int a1[Val2];
+int a2[E1::Val1]; // expected-error{{size of array has non-integer type}}
+
+int* p1 = new int[Val2];
+int* p2 = new int[E1::Val1]; // expected-error{{array size expression must have integral or unscoped enumeration type, not 'E1'}}
+
+enum class E4 {
+ e1 = -2147483648, // ok
+ e2 = 2147483647, // ok
+ e3 = 2147483648 // expected-error{{enumerator value evaluates to 2147483648, which cannot be narrowed to type 'int'}}
+};
+
+enum class E5 {
+ e1 = 2147483647, // ok
+ e2 // expected-error{{2147483648 is not representable in the underlying}}
+};
+
+enum class E6 : bool {
+ e1 = false, e2 = true,
+ e3 // expected-error{{2 is not representable in the underlying}}
+};
+
+enum E7 : bool {
+ e1 = false, e2 = true,
+ e3 // expected-error{{2 is not representable in the underlying}}
+};
+
+template <class T>
+struct X {
+ enum E : T {
+ e1, e2,
+ e3 // expected-error{{2 is not representable in the underlying}}
+ };
+};
+
+X<bool> X2; // expected-note{{in instantiation of template}}
+
+enum Incomplete1; // expected-error{{C++ forbids forward references}}
+
+enum Complete1 : int;
+Complete1 complete1;
+
+enum class Complete2;
+Complete2 complete2;
+
+// All the redeclarations below are done twice on purpose. Tests that the type
+// of the declaration isn't changed.
+
+enum class Redeclare2; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare2; // expected-error{{previously declared as scoped}}
+enum Redeclare2; // expected-error{{previously declared as scoped}}
+
+enum Redeclare3 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
+enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
+
+enum class Redeclare5;
+enum class Redeclare5 : int; // ok
+
+enum Redeclare6 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
+enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
+
+enum class Redeclare7; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
+enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
+
+enum : long {
+ long_enum_val = 10000
+};
+
+enum : long x; // expected-error{{unnamed enumeration must be a definition}} \
+// expected-warning{{declaration does not declare anything}}
+
+void PR9333() {
+ enum class scoped_enum { yes, no, maybe };
+ scoped_enum e = scoped_enum::yes;
+ if (e == scoped_enum::no) { }
+}
+
+// <rdar://problem/9366066>
+namespace rdar9366066 {
+ enum class X : unsigned { value };
+
+ void f(X x) {
+ x % X::value; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'rdar9366066::X')}}
+ x % 8; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'int')}}
+ }
+}
+
+// Part 1 of PR10264
+namespace test5 {
+ namespace ns {
+ typedef unsigned Atype;
+ enum A : Atype;
+ }
+ enum ns::A : ns::Atype {
+ x, y, z
+ };
+}
+
+// Part 2 of PR10264
+namespace test6 {
+ enum A : unsigned;
+ struct A::a; // expected-error {{incomplete type 'test6::A' named in nested name specifier}}
+ enum A::b; // expected-error {{incomplete type 'test6::A' named in nested name specifier}}
+ int A::c; // expected-error {{incomplete type 'test6::A' named in nested name specifier}}
+ void A::d(); // expected-error {{incomplete type 'test6::A' named in nested name specifier}}
+ void test() {
+ (void) A::e; // expected-error {{incomplete type 'test6::A' named in nested name specifier}}
+ }
+}
+
+namespace PR11484 {
+ const int val = 104;
+ enum class test1 { owner_dead = val, };
+}
+
+namespace N2764 {
+ enum class E { a, b };
+ enum E x1 = E::a; // ok
+ enum class E x2 = E::a; // expected-error {{reference to scoped enumeration must use 'enum' not 'enum class'}}
+
+ enum F { a, b };
+ enum F y1 = a; // ok
+ enum class F y2 = a; // expected-error {{reference to enumeration must use 'enum' not 'enum class'}}
+
+ struct S {
+ friend enum class E; // expected-error {{reference to scoped enumeration must use 'enum' not 'enum class'}}
+ friend enum class F; // expected-error {{reference to enumeration must use 'enum' not 'enum class'}}
+
+ friend enum G {}; // expected-error {{forward reference}} expected-error {{cannot define a type in a friend declaration}}
+ friend enum class H {}; // expected-error {{cannot define a type in a friend declaration}}
+
+ enum A : int;
+ A a;
+ } s;
+
+ enum S::A : int {};
+
+ enum class B;
+}
+
+enum class N2764::B {};
+
+namespace PR12106 {
+ template<typename E> struct Enum {
+ Enum() : m_e(E::Last) {}
+ E m_e;
+ };
+
+ enum eCOLORS { Last };
+ Enum<eCOLORS> e;
+}
+
+namespace test7 {
+ enum class E { e = (struct S*)0 == (struct S*)0 };
+ S *p;
+}
+
+namespace test8 {
+ template<typename T> struct S {
+ enum A : int; // expected-note {{here}}
+ enum class B; // expected-note {{here}}
+ enum class C : int; // expected-note {{here}}
+ enum class D : int; // expected-note {{here}}
+ };
+ template<typename T> enum S<T>::A { a }; // expected-error {{previously declared with fixed underlying type}}
+ template<typename T> enum class S<T>::B : char { b }; // expected-error {{redeclared with different underlying}}
+ template<typename T> enum S<T>::C : int { c }; // expected-error {{previously declared as scoped}}
+ template<typename T> enum class S<T>::D : char { d }; // expected-error {{redeclared with different underlying}}
+}
+
+namespace test9 {
+ template<typename T> struct S {
+ enum class ET : T; // expected-note 2{{here}}
+ enum class Eint : int; // expected-note 2{{here}}
+ };
+ template<> enum class S<int>::ET : int {};
+ template<> enum class S<char>::ET : short {}; // expected-error {{different underlying type}}
+ template<> enum class S<int>::Eint : short {}; // expected-error {{different underlying type}}
+ template<> enum class S<char>::Eint : int {};
+
+ template<typename T> enum class S<T>::ET : int {}; // expected-error {{different underlying type 'int' (was 'short')}}
+ template<typename T> enum class S<T>::Eint : T {}; // expected-error {{different underlying type 'short' (was 'int')}}
+
+ // The implicit instantiation of S<short> causes the implicit instantiation of
+ // all declarations of member enumerations, so is ill-formed, even though we
+ // never instantiate the definitions of S<short>::ET nor S<short>::Eint.
+ S<short> s; // expected-note {{in instantiation of}}
+}
+
+namespace test10 {
+ template<typename T> int f() {
+ enum E : int;
+ enum E : T; // expected-note {{here}}
+ E x;
+ enum E : int { e }; // expected-error {{different underlying}}
+ x = e;
+ return x;
+ }
+ int k = f<int>();
+ int l = f<short>(); // expected-note {{here}}
+
+ template<typename T> int g() {
+ enum class E : int;
+ enum class E : T; // expected-note {{here}}
+ E x;
+ enum class E : int { e }; // expected-error {{different underlying}}
+ x = E::e;
+ return (int)x;
+ }
+ int m = g<int>();
+ int n = g<short>(); // expected-note {{here}}
+}