Handling direct-list-initialization of enums in C++1z mode

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Handling direct-list-initialization of enums in C++1z mode

Nat! via cfe-dev
Hi,

After r264564, it became possible to perform direct-list-initialization of an
enum in C++1z mode, if the initializer and the enum share the same underlying
type. However, clang crashes on some code which relies on this feature:

  // clang++ -std=c++1z
  enum class A : unsigned {};
  A foo(unsigned x) { return A{x}; }

(We would reject this code in C++11/14 mode.)

The crash occurs in Sema::ImpCastExprToType, while we attempt to perform an
implicit conversion from 'unsigned int' ('x') to 'A'. The issue is that this is
an integral cast in an lvalue-to-rvalue conversion, which Sema asserts is not
possible. I'm not sure why exactly this kind of implicit cast is not allowed.

I'd like to send in a patch to fix this issue, but I'm not confident in my
simplistic fix which simply weakens the assertion in Sema. I'd like to know: is
the assertion really correct (lib/Sema/Sema.cpp:405)? If so, then I'd probably
need to find some other way to perform this conversion. If not, then I'd feel
more confident in my patch.

I've attached the WIP patch for reference.




thanks,
vedant


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

0001-Sema-Allow-integral-cast-for-lvalue-to-rvalue-conver.patch (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Handling direct-list-initialization of enums in C++1z mode

Nat! via cfe-dev
On 2/7/2017 5:31 PM, Vedant Kumar via cfe-dev wrote:

> Hi,
>
> After r264564, it became possible to perform direct-list-initialization of an
> enum in C++1z mode, if the initializer and the enum share the same underlying
> type. However, clang crashes on some code which relies on this feature:
>
>    // clang++ -std=c++1z
>    enum class A : unsigned {};
>    A foo(unsigned x) { return A{x}; }
>
> (We would reject this code in C++11/14 mode.)
>
> The crash occurs in Sema::ImpCastExprToType, while we attempt to perform an
> implicit conversion from 'unsigned int' ('x') to 'A'. The issue is that this is
> an integral cast in an lvalue-to-rvalue conversion, which Sema asserts is not
> possible. I'm not sure why exactly this kind of implicit cast is not allowed.
>
> I'd like to send in a patch to fix this issue, but I'm not confident in my
> simplistic fix which simply weakens the assertion in Sema. I'd like to know: is
> the assertion really correct (lib/Sema/Sema.cpp:405)?
Yes, the assertion is correct
> If so, then I'd probably
> need to find some other way to perform this conversion.

The right way to perform the conversion is a series of two implicit
casts: one of type CK_LValueToRValue, then another of type CK_IntegralCast.

-Eli

--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Handling direct-list-initialization of enums in C++1z mode

Nat! via cfe-dev

> On Feb 7, 2017, at 5:58 PM, Friedman, Eli <[hidden email]> wrote:
>
> On 2/7/2017 5:31 PM, Vedant Kumar via cfe-dev wrote:
>> Hi,
>>
>> After r264564, it became possible to perform direct-list-initialization of an
>> enum in C++1z mode, if the initializer and the enum share the same underlying
>> type. However, clang crashes on some code which relies on this feature:
>>
>>   // clang++ -std=c++1z
>>   enum class A : unsigned {};
>>   A foo(unsigned x) { return A{x}; }
>>
>> (We would reject this code in C++11/14 mode.)
>>
>> The crash occurs in Sema::ImpCastExprToType, while we attempt to perform an
>> implicit conversion from 'unsigned int' ('x') to 'A'. The issue is that this is
>> an integral cast in an lvalue-to-rvalue conversion, which Sema asserts is not
>> possible. I'm not sure why exactly this kind of implicit cast is not allowed.
>>
>> I'd like to send in a patch to fix this issue, but I'm not confident in my
>> simplistic fix which simply weakens the assertion in Sema. I'd like to know: is
>> the assertion really correct (lib/Sema/Sema.cpp:405)?
> Yes, the assertion is correct
>> If so, then I'd probably
>> need to find some other way to perform this conversion.
>
> The right way to perform the conversion is a series of two implicit casts: one of type CK_LValueToRValue, then another of type CK_IntegralCast.

That makes sense, seeing as 'x' in my example is not an rvalue!

I will try this and send in a patch.

thank you,
vedant

>
> -Eli
>
> --
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev