diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index a93911225e417..43f405b223504 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -45,9 +45,9 @@ const_eval_copy_nonoverlapping_overlapping =
`copy_nonoverlapping` called on overlapping ranges
const_eval_dangling_int_pointer =
- {$bad_pointer_message}: {$pointer} is a dangling pointer (it has no provenance)
+ {$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got {$pointer} which is a dangling pointer (it has no provenance)
const_eval_dangling_null_pointer =
- {$bad_pointer_message}: null pointer is a dangling pointer (it has no provenance)
+ {$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got a null pointer
const_eval_dangling_ptr_in_final = encountered dangling pointer in final value of {const_eval_intern_kind}
const_eval_dead_local =
@@ -87,6 +87,13 @@ const_eval_error = {$error_kind ->
const_eval_exact_div_has_remainder =
exact_div: {$a} cannot be divided by {$b} without remainder
+const_eval_expected_inbounds_pointer =
+ expected {$inbounds_size ->
+ [0] a pointer to some allocation
+ [1] a pointer to 1 byte of memory
+ *[x] a pointer to {$inbounds_size} bytes of memory
+ }
+
const_eval_extern_static =
cannot access extern static ({$did})
const_eval_extern_type_field = `extern type` field does not have a known offset
@@ -265,10 +272,16 @@ const_eval_pointer_arithmetic_overflow =
overflowing in-bounds pointer arithmetic
const_eval_pointer_arithmetic_test = out-of-bounds pointer arithmetic
const_eval_pointer_out_of_bounds =
- {$bad_pointer_message}: {$alloc_id} has size {$alloc_size}, so pointer to {$ptr_size} {$ptr_size ->
- [1] byte
- *[many] bytes
- } starting at offset {$ptr_offset} is out-of-bounds
+ {$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got {$pointer} {$ptr_offset_is_neg ->
+ [true] which points to before the beginning of the allocation
+ *[false] {$alloc_size_minus_ptr_offset ->
+ [0] which is at or beyond the end of the allocation of size {$alloc_size ->
+ [1] 1 byte
+ *[x] {$alloc_size} bytes
+ }
+ *[x] and there are only {$alloc_size_minus_ptr_offset} bytes starting at that pointer
+ }
+ }
const_eval_pointer_use_after_free =
{$bad_pointer_message}: {$alloc_id} has been freed, so this pointer is dangling
const_eval_ptr_as_bytes_1 =
@@ -466,5 +479,3 @@ const_eval_write_through_immutable_pointer =
const_eval_write_to_read_only =
writing to {$allocation} which is read-only
-const_eval_zst_pointer_out_of_bounds =
- {$bad_pointer_message}: {$alloc_id} has size {$alloc_size}, so pointer at offset {$ptr_offset} is out-of-bounds
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 292d6ba9d08a4..922225e22d909 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::