Skip to content

Commit

Permalink
Auto merge of rust-lang#36321 - uweigand:enum-abi, r=eddyb
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
bors authored Sep 9, 2016
2 parents 3781956 + ce3cecf commit 1df6445
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use std::cmp;

pub use syntax::abi::Abi;
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
use rustc::ty::layout::Layout;

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

0 comments on commit 1df6445

Please sign in to comment.