summaryrefslogtreecommitdiffstats
path: root/tests/ui/abi/foreign
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/abi/foreign')
-rw-r--r--tests/ui/abi/foreign/auxiliary/foreign_lib.rs37
-rw-r--r--tests/ui/abi/foreign/foreign-call-no-runtime.rs60
-rw-r--r--tests/ui/abi/foreign/foreign-dupe.rs17
-rw-r--r--tests/ui/abi/foreign/foreign-fn-with-byval.rs30
-rw-r--r--tests/ui/abi/foreign/foreign-no-abi.rs22
-rw-r--r--tests/ui/abi/foreign/invoke-external-foreign.rs17
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();
+ }
+}