Skip to content

Commit 26baf87

Browse files
committed
Auto merge of #1348 - RalfJung:raw-addr-of-align, r=RalfJung
Stacked Borrows: alignment does not matter Fixes #1339 Requires rust-lang/rust#71280
2 parents f844eb2 + 4b9abda commit 26baf87

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9b2f8dbba39dd4167f22a7026674a585c3d907d8
1+
b2e36e6c2d229126b59e892c9147fbb68115d292

src/eval.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
9898
start_id,
9999
tcx.mk_substs(::std::iter::once(ty::subst::GenericArg::from(main_ret_ty))),
100100
)
101+
.unwrap()
101102
.unwrap();
102103

103104
// First argument: pointer to `main()`.

src/stacked_borrows.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use log::trace;
1111
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1212
use rustc_middle::mir::RetagKind;
1313
use rustc_middle::ty;
14-
use rustc_target::abi::{LayoutOf, Size};
14+
use rustc_target::abi::{Align, LayoutOf, Size};
1515
use rustc_hir::Mutability;
1616

1717
use crate::*;
@@ -577,11 +577,13 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
577577
.size_and_align_of_mplace(place)?
578578
.map(|(size, _)| size)
579579
.unwrap_or_else(|| place.layout.size);
580+
// `reborrow` relies on getting a `Pointer` and everything being in-bounds,
581+
// so let's ensure that. However, we do not care about alignment.
580582
// We can see dangling ptrs in here e.g. after a Box's `Unique` was
581-
// updated using "self.0 = ..." (can happen in Box::from_raw); see miri#1050.
582-
let place = this.mplace_access_checked(place)?;
583+
// updated using "self.0 = ..." (can happen in Box::from_raw) so we cannot ICE; see miri#1050.
584+
let place = this.mplace_access_checked(place, Some(Align::from_bytes(1).unwrap()))?;
585+
// Nothing to do for ZSTs.
583586
if size == Size::ZERO {
584-
// Nothing to do for ZSTs.
585587
return Ok(val);
586588
}
587589

tests/run-pass/packed_struct.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
#![feature(unsize, coerce_unsized)]
1+
#![feature(unsize, coerce_unsized, raw_ref_op)]
22

33
use std::collections::hash_map::DefaultHasher;
44
use std::hash::Hash;
55

66
fn test_basic() {
77
#[repr(packed)]
88
struct S {
9+
fill: u8,
910
a: i32,
1011
b: i64,
1112
}
@@ -30,16 +31,21 @@ fn test_basic() {
3031
}
3132

3233
let mut x = S {
34+
fill: 0,
3335
a: 42,
3436
b: 99,
3537
};
3638
let a = x.a;
3739
let b = x.b;
3840
assert_eq!(a, 42);
3941
assert_eq!(b, 99);
42+
assert_eq!(&x.fill, &0); // `fill` just requirs 1-byte-align, so this is fine
4043
// can't do `assert_eq!(x.a, 42)`, because `assert_eq!` takes a reference
4144
assert_eq!({x.a}, 42);
4245
assert_eq!({x.b}, 99);
46+
// but we *can* take a raw pointer!
47+
assert_eq!(unsafe { (&raw const x.a).read_unaligned() }, 42);
48+
assert_eq!(unsafe { (&raw const x.b).read_unaligned() }, 99);
4349

4450
x.b = 77;
4551
assert_eq!({x.b}, 77);

0 commit comments

Comments
 (0)