about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-07-23 14:11:25 +0200
committerRalf Jung <post@ralfj.de>2025-07-23 14:19:14 +0200
commitf75595d2cd38e8a0a36ffc18a90fc5b05e290ee3 (patch)
tree68d8e9ece0e53469c63b77b7b1142d2d70172aeb
parenta7a1618e6c835f1f00940ad72203d05808209a0d (diff)
downloadrust-f75595d2cd38e8a0a36ffc18a90fc5b05e290ee3.tar.gz
rust-f75595d2cd38e8a0a36ffc18a90fc5b05e290ee3.zip
add codegen test for variadics (also replacing some existing does-this-build tests)
-rw-r--r--tests/codegen-llvm/cffi/c-variadic-ffi.rs86
-rw-r--r--tests/ui/c-variadic/variadic-ffi-1.rs5
-rw-r--r--tests/ui/c-variadic/variadic-ffi-1.stderr32
-rw-r--r--tests/ui/c-variadic/variadic-ffi-2-arm.rs9
-rw-r--r--tests/ui/c-variadic/variadic-ffi-2.rs28
-rw-r--r--tests/ui/c-variadic/variadic-ffi-2.stderr9
6 files changed, 110 insertions, 59 deletions
diff --git a/tests/codegen-llvm/cffi/c-variadic-ffi.rs b/tests/codegen-llvm/cffi/c-variadic-ffi.rs
new file mode 100644
index 00000000000..3e99c9fb84e
--- /dev/null
+++ b/tests/codegen-llvm/cffi/c-variadic-ffi.rs
@@ -0,0 +1,86 @@
+//! Test calling variadic functions with various ABIs.
+//@ add-core-stubs
+//@ compile-flags: -Z merge-functions=disabled
+//@ revisions: x86_32 x86_32_win x86_64 aarch64 arm32
+//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
+//@[x86_64] needs-llvm-components: x86
+//@[x86_32_win] compile-flags: --target i686-pc-windows-msvc
+//@[x86_32_win] needs-llvm-components: x86
+//@[x86_32] compile-flags: --target i686-unknown-linux-gnu
+//@[x86_32] needs-llvm-components: x86
+//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64] needs-llvm-components: aarch64
+//@[arm32] compile-flags: --target armv7-unknown-linux-gnueabihf
+//@[arm32] needs-llvm-components: arm
+#![crate_type = "lib"]
+#![feature(no_core)]
+#![feature(extended_varargs_abi_support, extern_system_varargs)]
+#![no_core]
+
+extern crate minicore;
+
+// CHECK-LABEL: @c
+#[unsafe(no_mangle)]
+fn c(f: extern "C" fn(i32, ...)) {
+    // CHECK: call void (i32, ...)
+    f(22, 44);
+}
+
+// CHECK-LABEL: @system
+#[unsafe(no_mangle)]
+fn system(f: extern "system" fn(i32, ...)) {
+    // Crucially, this is *always* the C calling convention, even on Windows.
+    // CHECK: call void (i32, ...)
+    f(22, 44);
+}
+
+// x86_32-LABEL: @cdecl
+#[unsafe(no_mangle)]
+#[cfg(target_arch = "x86")]
+fn cdecl(f: extern "cdecl" fn(i32, ...)) {
+    // x86_32: call void (i32, ...)
+    f(22, 44);
+}
+
+// x86_64-LABEL: @sysv
+#[unsafe(no_mangle)]
+#[cfg(target_arch = "x86_64")]
+fn sysv(f: extern "sysv64" fn(i32, ...)) {
+    // x86_64: call x86_64_sysvcc void (i32, ...)
+    f(22, 44);
+}
+
+// x86_64-LABEL: @win
+#[unsafe(no_mangle)]
+#[cfg(target_arch = "x86_64")]
+fn win(f: extern "win64" fn(i32, ...)) {
+    // x86_64: call win64cc void (i32, ...)
+    f(22, 44);
+}
+
+// CHECK-LABEL: @efiapi
+#[unsafe(no_mangle)]
+#[cfg(any(
+    target_arch = "arm",
+    target_arch = "aarch64",
+    target_arch = "riscv32",
+    target_arch = "riscv64",
+    target_arch = "x86",
+    target_arch = "x86_64"
+))]
+fn efiapi(f: extern "efiapi" fn(i32, ...)) {
+    // x86_32: call void (i32, ...)
+    // x86_32_win: call void (i32, ...)
+    // x86_64: call win64cc void (i32, ...)
+    // aarch64: call void (i32, ...)
+    // arm32: call arm_aapcscc void (i32, ...)
+    f(22, 44);
+}
+
+// arm32-LABEL: @aapcs
+#[unsafe(no_mangle)]
+#[cfg(target_arch = "arm")]
+fn aapcs(f: extern "aapcs" fn(i32, ...)) {
+    // arm32: call arm_aapcscc void (i32, ...)
+    f(22, 44);
+}
diff --git a/tests/ui/c-variadic/variadic-ffi-1.rs b/tests/ui/c-variadic/variadic-ffi-1.rs
index cd8f2a951ef..2baa00a079a 100644
--- a/tests/ui/c-variadic/variadic-ffi-1.rs
+++ b/tests/ui/c-variadic/variadic-ffi-1.rs
@@ -12,6 +12,11 @@ extern "stdcall" {
     //~^ ERROR: C-variadic functions with the "stdcall" calling convention are not supported
 }
 
