From eea6149e03401c4a94a213112fb0694e3f44991b Mon Sep 17 00:00:00 2001 From: Soveu Date: Thu, 14 Sep 2023 23:21:39 +0200 Subject: [PATCH] Enable varargs support for AAPCS calling convention This is the default calling convention for ARM - it is used for extern "C", therefore it supports varargs. --- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_target/src/spec/abi.rs | 3 ++- tests/ui/c-variadic/variadic-ffi-2.rs | 5 ++++- tests/ui/c-variadic/variadic-ffi-2.stderr | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index b0f333b79ca..ef788935efb 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -117,7 +117,7 @@ fluent_messages! { "../messages.ftl" } fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) { - const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`"; + const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `aapcs`, `win64`, `sysv64` or `efiapi`"; const CONVENTIONS_STABLE: &str = "`C` or `cdecl`"; const UNSTABLE_EXPLAIN: &str = "using calling conventions other than `C` or `cdecl` for varargs functions is unstable"; diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index 956a5cb5c2f..a99cccd42c4 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -68,7 +68,7 @@ pub enum Abi { impl Abi { pub fn supports_varargs(self) -> bool { // * C and Cdecl obviously support varargs. - // * C can be based on SysV64 or Win64, so they must support varargs. + // * C can be based on Aapcs, SysV64 or Win64, so they must support varargs. // * EfiApi is based on Win64 or C, so it also supports it. // // * Stdcall does not, because it would be impossible for the callee to clean @@ -79,6 +79,7 @@ pub fn supports_varargs(self) -> bool { match self { Self::C { .. } | Self::Cdecl { .. } + | Self::Aapcs { .. } | Self::Win64 { .. } | Self::SysV64 { .. } | Self::EfiApi => true, diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs index c34b7e55f6a..67a0a9a1dec 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.rs +++ b/tests/ui/c-variadic/variadic-ffi-2.rs @@ -3,10 +3,13 @@ fn baz(f: extern "stdcall" fn(usize, ...)) { //~^ ERROR: C-variadic function must have a compatible calling convention, - // like C, cdecl, win64, sysv64 or efiapi + // like C, cdecl, aapcs, win64, sysv64 or efiapi f(22, 44); } +fn aapcs(f: extern "aapcs" fn(usize, ...)) { + f(22, 44); +} fn sysv(f: extern "sysv64" fn(usize, ...)) { f(22, 44); } diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr index e21001ecaf8..8884fc6fb2a 100644 --- a/tests/ui/c-variadic/variadic-ffi-2.stderr +++ b/tests/ui/c-variadic/variadic-ffi-2.stderr @@ -1,4 +1,4 @@ -error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `win64`, `sysv64` or `efiapi` +error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `aapcs`, `win64`, `sysv64` or `efiapi` --> $DIR/variadic-ffi-2.rs:4:11 | LL | fn baz(f: extern "stdcall" fn(usize, ...)) {