You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
But it's undefined behavior to use c++ enum class in c abi.
According to x86 psABI (see figure 3.1), enum is represented with signed 4 byte. But in cpp the layout of enum class should be keep with the assigned type and no implicit conversion permitted.
We have met a bug because:
In cpp we pass an En::A to match_en, the compiler set register dl (the lower 8 bits of edx) to zero and pass edx to the cxxbridge1$match_end;
Normally in rust it only use the least 8 bits of edx ( rust takes the argument as u8). But once if lto is opened the compiler will check the interfaces and find the parameter is from c abi. Then the compiler assumes edx is properly extend zeros and directly use it to reduce instructions.
But the higher bits of edx stored junk data that are not zeros,leading to an unreachable branch.
Firefox had also met similar bug 4 years ago on non-lto environment.
Possible Solution
It's may be better to use the representing types (u8 for enums with repr(u8) .etc) when generate extern C interfaces and static_cast them on cpp side before it is passed to the extern C functions.
The text was updated successfully, but these errors were encountered:
Example
At present the generated code for
looks like
But it's undefined behavior to use c++ enum class in c abi.
According to x86 psABI (see figure 3.1), enum is represented with signed 4 byte. But in cpp the layout of enum class should be keep with the assigned type and no implicit conversion permitted.
We have met a bug because:
En::A
tomatch_en
, the compiler set registerdl
(the lower 8 bits ofedx
) to zero and passedx
to thecxxbridge1$match_end
;edx
( rust takes the argument as u8). But once if lto is opened the compiler will check the interfaces and find the parameter is from c abi. Then the compiler assumesedx
is properly extend zeros and directly use it to reduce instructions.edx
stored junk data that are not zeros,leading to an unreachable branch.Firefox had also met similar bug 4 years ago on non-lto environment.
Possible Solution
It's may be better to use the representing types (u8 for enums with repr(u8) .etc) when generate extern C interfaces and
static_cast
them on cpp side before it is passed to the extern C functions.The text was updated successfully, but these errors were encountered: