about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRichard Cobbe <ricobbe@microsoft.com>2021-06-08 13:56:06 -0700
committerRichard Cobbe <ricobbe@microsoft.com>2021-07-09 12:04:54 -0700
commita867dd4c7e65beb1453fcff9e252e7ab19f0e1d0 (patch)
treea1f439cc903d02a00ebc1e4120a34b59928df2d7 /src
parent8b87e85394aa583b01e53aef06343dd0749a3324 (diff)
downloadrust-a867dd4c7e65beb1453fcff9e252e7ab19f0e1d0.tar.gz
rust-a867dd4c7e65beb1453fcff9e252e7ab19f0e1d0.zip
Add support for raw-dylib with stdcall, fastcall functions on i686-pc-windows-msvc.
Diffstat (limited to 'src')
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/Makefile18
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/driver.rs5
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/extern.c123
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/lib.rs71
-rw-r--r--src/test/run-make/raw-dylib-alt-calling-convention/output.txt18
-rw-r--r--src/test/run-make/raw-dylib-c/Makefile (renamed from src/test/run-make/raw-dylib/Makefile)3
-rw-r--r--src/test/run-make/raw-dylib-c/driver.rs (renamed from src/test/run-make/raw-dylib/driver.rs)0
-rw-r--r--src/test/run-make/raw-dylib-c/extern_1.c (renamed from src/test/run-make/raw-dylib/extern_1.c)0
-rw-r--r--src/test/run-make/raw-dylib-c/extern_2.c (renamed from src/test/run-make/raw-dylib/extern_2.c)0
-rw-r--r--src/test/run-make/raw-dylib-c/lib.rs (renamed from src/test/run-make/raw-dylib/lib.rs)0
-rw-r--r--src/test/run-make/raw-dylib-c/output.txt (renamed from src/test/run-make/raw-dylib/output.txt)0
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs19
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr17
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs13
-rw-r--r--src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr8
15 files changed, 293 insertions, 2 deletions
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/Makefile b/src/test/run-make/raw-dylib-alt-calling-convention/Makefile
new file mode 100644
index 00000000000..0f874333fa0
--- /dev/null
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/Makefile
@@ -0,0 +1,18 @@
+# Test the behavior of #[link(.., kind = "raw-dylib")] with alternative calling conventions.
+
+# only-i686-pc-windows-msvc
+
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+	$(call COMPILE_OBJ,"$(TMPDIR)"/extern.obj,extern.c)
+	$(CC) "$(TMPDIR)"/extern.obj -link -dll -out:"$(TMPDIR)"/extern.dll
+	$(RUSTC) --crate-type lib --crate-name raw_dylib_alt_calling_convention_test lib.rs
+	$(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)"
+	"$(TMPDIR)"/driver > "$(TMPDIR)"/output.txt
+
+ifdef RUSTC_BLESS_TEST
+	cp "$(TMPDIR)"/output.txt output.txt
+else
+	$(DIFF) output.txt "$(TMPDIR)"/output.txt
+endif
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/driver.rs b/src/test/run-make/raw-dylib-alt-calling-convention/driver.rs
new file mode 100644
index 00000000000..3710507f5e4
--- /dev/null
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/driver.rs
@@ -0,0 +1,5 @@
+extern crate raw_dylib_alt_calling_convention_test;
+
+fn main() {
+    raw_dylib_alt_calling_convention_test::library_function();
+}
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/extern.c b/src/test/run-make/raw-dylib-alt-calling-convention/extern.c
new file mode 100644
index 00000000000..8f64abf2fb5
--- /dev/null
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/extern.c
@@ -0,0 +1,123 @@
+#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 __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);
+}
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs b/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
new file mode 100644
index 00000000000..ba0f1418aba
--- /dev/null
+++ b/src/test/run-make/raw-dylib-alt-calling-convention/lib.rs
@@ -0,0 +1,71 @@
+#![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 = "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);
+}
+
+pub fn library_function() {
+    unsafe {
+        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);
+
+        fastcall_fn_1(14);
+        fastcall_fn_2(16, 3.5);
+        fastcall_fn_3(3.5);
+        fastcall_fn_4(1, 2, 3.0);
+        fastcall_fn_5(S { x: 1, y: 2 }, 16);
+        fastcall_fn_6(Some(&S { x: 10, y: 12 }));
+        fastcall_fn_7(S2 { x: 15, y: 16 }, 3);
+        fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] });
+        fastcall_fn_9(1, 3.0);
+    }
+}
diff --git a/src/test/run-make/raw-dylib-alt-calling-convention/output.txt b/src/test/run-make/raw-dylib-alt-calling-convention/output.txt
new file mode 100644
index 00000000000..be598a22027
--- /dev/null
+++ b/src/test/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)
+fastcall_fn_1(14)
+fastcall_fn_2(16, 3.5)
+fastcall_fn_3(3.5)
+fastcall_fn_4(1, 2, 3.0)
+fastcall_fn_5(S { x: 1, y: 2 }, 16)
+fastcall_fn_6(S { x: 10, y: 12 })
+fastcall_fn_7(S2 { x: 15, y: 16 }, 3)
+fastcall_fn_8(S3 { x: [1, 2, 3, 4, 5] }, S3 { x: [6, 7, 8, 9, 10] })
+fastcall_fn_9(1, 3.0)
diff --git a/src/test/run-make/raw-dylib/Makefile b/src/test/run-make/raw-dylib-c/Makefile
index 7ce46fd9331..26ab4d34764 100644
--- a/src/test/run-make/raw-dylib/Makefile
+++ b/src/test/run-make/raw-dylib-c/Makefile
@@ -1,7 +1,6 @@
 # Test the behavior of #[link(.., kind = "raw-dylib")] on windows-msvc
 
-# only-windows
-# only-msvc
+# only-windows-msvc
 
 -include ../../run-make-fulldeps/tools.mk
 
diff --git a/src/test/run-make/raw-dylib/driver.rs b/src/test/run-make/raw-dylib-c/driver.rs
index 4059ede11fc..4059ede11fc 100644
--- a/src/test/run-make/raw-dylib/driver.rs
+++ b/src/test/run-make/raw-dylib-c/driver.rs
diff --git a/src/test/run-make/raw-dylib/extern_1.c b/src/test/run-make/raw-dylib-c/extern_1.c
index 72737c086eb..72737c086eb 100644
--- a/src/test/run-make/raw-dylib/extern_1.c
+++ b/src/test/run-make/raw-dylib-c/extern_1.c
diff --git a/src/test/run-make/raw-dylib/extern_2.c b/src/test/run-make/raw-dylib-c/extern_2.c
index ae87fc3f821..ae87fc3f821 100644
--- a/src/test/run-make/raw-dylib/extern_2.c
+++ b/src/test/run-make/raw-dylib-c/extern_2.c
diff --git a/src/test/run-make/raw-dylib/lib.rs b/src/test/run-make/raw-dylib-c/lib.rs
index d8e6301f38e..d8e6301f38e 100644
--- a/src/test/run-make/raw-dylib/lib.rs
+++ b/src/test/run-make/raw-dylib-c/lib.rs
diff --git a/src/test/run-make/raw-dylib/output.txt b/src/test/run-make/raw-dylib-c/output.txt
index 7800cba1872..7800cba1872 100644
--- a/src/test/run-make/raw-dylib/output.txt
+++ b/src/test/run-make/raw-dylib-c/output.txt
diff --git a/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs b/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs
new file mode 100644
index 00000000000..3f7597498ba
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.rs
@@ -0,0 +1,19 @@
+// only-i686-pc-windows-msvc
+// compile-flags: --crate-type lib --emit link
+#![allow(clashing_extern_declarations)]
+#![feature(raw_dylib)]
+//~^ WARN the feature `raw_dylib` is incomplete
+#[link(name = "foo", kind = "raw-dylib")]
+extern "C" {
+    fn f(x: i32);
+    //~^ ERROR multiple definitions of external function `f` from library `foo.dll` have different calling conventions
+}
+
+pub fn lib_main() {
+    #[link(name = "foo", kind = "raw-dylib")]
+    extern "stdcall" {
+        fn f(x: i32);
+    }
+
+    unsafe { f(42); }
+}
diff --git a/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr b/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr
new file mode 100644
index 00000000000..91f6f0cf722
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/multiple-definitions.stderr
@@ -0,0 +1,17 @@
+warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/multiple-definitions.rs:4:12
+   |
+LL | #![feature(raw_dylib)]
+   |            ^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+   = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
+
+error: multiple definitions of external function `f` from library `foo.dll` have different calling conventions
+  --> $DIR/multiple-definitions.rs:8:5
+   |
+LL |     fn f(x: i32);
+   |     ^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs
new file mode 100644
index 00000000000..e5a5ac2eb2b
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.rs
@@ -0,0 +1,13 @@
+// only-x86_64-pc-windows-msvc
+// compile-flags: --crate-type lib --emit link
+#![allow(incomplete_features)]
+#![feature(raw_dylib)]
+#[link(name = "foo", kind = "raw-dylib")]
+extern "stdcall" {
+    fn f(x: i32);
+    //~^ ERROR ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
+}
+
+pub fn lib_main() {
+    unsafe { f(42); }
+}
diff --git a/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr
new file mode 100644
index 00000000000..fc9008128ae
--- /dev/null
+++ b/src/test/ui/rfc-2627-raw-dylib/unsupported-abi.stderr
@@ -0,0 +1,8 @@
+error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
+  --> $DIR/unsupported-abi.rs:7:5
+   |
+LL |     fn f(x: i32);
+   |     ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+