+fn baz(f: extern "Rust" fn(usize, ...)) {
+    //~^ ERROR: C-variadic functions with the "Rust" calling convention are not supported
+    f(22, 44);
+}
+
 extern "C" {
     fn foo(f: isize, x: u8, ...);
 }
diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr
index a49fc0ce126..981b021276d 100644
--- a/tests/ui/c-variadic/variadic-ffi-1.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-1.stderr
@@ -4,14 +4,20 @@ error[E0045]: C-variadic functions with the "stdcall" calling convention are not
 LL |     fn printf(_: *const u8, ...);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
 
+error[E0045]: C-variadic functions with the "Rust" calling convention are not supported
+  --> $DIR/variadic-ffi-1.rs:15:11
+   |
+LL | fn baz(f: extern "Rust" fn(usize, ...)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
 error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
-  --> $DIR/variadic-ffi-1.rs:23:9
+  --> $DIR/variadic-ffi-1.rs:28:9
    |
 LL |         foo();
    |         ^^^-- two arguments of type `isize` and `u8` are missing
    |
 note: function defined here
-  --> $DIR/variadic-ffi-1.rs:16:8
+  --> $DIR/variadic-ffi-1.rs:21:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^ -         -
@@ -21,13 +27,13 @@ LL |         foo(/* isize */, /* u8 */);
    |             +++++++++++++++++++++
 
 error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
-  --> $DIR/variadic-ffi-1.rs:24:9
+  --> $DIR/variadic-ffi-1.rs:29:9
    |
 LL |         foo(1);
    |         ^^^--- argument #2 of type `u8` is missing
    |
 note: function defined here
-  --> $DIR/variadic-ffi-1.rs:16:8
+  --> $DIR/variadic-ffi-1.rs:21:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^           -
@@ -37,7 +43,7 @@ LL |         foo(1, /* u8 */);
    |              ++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-1.rs:26:56
+  --> $DIR/variadic-ffi-1.rs:31:56
    |
 LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
    |                -------------------------------------   ^^^ expected non-variadic fn, found variadic function
@@ -48,7 +54,7 @@ LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
                  found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
 
 error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-1.rs:27:54
+  --> $DIR/variadic-ffi-1.rs:32:54
    |
 LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
    |                -----------------------------------   ^^^ expected variadic fn, found non-variadic function
@@ -59,7 +65,7 @@ LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
                  found fn item `extern "C" fn(_, _) {bar}`
 
 error[E0617]: can't pass `f32` to variadic function
-  --> $DIR/variadic-ffi-1.rs:29:19
+  --> $DIR/variadic-ffi-1.rs:34:19
    |
 LL |         foo(1, 2, 3f32);
    |                   ^^^^
@@ -70,7 +76,7 @@ LL |         foo(1, 2, 3f32 as c_double);
    |                        +++++++++++
 
 error[E0617]: can't pass `bool` to variadic function
-  --> $DIR/variadic-ffi-1.rs:30:19
+  --> $DIR/variadic-ffi-1.rs:35:19
    |
 LL |         foo(1, 2, true);
    |                   ^^^^
@@ -81,7 +87,7 @@ LL |         foo(1, 2, true as c_int);
    |                        ++++++++
 
 error[E0617]: can't pass `i8` to variadic function
-  --> $DIR/variadic-ffi-1.rs:31:19
+  --> $DIR/variadic-ffi-1.rs:36:19
    |
 LL |         foo(1, 2, 1i8);
    |                   ^^^
@@ -92,7 +98,7 @@ LL |         foo(1, 2, 1i8 as c_int);
    |                       ++++++++
 
 error[E0617]: can't pass `u8` to variadic function
-  --> $DIR/variadic-ffi-1.rs:32:19
+  --> $DIR/variadic-ffi-1.rs:37:19
    |
 LL |         foo(1, 2, 1u8);
    |                   ^^^
@@ -103,7 +109,7 @@ LL |         foo(1, 2, 1u8 as c_uint);
    |                       +++++++++
 
 error[E0617]: can't pass `i16` to variadic function
-  --> $DIR/variadic-ffi-1.rs:33:19
+  --> $DIR/variadic-ffi-1.rs:38:19
    |
 LL |         foo(1, 2, 1i16);
    |                   ^^^^
@@ -114,7 +120,7 @@ LL |         foo(1, 2, 1i16 as c_int);
    |                        ++++++++
 
 error[E0617]: can't pass `u16` to variadic function
-  --> $DIR/variadic-ffi-1.rs:34:19
+  --> $DIR/variadic-ffi-1.rs:39:19
    |
 LL |         foo(1, 2, 1u16);
    |                   ^^^^
@@ -124,7 +130,7 @@ help: cast the value to `c_uint`
 LL |         foo(1, 2, 1u16 as c_uint);
    |                        +++++++++
 
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0045, E0060, E0308, E0617.
 For more information about an error, try `rustc --explain E0045`.
diff --git a/tests/ui/c-variadic/variadic-ffi-2-arm.rs b/tests/ui/c-variadic/variadic-ffi-2-arm.rs
deleted file mode 100644
index 3b0a71007a0..00000000000
--- a/tests/ui/c-variadic/variadic-ffi-2-arm.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ only-arm
-//@ build-pass
-#![feature(extended_varargs_abi_support)]
-
-fn aapcs(f: extern "aapcs" fn(usize, ...)) {
-    f(22, 44);
-}
-
-fn main() {}
diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs
deleted file mode 100644
index adfd9bfa279..00000000000
--- a/tests/ui/c-variadic/variadic-ffi-2.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-#![feature(extended_varargs_abi_support)]
-
-fn baz(f: extern "Rust" fn(usize, ...)) {
-    //~^ ERROR: C-variadic functions with the "Rust" calling convention are not supported
-    f(22, 44);
-}
-
-#[cfg(target_arch = "x86_64")]
-fn sysv(f: extern "sysv64" fn(usize, ...)) {
-    f(22, 44);
-}
-#[cfg(target_arch = "x86_64")]
-fn win(f: extern "win64" fn(usize, ...)) {
-    f(22, 44);
-}
-#[cfg(any(
-    target_arch = "arm",
-    target_arch = "aarch64",
-    target_arch = "riscv32",
-    target_arch = "riscv64",
-    target_arch = "x86",
-    target_arch = "x86_64"
-))]
-fn efiapi(f: extern "efiapi" fn(usize, ...)) {
-    f(22, 44);
-}
-
-fn main() {}
diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr
deleted file mode 100644
index 2ac0a9f5ea2..00000000000
--- a/tests/ui/c-variadic/variadic-ffi-2.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0045]: C-variadic functions with the "Rust" calling convention are not supported
-  --> $DIR/variadic-ffi-2.rs:3:11
-   |
-LL | fn baz(f: extern "Rust" fn(usize, ...)) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0045`.