Skip to content

Commit 8ecda4b

Browse files
committed
interpret: fix overlapping aggregate initialization
1 parent 7ad23f4 commit 8ecda4b

14 files changed

+77
-11
lines changed

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@ where
858858
/// Also, if you use this you are responsible for validating that things get copied at the
859859
/// right type.
860860
#[instrument(skip(self), level = "trace")]
861-
fn copy_op_no_validate(
861+
pub(super) fn copy_op_no_validate(
862862
&mut self,
863863
src: &impl Projectable<'tcx, M::Provenance>,
864864
dest: &impl Writeable<'tcx, M::Provenance>,

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
310310
operands: &IndexSlice<FieldIdx, mir::Operand<'tcx>>,
311311
dest: &PlaceTy<'tcx, M::Provenance>,
312312
) -> InterpResult<'tcx> {
313-
self.write_uninit(dest)?; // make sure all the padding ends up as uninit
314313
let (variant_index, variant_dest, active_field_index) = match *kind {
315314
mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
316315
let variant_dest = self.project_downcast(dest, variant_index)?;
@@ -346,9 +345,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
346345
let field_index = active_field_index.unwrap_or(field_index);
347346
let field_dest = self.project_field(&variant_dest, field_index)?;
348347
let op = self.eval_operand(operand, Some(field_dest.layout))?;
349-
self.copy_op(&op, &field_dest)?;
348+
// We validate manually below so we don't have to do it here.
349+
self.copy_op_no_validate(&op, &field_dest, /*allow_transmute*/ false)?;
350350
}
351-
self.write_discriminant(variant_index, dest)
351+
self.write_discriminant(variant_index, dest)?;
352+
// Validate that the entire thing is valid, and reset padding that might be in between the
353+
// fields.
354+
if M::enforce_validity(self, dest.layout()) {
355+
self.validate_operand(
356+
dest,
357+
M::enforce_validity_recursively(self, dest.layout()),
358+
/*reset_provenance_and_padding*/ true,
359+
)?;
360+
}
361+
interp_ok(())
352362
}
353363

354364
/// Repeats `operand` into the destination. `dest` must have array type, and that type

src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//@revisions: stack tree
2+
// Ensure this even hits the aliasing model
3+
//@compile-flags: -Zmiri-disable-validation
24
//@[tree]compile-flags: -Zmiri-tree-borrows
35
//@error-in-other-file: pointer not dereferenceable
46

src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//@revisions: stack tree
2+
// Ensure this even hits the aliasing model
3+
//@compile-flags: -Zmiri-disable-validation
24
//@[tree]compile-flags: -Zmiri-tree-borrows
35
//@error-in-other-file: is a dangling pointer
46
use std::ptr::NonNull;

src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x4..0x8]
1111
|
1212
LL | let ret = unsafe { &(*xraw).1 };
1313
| ^^^^^^^^^^
14-
help: <TAG> was later invalidated at offsets [0x0..0x8] by a write access
14+
help: <TAG> was later invalidated at offsets [0x4..0x8] by a write access
1515
--> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC
1616
|
1717
LL | unsafe { *xraw = (42, 23) }; // unfreeze

src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here, in the initial state Frozen
1212
|
1313
LL | let ret = unsafe { &(*xraw).1 };
1414
| ^^^^^^^^^^
15-
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8]
15+
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8]
1616
--> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC
1717
|
1818
LL | unsafe { *xraw = (42, 23) }; // unfreeze

src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x4..0x8]
1414
|
1515
LL | let ret = Some(unsafe { &(*xraw).1 });
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
17-
help: <TAG> was later invalidated at offsets [0x0..0x8] by a write access
17+
help: <TAG> was later invalidated at offsets [0x4..0x8] by a write access
1818
--> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC
1919
|
2020
LL | unsafe { *xraw = (42, 23) }; // unfreeze

src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here, in the initial state Frozen
1212
|
1313
LL | let ret = Some(unsafe { &(*xraw).1 });
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
15-
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8]
15+
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8]
1616
--> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC
1717
|
1818
LL | unsafe { *xraw = (42, 23) }; // unfreeze

src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x4..0x8]
1414
|
1515
LL | let ret = (unsafe { &(*xraw).1 },);
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^
17-
help: <TAG> was later invalidated at offsets [0x0..0x8] by a write access
17+
help: <TAG> was later invalidated at offsets [0x4..0x8] by a write access
1818
--> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC
1919
|
2020
LL | unsafe { *xraw = (42, 23) }; // unfreeze

src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ help: the accessed tag <TAG> was created here, in the initial state Frozen
1212
|
1313
LL | let ret = (unsafe { &(*xraw).1 },);
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^
15-
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8]
15+
help: the accessed tag <TAG> later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8]
1616
--> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC
1717
|
1818
LL | unsafe { *xraw = (42, 23) }; // unfreeze

0 commit comments

Comments
 (0)