[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 llvm-svn: 295266
This commit is contained in:
parent
6237678b14
commit
f4217f862a
|
@ -3981,6 +3981,8 @@ static void TryListInitialization(Sema &S,
|
|||
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.
|
||||
|
|
|
@ -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@-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}}
|
||||
//
|
||||
//
|
||||
// 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@-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}}
|
||||
//
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue