Rollup merge of #144359 - RalfJung:vararg-codegen, r=compiler-errors
add codegen test for variadics This is a part of https://github.com/rust-lang/rust/pull/144066 that can land without FCP.
This commit is contained in:
commit
e2c2d1a493
6 changed files with 110 additions and 59 deletions
86
tests/codegen-llvm/cffi/c-variadic-ffi.rs
Normal file
86
tests/codegen-llvm/cffi/c-variadic-ffi.rs
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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, ...);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue