@@ -371,7 +371,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
371371
372372 ( fixed_count, self . tcx . mk_type_list_from_iter ( extra_tys) )
373373 } else {
374- ( caller_fn_abi. args . len ( ) , ty:: List :: empty ( ) )
374+ ( caller_fn_abi. fixed_count . try_into ( ) . unwrap ( ) , ty:: List :: empty ( ) )
375375 } ;
376376
377377 let callee_fn_abi = self . fn_abi_of_instance ( instance, callee_c_variadic_args) ?;
@@ -393,7 +393,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
393393 } ) ;
394394 }
395395
396- if caller_fn_abi. fixed_count != callee_fn_abi. fixed_count {
396+ if caller_fn_abi. c_variadic && caller_fn_abi . fixed_count != callee_fn_abi. fixed_count {
397397 throw_ub ! ( CVariadicFixedCountMismatch {
398398 caller: caller_fn_abi. fixed_count,
399399 callee: callee_fn_abi. fixed_count,
@@ -472,12 +472,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
472472 // `pass_argument` would be the loop body. It takes care to
473473 // not advance `caller_iter` for ignored arguments.
474474 let mut callee_args_abis = if caller_fn_abi. c_variadic {
475- // Only the fixed arguments are passed normally.
475+ // Only the fixed arguments are passed normally. C-variadic functions cannot be
476+ // `extern "Rust"` and `#[track_caller]` can only be applied to `extern "Rust"`, to
477+ // the extra caller location argument is not relevant here.
478+ assert ! ( !instance. def. requires_caller_location( * self . tcx) ) ;
476479 callee_fn_abi. args [ ..fixed_count] . iter ( ) . enumerate ( )
477480 } else {
478- // NOTE: this handles the extra caller location argument
479- // when `#[track_caller]` is used. This attribute is only allowed on `extern "Rust"`
480- // functions, so the c-variadic case does not need to handle the extra argument.
481+ // NOTE: this handles the extra caller location argument that is passed when
482+ // `#[track_caller]` is used. The `fixed_count` does not account for this argument.
483+ // This attribute is only allowed on `extern "Rust"` functions, so the c-variadic
484+ // case does not need to handle the extra argument.
481485 callee_fn_abi. args . iter ( ) . enumerate ( )
482486 } ;
483487
@@ -501,7 +505,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
501505 // Consume the remaining arguments by putting them into the variable argument
502506 // list.
503507 let varargs = self . allocate_varargs ( & mut caller_args) ?;
504- let key = self . va_list_ptr ( varargs) ;
508+ // When the frame is dropped, these variable arguments are deallocated.
509+ self . frame_mut ( ) . va_list = varargs. clone ( ) ;
510+ let key = self . va_list_ptr ( varargs. into ( ) ) ;
505511
506512 // Zero the VaList, so it is fully initialized.
507513 self . write_bytes_ptr (
0 commit comments