more precise error for 'based on misaligned pointer' case
This commit is contained in:
parent
cbf47a17d2
commit
e24835c6e0
31 changed files with 112 additions and 91 deletions
|
@ -390,15 +390,6 @@ pub struct LiveDrop<'tcx> {
|
|||
pub dropped_at: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(const_eval_align_check_failed)]
|
||||
pub struct AlignmentCheckFailed {
|
||||
pub has: u64,
|
||||
pub required: u64,
|
||||
#[subdiagnostic]
|
||||
pub frames: Vec<FrameNote>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_error, code = "E0080")]
|
||||
pub struct ConstEvalError {
|
||||
|
@ -568,9 +559,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
|
||||
builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
|
||||
}
|
||||
AlignmentCheckFailed(Misalignment { required, has }) => {
|
||||
AlignmentCheckFailed(Misalignment { required, has }, msg) => {
|
||||
builder.set_arg("required", required.bytes());
|
||||
builder.set_arg("has", has.bytes());
|
||||
builder.set_arg("msg", format!("{msg:?}"));
|
||||
}
|
||||
WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => {
|
||||
builder.set_arg("allocation", alloc);
|
||||
|
|
|
@ -21,8 +21,8 @@ use rustc_target::abi::{Align, HasDataLayout, Size};
|
|||
use crate::fluent_generated as fluent;
|
||||
|
||||
use super::{
|
||||
alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckInAllocMsg,
|
||||
GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer,
|
||||
alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg,
|
||||
CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer,
|
||||
PointerArithmetic, Provenance, Scalar,
|
||||
};
|
||||
|
||||
|
@ -425,7 +425,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
// Must be aligned.
|
||||
if M::enforce_alignment(self) && align.bytes() > 1 {
|
||||
self.check_misalign(Self::offset_misalignment(addr, align))?;
|
||||
self.check_misalign(
|
||||
Self::offset_misalignment(addr, align),
|
||||
CheckAlignMsg::AccessedPtr,
|
||||
)?;
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -449,7 +452,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// Test align. Check this last; if both bounds and alignment are violated
|
||||
// we want the error to be about the bounds.
|
||||
if M::enforce_alignment(self) && align.bytes() > 1 {
|
||||
self.check_misalign(self.alloc_misalignment(ptr, offset, align, alloc_align))?;
|
||||
self.check_misalign(
|
||||
self.alloc_misalignment(ptr, offset, align, alloc_align),
|
||||
CheckAlignMsg::AccessedPtr,
|
||||
)?;
|
||||
}
|
||||
|
||||
// We can still be zero-sized in this branch, in which case we have to
|
||||
|
@ -460,9 +466,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn check_misalign(&self, misaligned: Option<Misalignment>) -> InterpResult<'tcx> {
|
||||
pub(super) fn check_misalign(
|
||||
&self,
|
||||
misaligned: Option<Misalignment>,
|
||||
msg: CheckAlignMsg,
|
||||
) -> InterpResult<'tcx> {
|
||||
if let Some(misaligned) = misaligned {
|
||||
throw_ub!(AlignmentCheckFailed(misaligned))
|
||||
throw_ub!(AlignmentCheckFailed(misaligned, msg))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ use rustc_middle::ty::Ty;
|
|||
use rustc_target::abi::{Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT};
|
||||
|
||||
use super::{
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, ImmTy, Immediate,
|
||||
InterpCx, InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, Operand, Pointer,
|
||||
PointerArithmetic, Projectable, Provenance, Readable, Scalar,
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckAlignMsg, ImmTy,
|
||||
Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy,
|
||||
Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, Scalar,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||
|
@ -461,7 +461,7 @@ where
|
|||
// We check alignment separately, and *after* checking everything else.
|
||||
// If an access is both OOB and misaligned, we want to see the bounds error.
|
||||
let a = self.get_ptr_alloc(mplace.ptr(), size, Align::ONE)?;
|
||||
self.check_misalign(mplace.mplace.misaligned)?;
|
||||
self.check_misalign(mplace.mplace.misaligned, CheckAlignMsg::BasedOn)?;
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
|
@ -477,7 +477,7 @@ where
|
|||
// We check alignment separately, and raise that error *after* checking everything else.
|
||||
// If an access is both OOB and misaligned, we want to see the bounds error.
|
||||
// However we have to call `check_misalign` first to make the borrow checker happy.
|
||||
let misalign_err = self.check_misalign(mplace.mplace.misaligned);
|
||||
let misalign_err = self.check_misalign(mplace.mplace.misaligned, CheckAlignMsg::BasedOn);
|
||||
let a = self.get_ptr_alloc_mut(mplace.ptr(), size, Align::ONE)?;
|
||||
misalign_err?;
|
||||
Ok(a)
|
||||
|
@ -881,8 +881,8 @@ where
|
|||
dest_size,
|
||||
/*nonoverlapping*/ true,
|
||||
)?;
|
||||
self.check_misalign(src.mplace.misaligned)?;
|
||||
self.check_misalign(dest.mplace.misaligned)?;
|
||||
self.check_misalign(src.mplace.misaligned, CheckAlignMsg::BasedOn)?;
|
||||
self.check_misalign(dest.mplace.misaligned, CheckAlignMsg::BasedOn)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
|
||||
),
|
||||
self.path,
|
||||
Ub(AlignmentCheckFailed(Misalignment { required, has })) => UnalignedPtr {
|
||||
Ub(AlignmentCheckFailed(Misalignment { required, has }, _msg)) => UnalignedPtr {
|
||||
ptr_kind,
|
||||
required_bytes: required.bytes(),
|
||||
found_bytes: has.bytes()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue