From f75595d2cd38e8a0a36ffc18a90fc5b05e290ee3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 23 Jul 2025 14:11:25 +0200 Subject: [PATCH] add codegen test for variadics (also replacing some existing does-this-build tests) --- tests/codegen-llvm/cffi/c-variadic-ffi.rs | 86 +++++++++++++++++++++++ tests/ui/c-variadic/variadic-ffi-1.rs | 5 ++ tests/ui/c-variadic/variadic-ffi-1.stderr | 32 +++++---- tests/ui/c-variadic/variadic-ffi-2-arm.rs | 9 --- tests/ui/c-variadic/variadic-ffi-2.rs | 28 -------- tests/ui/c-variadic/variadic-ffi-2.stderr | 9 --- 6 files changed, 110 insertions(+), 59 deletions(-) create mode 100644 tests/codegen-llvm/cffi/c-variadic-ffi.rs delete mode 100644 tests/ui/c-variadic/variadic-ffi-2-arm.rs delete mode 100644 tests/ui/c-variadic/variadic-ffi-2.rs delete mode 100644 tests/ui/c-variadic/variadic-ffi-2.stderr 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 0000000000000..3e99c9fb84e42 --- /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 cd8f2a951ef89..2baa00a079a42 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 a49fc0ce12603..981b021276d20 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 3b0a71007a0e6..0000000000000 --- 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 adfd9bfa27962..0000000000000 --- 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 2ac0a9f5ea2cf..0000000000000 --- 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`.