diff options
| author | Ralf Jung <post@ralfj.de> | 2024-07-27 18:09:50 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-07-27 21:12:54 +0200 |
| commit | f8ebe8d783e20c44508fab32b708f1b9d9a4bf13 (patch) | |
| tree | 27b486aa8fa8400866095e053fa478fe9a7a7d94 /compiler/rustc_const_eval/src | |
| parent | 5b38b149dc5f8a9aaeb06eac6c6f819e0a17caee (diff) | |
| download | rust-f8ebe8d783e20c44508fab32b708f1b9d9a4bf13.tar.gz rust-f8ebe8d783e20c44508fab32b708f1b9d9a4bf13.zip | |
improve dangling/oob errors and make them more uniform
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/errors.rs | 42 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/memory.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/validity.rs | 8 |
3 files changed, 41 insertions, 21 deletions
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 292d6ba9d08..922225e22d9 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -7,9 +7,9 @@ use rustc_errors::{ use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::interpret::{ - CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, Misalignment, - PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, - ValidationErrorInfo, + CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpError, InvalidMetaKind, + InvalidProgramInfo, Misalignment, Pointer, PointerKind, ResourceExhaustionInfo, + UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, }; use rustc_middle::ty::{self, Mutability, Ty}; use rustc_span::Span; @@ -488,10 +488,9 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { InvalidMeta(InvalidMetaKind::TooBig) => const_eval_invalid_meta, UnterminatedCString(_) => const_eval_unterminated_c_string, PointerUseAfterFree(_, _) => const_eval_pointer_use_after_free, - PointerOutOfBounds { ptr_size: Size::ZERO, .. } => const_eval_zst_pointer_out_of_bounds, PointerOutOfBounds { .. } => const_eval_pointer_out_of_bounds, - DanglingIntPointer(0, _) => const_eval_dangling_null_pointer, - DanglingIntPointer(_, _) => const_eval_dangling_int_pointer, + DanglingIntPointer { addr: 0, .. } => const_eval_dangling_null_pointer, + DanglingIntPointer { .. } => const_eval_dangling_int_pointer, AlignmentCheckFailed { .. } => const_eval_alignment_check_failed, WriteToReadOnly(_) => const_eval_write_to_read_only, DerefFunctionPointer(_) => const_eval_deref_function_pointer, @@ -573,18 +572,33 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { diag.arg("alloc_id", alloc_id) .arg("bad_pointer_message", bad_pointer_message(msg, dcx)); } - PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => { - diag.arg("alloc_id", alloc_id) - .arg("alloc_size", alloc_size.bytes()) - .arg("ptr_offset", ptr_offset) - .arg("ptr_size", ptr_size.bytes()) + PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, inbounds_size, msg } => { + diag.arg("alloc_size", alloc_size.bytes()) + .arg("inbounds_size", inbounds_size.bytes()) .arg("bad_pointer_message", bad_pointer_message(msg, dcx)); + diag.arg( + "pointer", + Pointer::new( + Some(CtfeProvenance::from(alloc_id)), + Size::from_bytes(ptr_offset as u64), + ) + .to_string(), + ); + diag.arg("ptr_offset_is_neg", ptr_offset < 0); + diag.arg( + "alloc_size_minus_ptr_offset", + alloc_size.bytes().saturating_sub(ptr_offset as u64), + ); } - DanglingIntPointer(ptr, msg) => { - if ptr != 0 { - diag.arg("pointer", format!("{ptr:#x}[noalloc]")); + DanglingIntPointer { addr, inbounds_size, msg } => { + if addr != 0 { + diag.arg( + "pointer", + Pointer::<Option<CtfeProvenance>>::from_addr_invalid(addr).to_string(), + ); } + diag.arg("inbounds_size", inbounds_size.bytes()); diag.arg("bad_pointer_message", bad_pointer_message(msg, dcx)); } AlignmentCheckFailed(Misalignment { required, has }, msg) => { diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 0d85e8ef664..f49a0ed727a 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -459,7 +459,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(match self.ptr_try_get_alloc_id(ptr) { Err(addr) => { // We couldn't get a proper allocation. - throw_ub!(DanglingIntPointer(addr, msg)); + throw_ub!(DanglingIntPointer { addr, inbounds_size: size, msg }); } Ok((alloc_id, offset, prov)) => { let (alloc_size, _alloc_align, ret_val) = alloc_size(alloc_id, offset, prov)?; @@ -470,7 +470,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { alloc_id, alloc_size, ptr_offset: self.target_usize_to_isize(offset.bytes()), - ptr_size: size, + inbounds_size: size, msg, }) } @@ -1443,7 +1443,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ptr: Pointer<Option<M::Provenance>>, ) -> InterpResult<'tcx, (AllocId, Size, M::ProvenanceExtra)> { self.ptr_try_get_alloc_id(ptr).map_err(|offset| { - err_ub!(DanglingIntPointer(offset, CheckInAllocMsg::InboundsTest)).into() + err_ub!(DanglingIntPointer { + addr: offset, + // We don't know the actually required size. + inbounds_size: Size::ZERO, + msg: CheckInAllocMsg::InboundsTest + }) + .into() }) } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3dc3e6c8833..879f9205cbf 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -348,7 +348,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { try_validation!( self.ecx.get_ptr_vtable_ty(vtable, Some(data)), self.path, - Ub(DanglingIntPointer(..) | InvalidVTablePointer(..)) => + Ub(DanglingIntPointer{ .. } | InvalidVTablePointer(..)) => InvalidVTablePtr { value: format!("{vtable}") }, Ub(InvalidVTableTrait { expected_trait, vtable_trait }) => { InvalidMetaWrongTrait { expected_trait, vtable_trait: *vtable_trait } @@ -405,8 +405,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message ), self.path, - Ub(DanglingIntPointer(0, _)) => NullPtr { ptr_kind }, - Ub(DanglingIntPointer(i, _)) => DanglingPtrNoProvenance { + Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind }, + Ub(DanglingIntPointer { addr: i, .. }) => DanglingPtrNoProvenance { ptr_kind, // FIXME this says "null pointer" when null but we need translate pointer: format!("{}", Pointer::<Option<AllocId>>::from_addr_invalid(*i)) @@ -605,7 +605,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { let _fn = try_validation!( self.ecx.get_ptr_fn(ptr), self.path, - Ub(DanglingIntPointer(..) | InvalidFunctionPointer(..)) => + Ub(DanglingIntPointer{ .. } | InvalidFunctionPointer(..)) => InvalidFnPtr { value: format!("{ptr}") }, ); // FIXME: Check if the signature matches |
