fix handling of alignment for dyn-sized places
This commit is contained in:
parent
124fb1490a
commit
e7c6db7d44
3 changed files with 12 additions and 9 deletions
|
@ -328,7 +328,8 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
let mplace = MemPlace { ptr: ptr.to_pointer(self)?, meta };
|
let mplace = MemPlace { ptr: ptr.to_pointer(self)?, meta };
|
||||||
// When deref'ing a pointer, the *static* alignment given by the type is what matters.
|
// `ref_to_mplace` is called on raw pointers even if they don't actually get dereferenced;
|
||||||
|
// we hence can't call `size_and_align_of` since that asserts more validity than we want.
|
||||||
let align = layout.align.abi;
|
let align = layout.align.abi;
|
||||||
Ok(MPlaceTy { mplace, layout, align })
|
Ok(MPlaceTy { mplace, layout, align })
|
||||||
}
|
}
|
||||||
|
@ -379,11 +380,12 @@ where
|
||||||
|
|
||||||
/// Check if this mplace is dereferenceable and sufficiently aligned.
|
/// Check if this mplace is dereferenceable and sufficiently aligned.
|
||||||
pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
|
pub fn check_mplace(&self, mplace: MPlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
|
||||||
let (size, align) = self
|
let (size, _align) = self
|
||||||
.size_and_align_of_mplace(&mplace)?
|
.size_and_align_of_mplace(&mplace)?
|
||||||
.unwrap_or((mplace.layout.size, mplace.layout.align.abi));
|
.unwrap_or((mplace.layout.size, mplace.layout.align.abi));
|
||||||
assert!(mplace.align <= align, "dynamic alignment less strict than static one?");
|
// Due to packed places, only `mplace.align` matters.
|
||||||
let align = if M::enforce_alignment(self).should_check() { align } else { Align::ONE };
|
let align =
|
||||||
|
if M::enforce_alignment(self).should_check() { mplace.align } else { Align::ONE };
|
||||||
self.check_ptr_access_align(mplace.ptr, size, align, CheckInAllocMsg::DerefTest)?;
|
self.check_ptr_access_align(mplace.ptr, size, align, CheckInAllocMsg::DerefTest)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// should find the bug even without validation and stacked borrows, but gets masked by optimizations
|
// should find the bug even without, but gets masked by optimizations
|
||||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 -Cdebug-assertions=no
|
//@compile-flags: -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 -Cdebug-assertions=no
|
||||||
|
//@normalize-stderr-test: "but found [0-9]+" -> "but found $$ALIGN"
|
||||||
|
|
||||||
#[repr(align(256))]
|
#[repr(align(256))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -19,6 +20,6 @@ fn main() {
|
||||||
(&mut ptr as *mut _ as *mut *const u8).write(&buf as *const _ as *const u8);
|
(&mut ptr as *mut _ as *mut *const u8).write(&buf as *const _ as *const u8);
|
||||||
}
|
}
|
||||||
// Re-borrow that. This should be UB.
|
// Re-borrow that. This should be UB.
|
||||||
let _ptr = &*ptr; //~ERROR: alignment 256 is required
|
let _ptr = &*ptr; //~ERROR: required 256 byte alignment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required
|
error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required 256 byte alignment but found $ALIGN)
|
||||||
--> $DIR/dyn_alignment.rs:LL:CC
|
--> $DIR/dyn_alignment.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _ptr = &*ptr;
|
LL | let _ptr = &*ptr;
|
||||||
| ^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required
|
| ^^^^^ constructing invalid value: encountered an unaligned reference (required 256 byte alignment but found $ALIGN)
|
||||||
|
|
|
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue