diff options
| author | bors <bors@rust-lang.org> | 2013-11-25 20:32:22 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-11-25 20:32:22 -0800 |
| commit | 720bcd81de9d5fbdb60761fc929d40e487005722 (patch) | |
| tree | d4b3631a582b7bca65f25945b5b22c89a3708fce /src/test | |
| parent | ffaee0fd96b5d23ae9668605d1425111f4210c58 (diff) | |
| parent | 0c04a26b3f8ba70ea686e1a365729835c62c26eb (diff) | |
| download | rust-720bcd81de9d5fbdb60761fc929d40e487005722.tar.gz rust-720bcd81de9d5fbdb60761fc929d40e487005722.zip | |
auto merge of #10652 : jld/rust/enum-unstruct, r=thestinger
This is needed so that the FFI works as expected on platforms that don't flatten aggregates the way the AMD64 ABI does, especially for `#[repr(C)]`. This moves more of `type_of` into `trans::adt`, because the type might or might not be an LLVM struct. Closes #10308.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/run-pass/enum-clike-ffi-as-int.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/test/run-pass/enum-clike-ffi-as-int.rs b/src/test/run-pass/enum-clike-ffi-as-int.rs new file mode 100644 index 00000000000..0c897b959a5 --- /dev/null +++ b/src/test/run-pass/enum-clike-ffi-as-int.rs @@ -0,0 +1,39 @@ +// Copyright 2013 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! + * C-like enums have to be represented as LLVM ints, not wrapped in a + * struct, because it's important for the FFI that they interoperate + * with C integers/enums, and the ABI can treat structs differently. + * For example, on i686-linux-gnu, a struct return value is passed by + * storing to a hidden out parameter, whereas an integer would be + * returned in a register. + * + * This test just checks that the ABIs for the enum and the plain + * integer are compatible, rather than actually calling C code. + * The unused parameter to `foo` is to increase the likelihood of + * crashing if something goes wrong here. + */ + +#[repr(u32)] +enum Foo { + A = 0, + B = 23 +} + +#[inline(never)] +extern "C" fn foo(_x: uint) -> Foo { B } + +pub fn main() { + unsafe { + let f: extern "C" fn(uint) -> u32 = ::std::cast::transmute(foo); + assert_eq!(f(0xDEADBEEF), B as u32); + } +} |
