summaryrefslogtreecommitdiffstats
path: root/tests/run-make/raw-dylib-alt-calling-convention
diff options
context:
space:
mode:
Diffstat (limited to 'tests/run-make/raw-dylib-alt-calling-convention')
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/Makefile32
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/driver.rs8
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/extern.c193
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/lib.rs115
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/output.msvc.txt12
-rw-r--r--tests/run-make/raw-dylib-alt-calling-convention/output.txt18
6 files changed, 378 insertions, 0 deletions
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/Makefile b/tests/run-make/raw-dylib-alt-calling-convention/Makefile
new file mode 100644
index 000000000..03f8778d2
--- /dev/null
+++ b/tests/run-make/raw-dylib-alt-calling-convention/Makefile
@@ -0,0 +1,32 @@
+# Test the behavior of #[link(.., kind = "raw-dylib")] with alternative calling conventions.
+
+# only-x86
+# only-windows
+
+include ../../run-make-fulldeps/tools.mk
+
+all:
+ $(RUSTC) --crate-type lib --crate-name raw_dylib_alt_calling_convention_test lib.rs
+ $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
+ $(call COMPILE_OBJ,"$(TMPDIR)"/extern.obj,extern.c)
+ifdef IS_MSVC
+ $(CC) "$(TMPDIR)"/extern.obj -link -dll -out:"$(TMPDIR)"/extern.dll -noimplib
+else
+ $(CC) "$(TMPDIR)"/extern.obj -shared -o "$(TMPDIR)"/extern.dll
+endif
+
+ "$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
+ifdef RUSTC_BLESS_TEST
+ cp "$(TMPDIR)"/output.txt output.txt
+else
+ $(DIFF) output.txt "$(TMPDIR)"/output.txt
+endif
+
+ifdef IS_MSVC
+ "$(TMPDIR)"/driver true > "$(TMPDIR)"/output.msvc.txt
+ifdef RUSTC_BLESS_TEST
+ cp "$(TMPDIR)"/output.msvc.txt output.msvc.txt
+else
+ $(DIFF) output.msvc.txt "$(TMPDIR)"/output.msvc.txt
+endif
+endif
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/driver.rs b/tests/run-make/raw-dylib-alt-calling-convention/driver.rs
new file mode 100644
index 000000000..b7f372c6b
--- /dev/null
+++ b/tests/run-make/raw-dylib-alt-calling-convention/driver.rs
@@ -0,0 +1,8 @@
+extern crate raw_dylib_alt_calling_convention_test;
+
+fn main() {
+ raw_dylib_alt_calling_convention_test::library_function(
+ std::env::args().skip(1).next().map_or(
+ false,
+ |s| std::str::FromStr::from_str(&s).unwrap()));
+}
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/extern.c b/tests/run-make/raw-dylib-alt-calling-convention/extern.c
new file mode 100644
index 000000000..344d4a6bf
--- /dev/null
+++ b/tests/run-make/raw-dylib-alt-calling-convention/extern.c
@@ -0,0 +1,193 @@
+#include <stdio.h>
+#include <stdint.h>
+
+struct S {
+ uint8_t x;
+ int32_t y;
+};
+
+struct S2 {
+ int32_t x;
+ uint8_t y;
+};
+
+struct S3 {
+ uint8_t x[5];
+};
+
+__declspec(dllexport) void __stdcall stdcall_fn_1(int i) {
+ printf("stdcall_fn_1(%d)\n", i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __stdcall stdcall_fn_2(uint8_t i, float f) {
+ printf("stdcall_fn_2(%d, %.1f)\n", i, f);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __stdcall stdcall_fn_3(double d) {
+ printf("stdcall_fn_3(%.1f)\n", d);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __stdcall stdcall_fn_4(uint8_t i, uint8_t j, float f) {
+ printf("stdcall_fn_4(%d, %d, %.1f)\n", i, j, f);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __stdcall stdcall_fn_5(struct S s, int i) {
+ printf("stdcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i);
+ fflush(stdout);
+}
+
+// Test that stdcall support works correctly with the nullable pointer optimization.
+__declspec(dllexport) void __stdcall stdcall_fn_6(struct S* s) {
+ if (s) {
+ printf("stdcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y);
+ } else {
+ printf("stdcall_fn_6(null)\n");
+ }
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __stdcall stdcall_fn_7(struct S2 s, int i) {
+ printf("stdcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i);
+ fflush(stdout);
+}
+
+// Verify that we compute the correct amount of space in the argument list for a 5-byte struct.
+__declspec(dllexport) void __stdcall stdcall_fn_8(struct S3 s, struct S3 t) {
+ printf("stdcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n",
+ s.x[0], s.x[1], s.x[2], s.x[3], s.x[4],
+ t.x[0], t.x[1], t.x[2], t.x[3], t.x[4]
+ );
+ fflush(stdout);
+}
+
+// test whether f64/double values are aligned on 4-byte or 8-byte boundaries.
+__declspec(dllexport) void __stdcall stdcall_fn_9(uint8_t x, double y) {
+ printf("stdcall_fn_9(%d, %.1f)\n", x, y);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __stdcall stdcall_fn_10(int i) {
+ printf("stdcall_fn_10(%d)\n", i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_1(int i) {
+ printf("fastcall_fn_1(%d)\n", i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_2(uint8_t i, float f) {
+ printf("fastcall_fn_2(%d, %.1f)\n", i, f);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_3(double d) {
+ printf("fastcall_fn_3(%.1f)\n", d);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_4(uint8_t i, uint8_t j, float f) {
+ printf("fastcall_fn_4(%d, %d, %.1f)\n", i, j, f);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_5(struct S s, int i) {
+ printf("fastcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_6(struct S* s) {
+ if (s) {
+ printf("fastcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y);
+ } else {
+ printf("fastcall_fn_6(null)\n");
+ }
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_7(struct S2 s, int i) {
+ printf("fastcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_8(struct S3 s, struct S3 t) {
+ printf("fastcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n",
+ s.x[0], s.x[1], s.x[2], s.x[3], s.x[4],
+ t.x[0], t.x[1], t.x[2], t.x[3], t.x[4]
+ );
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_9(uint8_t x, double y) {
+ printf("fastcall_fn_9(%d, %.1f)\n", x, y);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __fastcall fastcall_fn_10(int i) {
+ printf("fastcall_fn_10(%d)\n", i);
+ fflush(stdout);
+}
+
+// GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
+#ifdef _MSC_VER
+__declspec(dllexport) void __vectorcall vectorcall_fn_1(int i) {
+ printf("vectorcall_fn_1(%d)\n", i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_2(uint8_t i, float f) {
+ printf("vectorcall_fn_2(%d, %.1f)\n", i, f);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_3(double d) {
+ printf("vectorcall_fn_3(%.1f)\n", d);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_4(uint8_t i, uint8_t j, float f) {
+ printf("vectorcall_fn_4(%d, %d, %.1f)\n", i, j, f);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_5(struct S s, int i) {
+ printf("vectorcall_fn_5(S { x: %d, y: %d }, %d)\n", s.x, s.y, i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_6(struct S* s) {
+ if (s) {
+ printf("vectorcall_fn_6(S { x: %d, y: %d })\n", s->x, s->y);
+ } else {
+ printf("vectorcall_fn_6(null)\n");
+ }
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_7(struct S2 s, int i) {
+ printf("vectorcall_fn_7(S2 { x: %d, y: %d }, %d)\n", s.x, s.y, i);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_8(struct S3 s, struct S3 t) {
+ printf("vectorcall_fn_8(S3 { x: [%d, %d, %d, %d, %d] }, S3 { x: [%d, %d, %d, %d, %d] })\n",
+ s.x[0], s.x[1], s.x[2], s.x[3], s.x[4],
+ t.x[0], t.x[1], t.x[2], t.x[3], t.x[4]
+ );
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_9(uint8_t x, double y) {
+ printf("vectorcall_fn_9(%d, %.1f)\n", x, y);
+ fflush(stdout);
+}
+
+__declspec(dllexport) void __vectorcall vectorcall_fn_10(int i) {
+ printf("vectorcall_fn_10(%d)\n", i);
+ fflush(stdout);
+}
+#endif
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/lib.rs b/tests/run-make/raw-dylib-alt-calling-convention/lib.rs
new file mode 100644
index 000000000..22f222c12
--- /dev/null
+++ b/tests/run-make/raw-dylib-alt-calling-convention/lib.rs
@@ -0,0 +1,115 @@
+#![feature(abi_vectorcall)]
+#![cfg_attr(target_arch = "x86", feature(raw_dylib))]
+
+#[repr(C)]
+#[derive(Clone)]
+struct S {
+ x: u8,
+ y: i32,
+}
+
+#[repr(C)]
+#[derive(Clone)]
+struct S2 {
+ x: i32,
+ y: u8,
+}
+
+#[repr(C)]
+#[derive(Clone)]
+struct S3 {
+ x: [u8; 5],
+}
+
+#[link(name = "extern", kind = "raw-dylib")]
+extern "stdcall" {
+ fn stdcall_fn_1(i: i32);
+ fn stdcall_fn_2(c: u8, f: f32);
+ fn stdcall_fn_3(d: f64);
+ fn stdcall_fn_4(i: u8, j: u8, f: f32);
+ fn stdcall_fn_5(a: S, b: i32);
+ fn stdcall_fn_6(a: Option<&S>);
+ fn stdcall_fn_7(a: S2, b: i32);
+ fn stdcall_fn_8(a: S3, b: S3);
+ fn stdcall_fn_9(x: u8, y: f64);
+ #[link_name = "stdcall_fn_10"]
+ fn stdcall_fn_10_renamed(i: i32);
+}
+
+#[link(name = "extern", kind = "raw-dylib")]
+extern "fastcall" {
+ fn fastcall_fn_1(i: i32);
+ fn fastcall_fn_2(c: u8, f: f32);
+ fn fastcall_fn_3(d: f64);
+ fn fastcall_fn_4(i: u8, j: u8, f: f32);
+ fn fastcall_fn_5(a: S, b: i32);
+ fn fastcall_fn_6(a: Option<&S>);
+ fn fastcall_fn_7(a: S2, b: i32);
+ fn fastcall_fn_8(a: S3, b: S3);
+ fn fastcall_fn_9(x: u8, y: f64);
+ #[link_name = "fastcall_fn_10"]
+ fn fastcall_fn_10_renamed(i: i32);
+}
+
+#[cfg(target_env = "msvc")]
+#[link(name = "extern", kind = "raw-dylib")]
+extern "vectorcall" {
+ fn vectorcall_fn_1(i: i32);
+ fn vectorcall_fn_2(c: u8, f: f32);
+ fn vectorcall_fn_3(d: f64);
+ fn vectorcall_fn_4(i: u8, j: u8, f: f32);
+ fn vectorcall_fn_5(a: S, b: i32);
+ fn vectorcall_fn_6(a: Option<&S>);
+ fn vectorcall_fn_7(a: S2, b: i32);
+ fn vectorcall_fn_8(a: S3, b: S3);
+ fn vectorcall_fn_9(x: u8, y: f64);
+ #[link_name = "vectorcall_fn_10"]
+ fn vectorcall_fn_10_renamed(i: i32);
+}
+
+pub fn library_function(run_msvc_only: bool) {
+ unsafe {
+ if !run_msvc_only {
+ stdcall_fn_1(14);
+ stdcall_fn_2(16, 3.5);
+ stdcall_fn_3(3.5);
+ stdcall_fn_4(1, 2, 3.0);
+ stdcall_fn_5(S { x: 1, y: 2 }, 16);
+ stdcall_fn_6(Some(&S { x: 10, y: 12 }));
+ stdcall_fn_7(S2 { x: 15, y: 16 }, 3);
+ stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
+ stdcall_fn_9(1, 3.0);
+ stdcall_fn_10_renamed(19);
+
+ fastcall_fn_1(14);
+ fastcall_fn_2(16, 3.5);
+ fastcall_fn_3(3.5);
+ fastcall_fn_4(1, 2, 3.0);
+ fastcall_fn_6(Some(&S { x: 10, y: 12 }));
+ fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
+ fastcall_fn_9(1, 3.0);
+ fastcall_fn_10_renamed(19);
+ } else {
+ // FIXME: 91167
+ // rustc generates incorrect code for the calls to fastcall_fn_5 and fastcall_fn_7
+ // on i686-pc-windows-gnu; disabling these until the indicated issue is fixed.
+ fastcall_fn_5(S { x: 1, y: 2 }, 16);
+ fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
+
+ // GCC doesn't support vectorcall: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89485
+ #[cfg(target_env = "msvc")]
+ {
+ vectorcall_fn_1(14);
+ vectorcall_fn_2(16, 3.5);
+ vectorcall_fn_3(3.5);
+ vectorcall_fn_4(1, 2, 3.0);
+ vectorcall_fn_5(S { x: 1, y: 2 }, 16);
+ vectorcall_fn_6(Some(&S { x: 10, y: 12 }));
+ vectorcall_fn_7(S2 { x: 15, y: 16 }, 3);
+ vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
+ vectorcall_fn_9(1, 3.0);
+ vectorcall_fn_10_renamed(19);
+ }
+ }
+ }
+}
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/output.msvc.txt b/tests/run-make/raw-dylib-alt-calling-convention/output.msvc.txt
new file mode 100644
index 000000000..a216835c4
--- /dev/null
+++ b/tests/run-make/raw-dylib-alt-calling-convention/output.msvc.txt
@@ -0,0 +1,12 @@
+fastcall_fn_5(S { x: 1, y: 2 }, 16)
+fastcall_fn_7(S2 { x: 15, y: 16 }, 3)
+vectorcall_fn_1(14)
+vectorcall_fn_2(16, 3.5)
+vectorcall_fn_3(3.5)
+vectorcall_fn_4(1, 2, 3.0)
+vectorcall_fn_5(S { x: 1, y: 2 }, 16)
+vectorcall_fn_6(S { x: 10, y: 12 })
+vectorcall_fn_7(S2 { x: 15, y: 16 }, 3)
+vectorcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
+vectorcall_fn_9(1, 3.0)
+vectorcall_fn_10(19)
diff --git a/tests/run-make/raw-dylib-alt-calling-convention/output.txt b/tests/run-make/raw-dylib-alt-calling-convention/output.txt
new file mode 100644
index 000000000..7622d3161
--- /dev/null
+++ b/tests/run-make/raw-dylib-alt-calling-convention/output.txt
@@ -0,0 +1,18 @@
+stdcall_fn_1(14)
+stdcall_fn_2(16, 3.5)
+stdcall_fn_3(3.5)
+stdcall_fn_4(1, 2, 3.0)
+stdcall_fn_5(S { x: 1, y: 2 }, 16)
+stdcall_fn_6(S { x: 10, y: 12 })
+stdcall_fn_7(S2 { x: 15, y: 16 }, 3)
+stdcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
+stdcall_fn_9(1, 3.0)
+stdcall_fn_10(19)
+fastcall_fn_1(14)
+fastcall_fn_2(16, 3.5)
+fastcall_fn_3(3.5)
+fastcall_fn_4(1, 2, 3.0)
+fastcall_fn_6(S { x: 10, y: 12 })
+fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
+fastcall_fn_9(1, 3.0)
+fastcall_fn_10(19)