diff options
| author | bors <bors@rust-lang.org> | 2025-08-21 22:57:46 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-08-21 22:57:46 +0000 |
| commit | 8e3710ef31a0b2cdf5a1c2f3929b7735d1e28c20 (patch) | |
| tree | fd4b586c55cb9c9d40c84180d4ece8c70110963e /tests/ui/c-variadic/same-program-multiple-abis-arm.rs | |
| parent | 6ba0ce40941eee1ca02e9ba49c791ada5158747a (diff) | |
| parent | 7d2993daf3866947877e285d99235a00332a4e99 (diff) | |
| download | rust-8e3710ef31a0b2cdf5a1c2f3929b7735d1e28c20.tar.gz rust-8e3710ef31a0b2cdf5a1c2f3929b7735d1e28c20.zip | |
Auto merge of #145728 - jhpratt:rollup-nwbw8de, r=jhpratt
Rollup of 16 pull requests Successful merges: - rust-lang/rust#137494 (libstd: init(): dup() subsequent /dev/nulls instead of opening them again) - rust-lang/rust#144541 (c-variadic: multiple ABIs in the same program for arm) - rust-lang/rust#144613 (aarch64-nintendo-switch-freestanding - Enable CPU features that are always available in a live system (crypto instructions, plus explicit NEON).) - rust-lang/rust#144780 (Add a method to dump MIR in the middle of MIR building) - rust-lang/rust#145137 (Consolidate panicking functions in `slice/index.rs`) - rust-lang/rust#145507 (Refactor attribute parsing to improve ergonomics and some diagnostics) - rust-lang/rust#145604 (Gate static closures behind a parser feature) - rust-lang/rust#145648 (Add two tidy dependency checks) - rust-lang/rust#145661 (update some s390x codegen tests) - rust-lang/rust#145672 (Instantiate higher-ranked binder with erased when checking `IntoIterator` predicate for query instability) - rust-lang/rust#145689 (Migrate `panic_unwind` to use `cfg_select!`) - rust-lang/rust#145700 (Handle `ReEarlyParam` in `type_name`.) - rust-lang/rust#145703 (Remove MIPS targets from CI LLVM platforms) - rust-lang/rust#145704 (ci: don't cleanup windows disk) - rust-lang/rust#145705 (remove an `as` cast in prefetch codegen) - rust-lang/rust#145712 (Update outdated link in bound region comments) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'tests/ui/c-variadic/same-program-multiple-abis-arm.rs')
| -rw-r--r-- | tests/ui/c-variadic/same-program-multiple-abis-arm.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs new file mode 100644 index 00000000000..1b0bdecabfb --- /dev/null +++ b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs @@ -0,0 +1,77 @@ +#![feature(extended_varargs_abi_support)] +//@ run-pass +//@ only-arm +//@ ignore-thumb (this test uses arm assembly) +//@ only-eabihf (the assembly below requires float hardware support) + +// Check that multiple c-variadic calling conventions can be used in the same program. +// +// Clang and gcc reject defining functions with a non-default calling convention and a variable +// argument list, so C programs that use multiple c-variadic calling conventions are unlikely +// to come up. Here we validate that our codegen backends do in fact generate correct code. + +extern "C" { + fn variadic_c(_: f64, _: ...) -> f64; +} + +extern "aapcs" { + fn variadic_aapcs(_: f64, _: ...) -> f64; +} + +fn main() { + unsafe { + assert_eq!(variadic_c(1.0, 2.0, 3.0), 1.0 + 2.0 + 3.0); + assert_eq!(variadic_aapcs(1.0, 2.0, 3.0), 1.0 + 2.0 + 3.0); + } +} + +// This assembly was generated using https://godbolt.org/z/xcW6a1Tj5, and corresponds to the +// following code compiled for the `armv7-unknown-linux-gnueabihf` target: +// +// ```rust +// #![feature(c_variadic)] +// +// #[unsafe(no_mangle)] +// unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { +// let b = args.arg::<f64>(); +// let c = args.arg::<f64>(); +// +// a + b + c +// } +// ``` +// +// This function uses floats (and passes one normal float argument) because the aapcs and C calling +// conventions differ in how floats are passed, e.g. https://godbolt.org/z/sz799f51x. However, for +// c-variadic functions, both ABIs actually behave the same, based on: +// +// https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst#65parameter-passing +// +// > A variadic function is always marshaled as for the base standard. +// +// https://github.com/ARM-software/abi-aa/blob/main/aapcs32/aapcs32.rst#7the-standard-variants +// +// > This section applies only to non-variadic functions. For a variadic function the base standard +// > is always used both for argument passing and result return. +core::arch::global_asm!( + r#" +{variadic_c}: +{variadic_aapcs}: + sub sp, sp, #12 + stmib sp, {{r2, r3}} + vmov d0, r0, r1 + add r0, sp, #4 + vldr d1, [sp, #4] + add r0, r0, #15 + bic r0, r0, #7 + vadd.f64 d0, d0, d1 + add r1, r0, #8 + str r1, [sp] + vldr d1, [r0] + vadd.f64 d0, d0, d1 + vmov r0, r1, d0 + add sp, sp, #12 + bx lr + "#, + variadic_c = sym variadic_c, + variadic_aapcs = sym variadic_aapcs, +); |
