diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 32e481dd2d480..2ab4814fa0cc3 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -176,11 +176,15 @@ fn classify_ty(ty: Type) -> Vec { } fn classify_struct(tys: &[Type], - cls: &mut [RegClass], i: uint, - off: uint) { + cls: &mut [RegClass], + i: uint, + off: uint, + packed: bool) { let mut field_off = off; for ty in tys.iter() { - field_off = align(field_off, *ty); + if !packed { + field_off = align(field_off, *ty); + } classify(*ty, cls, i, field_off); field_off += ty_size(*ty); } @@ -219,7 +223,7 @@ fn classify_ty(ty: Type) -> Vec { unify(cls, ix + off / 8u, SSEDs); } Struct => { - classify_struct(ty.field_types().as_slice(), cls, ix, off); + classify_struct(ty.field_types().as_slice(), cls, ix, off, ty.is_packed()); } Array => { let len = ty.array_length(); diff --git a/src/test/run-make/extern-fn-with-packed-struct/Makefile b/src/test/run-make/extern-fn-with-packed-struct/Makefile new file mode 100644 index 0000000000000..ea6971853fe99 --- /dev/null +++ b/src/test/run-make/extern-fn-with-packed-struct/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(CC) -std=c99 test.c -c -o $(TMPDIR)/test.o + $(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o + $(RUSTC) test.rs -L $(TMPDIR) + $(call RUN,test) || exit 1 diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.c b/src/test/run-make/extern-fn-with-packed-struct/test.c new file mode 100644 index 0000000000000..c3456a64b9bc4 --- /dev/null +++ b/src/test/run-make/extern-fn-with-packed-struct/test.c @@ -0,0 +1,11 @@ +// Pragma needed cause of gcc bug on windows: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 +#pragma pack(1) +struct __attribute__((packed)) Foo { + char a; + short b; + char c; +}; + +struct Foo foo(struct Foo foo) { + return foo; +} diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make/extern-fn-with-packed-struct/test.rs new file mode 100644 index 0000000000000..4b07b7f39f56d --- /dev/null +++ b/src/test/run-make/extern-fn-with-packed-struct/test.rs @@ -0,0 +1,30 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[packed] +#[deriving(PartialEq, Show)] +struct Foo { + a: i8, + b: i16, + c: i8 +} + +#[link(name = "test", kind = "static")] +extern { + fn foo(f: Foo) -> Foo; +} + +fn main() { + unsafe { + let a = Foo { a: 1, b: 2, c: 3 }; + let b = foo(a); + assert_eq!(a, b); + } +}