Skip to content

Commit a47bdd2

Browse files
committed
c-variadic: error when we can't guarantee that the backend does the right thing
1 parent b2fabe3 commit a47bdd2

3 files changed

Lines changed: 32 additions & 22 deletions

File tree

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ impl<'a> AstValidator<'a> {
761761
match fn_ctxt {
762762
FnCtxt::Foreign => return,
763763
FnCtxt::Free | FnCtxt::Assoc(_) => {
764-
if !self.sess.target.arch.supports_c_variadic_definitions() {
764+
if !self.sess.target.supports_c_variadic_definitions() {
765765
self.dcx().emit_err(errors::CVariadicNotSupported {
766766
variadic_span: variadic_param.span,
767767
target: &*self.sess.target.llvm_target,

compiler/rustc_codegen_llvm/src/va_arg.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,9 +1186,10 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
11861186
// Clang uses the LLVM implementation for these architectures.
11871187
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))
11881188
}
1189-
Arch::Other(_) => {
1190-
// For custom targets, use the LLVM va_arg instruction as a fallback.
1191-
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))
1189+
Arch::Other(ref arch) => {
1190+
// Just to be safe we error out explicitly here, instead of crossing our fingers that
1191+
// the default LLVM implementation has the correct behavior for this target.
1192+
bug!("c-variadic functions are not currently implemented for custom target {arch}")
11921193
}
11931194
}
11941195
}

compiler/rustc_target/src/spec/mod.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,24 +1939,6 @@ impl Arch {
19391939
}
19401940
}
19411941

1942-
pub fn supports_c_variadic_definitions(&self) -> bool {
1943-
use Arch::*;
1944-
1945-
match self {
1946-
// These targets just do not support c-variadic definitions.
1947-
Bpf | SpirV => false,
1948-
1949-
// We don't know if the target supports c-variadic definitions, but we don't want
1950-
// to needlessly restrict custom target.json configurations.
1951-
Other(_) => true,
1952-
1953-
AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64
1954-
| M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC
1955-
| PowerPC64 | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32 | Wasm64 | X86
1956-
| X86_64 | Xtensa => true,
1957-
}
1958-
}
1959-
19601942
/// Whether `#[rustc_scalable_vector]` is supported for a target architecture
19611943
pub fn supports_scalable_vectors(&self) -> bool {
19621944
use Arch::*;
@@ -2170,6 +2152,33 @@ impl Target {
21702152

21712153
Ok(dl)
21722154
}
2155+
2156+
pub fn supports_c_variadic_definitions(&self) -> bool {
2157+
use Arch::*;
2158+
2159+
match self.arch {
2160+
// The c-variadic ABI for this target may change in the future, per this comment in
2161+
// clang:
2162+
//
2163+
// > To be compatible with GCC's behaviors, we force arguments with
2164+
// > 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`,
2165+
// > `unsigned long long` and `double` to have 4-byte alignment. This
2166+
// > behavior may be changed when RV32E/ILP32E is ratified.
2167+
RiscV32 if self.llvm_abiname == "ilp32e" => false,
2168+
2169+
// These targets just do not support c-variadic definitions.
2170+
Bpf | SpirV => false,
2171+
2172+
// We don't know how c-variadics work for this target. Using the default LLVM
2173+
// fallback implementation may work, but just to be safe we disallow this.
2174+
Other(_) => false,
2175+
2176+
AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64
2177+
| M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC
2178+
| PowerPC64 | RiscV32 | RiscV64 | S390x | Sparc | Sparc64 | Wasm32 | Wasm64 | X86
2179+
| X86_64 | Xtensa => true,
2180+
}
2181+
}
21732182
}
21742183

21752184
pub trait HasTargetSpec {

0 commit comments

Comments
 (0)