Rollup merge of #119587 - beepster4096:system_varargs, r=petrochenkov
Varargs support for system ABI This PR allows functions with the `system` ABI to be variadic (under the `extended_varargs_abi_support` feature tracked in #100189). On x86 windows, the `system` ABI is equivalent to `C` for variadic functions. On other platforms, `system` is already equivalent to `C`. Fixes #110505
This commit is contained in:
commit
7b507db24b
8 changed files with 34 additions and 13 deletions
|
@ -840,7 +840,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||
"sparc" => sparc::compute_abi_info(cx, self),
|
||||
"sparc64" => sparc64::compute_abi_info(cx, self),
|
||||
"nvptx64" => {
|
||||
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
|
||||
if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::PtxKernel {
|
||||
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
||||
} else {
|
||||
nvptx64::compute_abi_info(self)
|
||||
|
@ -849,7 +849,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
|
|||
"hexagon" => hexagon::compute_abi_info(self),
|
||||
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
|
||||
"wasm32" | "wasm64" => {
|
||||
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::Wasm {
|
||||
if cx.target_spec().adjust_abi(abi, self.c_variadic) == spec::abi::Abi::Wasm {
|
||||
wasm::compute_wasm_abi_info(self)
|
||||
} else {
|
||||
wasm::compute_c_abi_info(cx, self)
|
||||
|
|
|
@ -70,15 +70,16 @@ impl Abi {
|
|||
// * C and Cdecl obviously 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.
|
||||
// * System falls back to C for functions with varargs.
|
||||
//
|
||||
// * Stdcall does not, because it would be impossible for the callee to clean
|
||||
// up the arguments. (callee doesn't know how many arguments are there)
|
||||
// * Same for Fastcall, Vectorcall and Thiscall.
|
||||
// * System can become Stdcall, so is also a no-no.
|
||||
// * Other calling conventions are related to hardware or the compiler itself.
|
||||
match self {
|
||||
Self::C { .. }
|
||||
| Self::Cdecl { .. }
|
||||
| Self::System { .. }
|
||||
| Self::Aapcs { .. }
|
||||
| Self::Win64 { .. }
|
||||
| Self::SysV64 { .. }
|
||||
|
|
|
@ -2401,10 +2401,14 @@ impl DerefMut for Target {
|
|||
|
||||
impl Target {
|
||||
/// Given a function ABI, turn it into the correct ABI for this target.
|
||||
pub fn adjust_abi(&self, abi: Abi) -> Abi {
|
||||
pub fn adjust_abi(&self, abi: Abi, c_variadic: bool) -> Abi {
|
||||
match abi {
|
||||
Abi::C { .. } => self.default_adjusted_cabi.unwrap_or(abi),
|
||||
Abi::System { unwind } if self.is_like_windows && self.arch == "x86" => {
|
||||
|
||||
// On Windows, `extern "system"` behaves like msvc's `__stdcall`.
|
||||
// `__stdcall` only applies on x86 and on non-variadic functions:
|
||||
// https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
|
||||
Abi::System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => {
|
||||
Abi::Stdcall { unwind }
|
||||
}
|
||||
Abi::System { unwind } => Abi::C { unwind },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue