@@ -704,6 +704,7 @@ where
704704 // wrong type.
705705
706706 let tcx = * self . tcx ;
707+ let will_later_validate = M :: enforce_validity ( self , layout) ;
707708 let Some ( mut alloc) = self . get_place_alloc_mut ( & MPlaceTy { mplace : dest, layout } ) ? else {
708709 // zero-sized access
709710 return interp_ok ( ( ) ) ;
@@ -714,23 +715,31 @@ where
714715 alloc. write_scalar ( alloc_range ( Size :: ZERO , scalar. size ( ) ) , scalar) ?;
715716 }
716717 Immediate :: ScalarPair ( a_val, b_val) => {
717- let BackendRepr :: ScalarPair ( a , b) = layout. backend_repr else {
718+ let BackendRepr :: ScalarPair ( _a , b) = layout. backend_repr else {
718719 span_bug ! (
719720 self . cur_span( ) ,
720721 "write_immediate_to_mplace: invalid ScalarPair layout: {:#?}" ,
721722 layout
722723 )
723724 } ;
724- let b_offset = a. size ( & tcx) . align_to ( b. align ( & tcx) . abi ) ;
725+ let a_size = a_val. size ( ) ;
726+ let b_offset = a_size. align_to ( b. align ( & tcx) . abi ) ;
725727 assert ! ( b_offset. bytes( ) > 0 ) ; // in `operand_field` we use the offset to tell apart the fields
726728
727729 // It is tempting to verify `b_offset` against `layout.fields.offset(1)`,
728730 // but that does not work: We could be a newtype around a pair, then the
729731 // fields do not match the `ScalarPair` components.
730732
731- alloc. write_scalar ( alloc_range ( Size :: ZERO , a_val. size ( ) ) , a_val) ?;
733+ // In preparation, if we do *not* later reset the padding, we clear the entire
734+ // destination now to ensure that no stray pointer fragments are being
735+ // preserved (see <https://github.com/rust-lang/rust/issues/148470>).
736+ // We can skip this if there is no padding (e.g. for wide pointers).
737+ if !will_later_validate && a_size + b_val. size ( ) != layout. size {
738+ alloc. write_uninit_full ( ) ;
739+ }
740+
741+ alloc. write_scalar ( alloc_range ( Size :: ZERO , a_size) , a_val) ?;
732742 alloc. write_scalar ( alloc_range ( b_offset, b_val. size ( ) ) , b_val) ?;
733- // We don't have to reset padding here, `write_immediate` will anyway do a validation run.
734743 }
735744 Immediate :: Uninit => alloc. write_uninit_full ( ) ,
736745 }
0 commit comments