File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -761,7 +761,8 @@ 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+ let target = & self . sess . target ;
765+ if !target. arch . supports_c_variadic_definitions ( & target. abi ) {
765766 self . dcx ( ) . emit_err ( errors:: CVariadicNotSupported {
766767 variadic_span : variadic_param. span ,
767768 target : & * self . sess . target . llvm_target ,
Original file line number Diff line number Diff 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}
Original file line number Diff line number Diff line change @@ -1939,16 +1939,25 @@ impl Arch {
19391939 }
19401940 }
19411941
1942- pub fn supports_c_variadic_definitions ( & self ) -> bool {
1942+ pub fn supports_c_variadic_definitions ( & self , abi : & Abi ) -> bool {
19431943 use Arch :: * ;
19441944
19451945 match self {
1946+ // The c-variadic ABI for this target may change in the future, per this comment in
1947+ // clang:
1948+ //
1949+ // > To be compatible with GCC's behaviors, we force arguments with
1950+ // > 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`,
1951+ // > `unsigned long long` and `double` to have 4-byte alignment. This
1952+ // > behavior may be changed when RV32E/ILP32E is ratified.
1953+ RiscV32 if * abi == Abi :: Ilp32e => false ,
1954+
19461955 // These targets just do not support c-variadic definitions.
19471956 Bpf | SpirV => false ,
19481957
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 ,
1958+ // We don't know how c-variadics work for this target. Using the default LLVM
1959+ // fallback implementation may work, but just to be safe we disallow this .
1960+ Other ( _) => false ,
19521961
19531962 AArch64 | AmdGpu | Arm | Arm64EC | Avr | CSky | Hexagon | LoongArch32 | LoongArch64
19541963 | M68k | Mips | Mips32r6 | Mips64 | Mips64r6 | Msp430 | Nvptx64 | PowerPC
You can’t perform that action at this time.
0 commit comments