diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4503,13 +4503,13 @@ Kind.getKind() == InitializationKind::IK_DirectList && ET && ET->getDecl()->isFixed() && !S.Context.hasSameUnqualifiedType(E->getType(), DestType) && - (E->getType()->isIntegralOrEnumerationType() || + (E->getType()->isIntegralOrUnscopedEnumerationType() || E->getType()->isFloatingType())) { // There are two ways that T(v) can work when T is an enumeration type. // If there is either an implicit conversion sequence from v to T or // a conversion function that can convert from v to T, then we use that. - // Otherwise, if v is of integral, enumeration, or floating-point type, - // it is converted to the enumeration type via its underlying type. + // Otherwise, if v is of integral, unscoped enumeration, or floating-point + // type, it is converted to the enumeration type via its underlying type. // There is no overlap possible between these two cases (except when the // source value is already of the destination type), and the first // case is handled by the general case for single-element lists below. diff --git a/clang/test/SemaCXX/enum-scoped.cpp b/clang/test/SemaCXX/enum-scoped.cpp --- a/clang/test/SemaCXX/enum-scoped.cpp +++ b/clang/test/SemaCXX/enum-scoped.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++17 -verify -triple x86_64-apple-darwin %s enum class E1 { Val1 = 1L @@ -31,10 +32,22 @@ int x2 = Val2; int a1[Val2]; -int a2[E1::Val1]; // expected-error{{size of array has non-integer type}} +int a2[E1::Val1]; + +#if __cplusplus >= 201703L +// expected-error@-3 {{type 'E1' is not implicitly convertible to 'unsigned long'}} +#else +// expected-error@-5 {{size of array has non-integer type}} +#endif 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'}} +int* p2 = new int[E1::Val1]; + +#if __cplusplus >= 201703L +// expected-error@-3 {{converting 'E1' to incompatible type 'unsigned long'}} +#else +// expected-error@-5 {{array size expression must have integral or unscoped enumeration type, not 'E1'}} +#endif enum class E4 { e1 = -2147483648, // ok @@ -317,3 +330,11 @@ enum C { R, G, B }; enum B { F = (enum C) -1, T}; // this should compile cleanly, it used to assert. }; + +namespace test12 { +// Check that clang rejects this code without crashing in c++17. +enum class A; +enum class B; +A a; +B b{a}; // expected-error {{cannot initialize}} +}