Author: vedantk Date: Wed Feb 15 19:20:00 2017 New Revision: 295266 URL: http://llvm.org/viewvc/llvm-project?rev=295266&view=rev Log: [Sema] Add lvalue-to-rvalue cast in direct-list-initialization of enum
After r264564, we allowed direct-list-initialization of an enum from an integral value in C++1z mode, so long as that value can convert to the enum's underlying type. In this kind of initialization, we need a lvalue-to-rvalue conversion for the initializer value if it is not a rvalue. This lets us accept the following code: enum class A : unsigned {}; A foo(unsigned x) { return A{x}; } Differential Revision: https://reviews.llvm.org/D29723 Modified: cfe/trunk/lib/Sema/SemaInit.cpp cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp Modified: cfe/trunk/lib/Sema/SemaInit.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=295266&r1=295265&r2=295266&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Feb 15 19:20:00 2017 @@ -3981,6 +3981,8 @@ static void TryListInitialization(Sema & ImplicitConversionSequence ICS; ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); + if (!E->isRValue()) + ICS.Standard.First = ICK_Lvalue_To_Rvalue; // If E is of a floating-point type, then the conversion is ill-formed // due to narrowing, but go through the motions in order to produce the // right diagnostic. Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp?rev=295266&r1=295265&r2=295266&view=diff ============================================================================== --- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp (original) +++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp Wed Feb 15 19:20:00 2017 @@ -150,35 +150,44 @@ namespace cxx1z_direct_enum_init { void f(T); f(T{0}); + + char c; + auto t3 = T{c}; } #if __cplusplus <= 201402L - // expected-error@-15 5{{cannot initialize}} - // expected-error@-15 5{{cannot initialize}} - // expected-error@-15 5{{cannot initialize}} + // expected-error@-18 5{{cannot initialize}} + // expected-error@-18 5{{cannot initialize}} + // expected-error@-18 5{{cannot initialize}} + // // + // expected-error@-18 5{{cannot initialize}} // - // expected-error@-15 5{{cannot initialize}} + // expected-error@-18 5{{cannot initialize}} // - // expected-error@-15 5{{cannot initialize}} + // expected-error@-18 5{{cannot initialize}} // - // expected-error@-15 5{{cannot initialize}} // + // expected-error@-18 5{{cannot initialize}} // - // expected-error@-15 5{{cannot initialize}} + // + // expected-error@-18 5{{cannot initialize}} #else - // expected-error@-29 {{cannot initialize}} - // expected-error@-29 {{cannot initialize}} - // expected-error@-29 {{cannot initialize}} + // expected-error@-35 {{cannot initialize}} + // expected-error@-35 {{cannot initialize}} + // expected-error@-35 {{cannot initialize}} + // // + // expected-error@-35 {{cannot initialize}} // - // expected-error@-29 {{cannot initialize}} + // expected-error@-35 {{cannot initialize}} // - // expected-error@-29 {{cannot initialize}} + // expected-error@-35 {{cannot initialize}} // - // expected-error@-29 {{cannot initialize}} // + // expected-error@-35 {{cannot initialize}} // - // expected-error@-29 {{cannot initialize}} + // + // expected-error@-35 {{cannot initialize}} #endif template<typename T> void bad() { @@ -252,4 +261,12 @@ namespace cxx1z_direct_enum_init { (void)B{0.0}; // expected-error {{type 'double' cannot be narrowed}} #endif } + +#if __cplusplus > 201402L + enum class F : unsigned {}; + F f1(unsigned x) { return F{x}; } + F f2(const unsigned x) { return F{x}; } + F f3(bool x) { return F{x}; } + F f4(const bool x) { return F{x}; } +#endif } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits