summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-25 20:32:22 -0800
committerbors <bors@rust-lang.org>2013-11-25 20:32:22 -0800
commit720bcd81de9d5fbdb60761fc929d40e487005722 (patch)
treed4b3631a582b7bca65f25945b5b22c89a3708fce /src/test
parentffaee0fd96b5d23ae9668605d1425111f4210c58 (diff)
parent0c04a26b3f8ba70ea686e1a365729835c62c26eb (diff)
downloadrust-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.rs39
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);
+  }
+}