@@ -3,7 +3,8 @@ use std::ffi::c_uint;
33use std:: { assert_matches, iter, ptr} ;
44
55use rustc_abi:: {
6- Align , BackendRepr , Float , HasDataLayout , NumScalableVectors , Primitive , Size , WrappingRange ,
6+ Align , BackendRepr , Float , HasDataLayout , Integer , NumScalableVectors , Primitive , Size ,
7+ WrappingRange ,
78} ;
89use rustc_codegen_ssa:: base:: { compare_simd_types, wants_msvc_seh, wants_wasm_eh} ;
910use rustc_codegen_ssa:: common:: { IntPredicate , TypeKind } ;
@@ -288,10 +289,17 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
288289 bug ! ( "the va_arg intrinsic does not support non-scalar types" )
289290 } ;
290291
292+ // We reject types that would never be passed as varargs in C because
293+ // they get promoted to a larger type, specifically integers smaller than
294+ // c_int and float type smaller than c_double.
291295 match scalar. primitive ( ) {
292296 Primitive :: Pointer ( _) => {
293297 // Pointers are always OK.
294- emit_va_arg ( self , args[ 0 ] , result. layout . ty )
298+ }
299+ Primitive :: Int ( Integer :: I128 , _) => {
300+ // FIXME: maybe we should support these? At least on 32-bit powerpc
301+ // the logic in LLVM does not handle i128 correctly though.
302+ bug ! ( "the va_arg intrinsic does not support `i128`/`u128`" )
295303 }
296304 Primitive :: Int ( ..) => {
297305 let int_width = self . cx ( ) . size_of ( result. layout . ty ) . bits ( ) ;
@@ -305,27 +313,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
305313 target_c_int_width
306314 ) ;
307315 }
308- emit_va_arg ( self , args[ 0 ] , result. layout . ty )
309316 }
310317 Primitive :: Float ( Float :: F16 ) => {
311318 bug ! ( "the va_arg intrinsic does not support `f16`" )
312319 }
313320 Primitive :: Float ( Float :: F32 ) => {
314- if self . cx ( ) . sess ( ) . target . arch == Arch :: Avr {
315- // c_double is actually f32 on avr.
316- emit_va_arg ( self , args[ 0 ] , result. layout . ty )
317- } else {
321+ // c_double is actually f32 on avr.
322+ if self . cx ( ) . sess ( ) . target . arch != Arch :: Avr {
318323 bug ! ( "the va_arg intrinsic does not support `f32` on this target" )
319324 }
320325 }
321326 Primitive :: Float ( Float :: F64 ) => {
322327 // 64-bit floats are always OK.
323- emit_va_arg ( self , args[ 0 ] , result. layout . ty )
324328 }
325329 Primitive :: Float ( Float :: F128 ) => {
330+ // FIXME(f128) figure out whether we should support this.
326331 bug ! ( "the va_arg intrinsic does not support `f128`" )
327332 }
328333 }
334+
335+ emit_va_arg ( self , args[ 0 ] , result. layout . ty )
329336 }
330337
331338 sym:: volatile_load | sym:: unaligned_volatile_load => {
0 commit comments