Skip to content

Commit 1df6445

Browse files
authored
Auto merge of #36321 - uweigand:enum-abi, r=eddyb
Follow target ABI sign-/zero-extension rules for enum types While attempting to port Rust to s390x, I ran into an ABI violation (that caused rust_eh_personality to be miscompiled, breaking unwinding). The problem is that this function returns an enum type, which is supposed to be sign-extended according to the s390x ABI. However, common code would ignore target sign-/zero-extension rules for any types that do not satisfy is_integral(), which includes enums. For the general case of Rust enum types, which map to structure types with a discriminant, that seems correct. However, in the special case of simple enums that map directly to C enum types (i.e. LLVM integers), this is incorrect; we must follow the target extension rules for those. Signed-off-by: Ulrich Weigand <[email protected]>
2 parents 3781956 + ce3cecf commit 1df6445

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

src/librustc_trans/abi.rs

+6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::cmp;
3535

3636
pub use syntax::abi::Abi;
3737
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
38+
use rustc::ty::layout::Layout;
3839

3940
#[derive(Clone, Copy, PartialEq, Debug)]
4041
enum ArgKind {
@@ -317,6 +318,11 @@ impl FnType {
317318
if ty.is_integral() {
318319
arg.signedness = Some(ty.is_signed());
319320
}
321+
// Rust enum types that map onto C enums also need to follow
322+
// the target ABI zero-/sign-extension rules.
323+
if let Layout::CEnum { signed, .. } = *ccx.layout_of(ty) {
324+
arg.signedness = Some(signed);
325+
}
320326
if llsize_of_real(ccx, arg.ty) == 0 {
321327
// For some forsaken reason, x86_64-pc-windows-gnu
322328
// doesn't ignore zero-sized struct arguments.

0 commit comments

Comments
 (0)