diff options
Diffstat (limited to 'tests/ui/abi/foreign')
-rw-r--r-- | tests/ui/abi/foreign/auxiliary/foreign_lib.rs | 37 | ||||
-rw-r--r-- | tests/ui/abi/foreign/foreign-call-no-runtime.rs | 60 | ||||
-rw-r--r-- | tests/ui/abi/foreign/foreign-dupe.rs | 17 | ||||
-rw-r--r-- | tests/ui/abi/foreign/foreign-fn-with-byval.rs | 30 | ||||
-rw-r--r-- | tests/ui/abi/foreign/foreign-no-abi.rs | 22 | ||||
-rw-r--r-- | tests/ui/abi/foreign/invoke-external-foreign.rs | 17 |
6 files changed, 183 insertions, 0 deletions
diff --git a/tests/ui/abi/foreign/auxiliary/foreign_lib.rs b/tests/ui/abi/foreign/auxiliary/foreign_lib.rs new file mode 100644 index 000000000..3c649b778 --- /dev/null +++ b/tests/ui/abi/foreign/auxiliary/foreign_lib.rs @@ -0,0 +1,37 @@ +#![crate_name = "foreign_lib"] +#![feature(rustc_private)] + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern "C" { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt2 { + extern crate libc; + + extern "C" { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern "C" { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} diff --git a/tests/ui/abi/foreign/foreign-call-no-runtime.rs b/tests/ui/abi/foreign/foreign-call-no-runtime.rs new file mode 100644 index 000000000..d5b90a359 --- /dev/null +++ b/tests/ui/abi/foreign/foreign-call-no-runtime.rs @@ -0,0 +1,60 @@ +// run-pass +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; + +use std::mem; +use std::thread; + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), data: libc::uintptr_t) -> libc::uintptr_t; +} + +pub fn main() { + unsafe { + thread::spawn(move || { + let i: isize = 100; + rust_dbg_call(callback_isize, mem::transmute(&i)); + }) + .join() + .unwrap(); + + thread::spawn(move || { + let i: i32 = 100; + rust_dbg_call(callback_i32, mem::transmute(&i)); + }) + .join() + .unwrap(); + + thread::spawn(move || { + let i: i64 = 100; + rust_dbg_call(callback_i64, mem::transmute(&i)); + }) + .join() + .unwrap(); + } +} + +extern "C" fn callback_isize(data: libc::uintptr_t) { + unsafe { + let data: *const isize = mem::transmute(data); + assert_eq!(*data, 100); + } +} + +extern "C" fn callback_i64(data: libc::uintptr_t) { + unsafe { + let data: *const i64 = mem::transmute(data); + assert_eq!(*data, 100); + } +} + +extern "C" fn callback_i32(data: libc::uintptr_t) { + unsafe { + let data: *const i32 = mem::transmute(data); + assert_eq!(*data, 100); + } +} diff --git a/tests/ui/abi/foreign/foreign-dupe.rs b/tests/ui/abi/foreign/foreign-dupe.rs new file mode 100644 index 000000000..3c9f0f583 --- /dev/null +++ b/tests/ui/abi/foreign/foreign-dupe.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:foreign_lib.rs +// ignore-wasm32-bare no libc to test ffi with + +// Check that we can still call duplicated extern (imported) functions +// which were declared in another crate. See issues #32740 and #32783. + + +extern crate foreign_lib; + +pub fn main() { + unsafe { + let x = foreign_lib::rustrt::rust_get_test_int(); + assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int()); + } +} diff --git a/tests/ui/abi/foreign/foreign-fn-with-byval.rs b/tests/ui/abi/foreign/foreign-fn-with-byval.rs new file mode 100644 index 000000000..f366b6ee1 --- /dev/null +++ b/tests/ui/abi/foreign/foreign-fn-with-byval.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct S { + x: u64, + y: u64, + z: u64, +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn get_x(x: S) -> u64; + pub fn get_y(x: S) -> u64; + pub fn get_z(x: S) -> u64; +} + +#[inline(never)] +fn indirect_call(func: unsafe extern "C" fn(s: S) -> u64, s: S) -> u64 { + unsafe { func(s) } +} + +fn main() { + let s = S { x: 1, y: 2, z: 3 }; + assert_eq!(s.x, indirect_call(get_x, s)); + assert_eq!(s.y, indirect_call(get_y, s)); + assert_eq!(s.z, indirect_call(get_z, s)); +} diff --git a/tests/ui/abi/foreign/foreign-no-abi.rs b/tests/ui/abi/foreign/foreign-no-abi.rs new file mode 100644 index 000000000..3f4f70c99 --- /dev/null +++ b/tests/ui/abi/foreign/foreign-no-abi.rs @@ -0,0 +1,22 @@ +// run-pass +// ABI is cdecl by default + +// ignore-wasm32-bare no libc to test ffi with +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern "C" { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub fn main() { + unsafe { + rustrt::rust_get_test_int(); + } +} diff --git a/tests/ui/abi/foreign/invoke-external-foreign.rs b/tests/ui/abi/foreign/invoke-external-foreign.rs new file mode 100644 index 000000000..dbd2b4ad8 --- /dev/null +++ b/tests/ui/abi/foreign/invoke-external-foreign.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:foreign_lib.rs +// ignore-wasm32-bare no libc to test ffi with + +// The purpose of this test is to check that we can +// successfully (and safely) invoke external, cdecl +// functions from outside the crate. + +// pretty-expanded FIXME #23616 + +extern crate foreign_lib; + +pub fn main() { + unsafe { + let _foo = foreign_lib::rustrt::rust_get_test_int(); + } +} |