/// The size of the allocation. Currently, must always equal `bytes.len()`.
pub size: Size,
/// The alignment of the allocation to detect unaligned reads.
+ /// (`Align` guarantees that this is a power of two.)
pub align: Align,
/// `true` if the allocation is mutable.
/// Also used by codegen to determine if a static should be put into mutable memory,
UnterminatedCString(Pointer),
/// Dereferencing a dangling pointer after it got freed.
PointerUseAfterFree(AllocId),
- /// Using a NULL pointer in the wrong way.
- InvalidNullPointerUsage,
/// Used a pointer outside the bounds it is valid for.
PointerOutOfBounds {
ptr: Pointer,
required: Align,
has: Align,
},
+ /// Using an integer as a pointer in the wrong way.
+ InvalidIntPointerUsage(u64),
/// Writing to read-only memory.
WriteToReadOnly(AllocId),
/// Using a pointer-not-to-a-function as function pointer.
PointerUseAfterFree(a) => {
write!(f, "pointer to {:?} was dereferenced after this allocation got freed", a)
}
- InvalidNullPointerUsage => write!(f, "invalid use of NULL pointer"),
PointerOutOfBounds { ptr, msg, allocation_size } => write!(
f,
"{} failed: pointer must be in-bounds at offset {}, \
ptr.alloc_id,
allocation_size.bytes()
),
+ InvalidIntPointerUsage(0) => write!(f, "invalid use of NULL pointer"),
+ InvalidIntPointerUsage(i) => write!(f, "invalid use of {} as a pointer", i),
AlignmentCheckFailed { required, has } => write!(
f,
"accessing memory with alignment {}, but alignment {} is required",
pub enum UnsupportedOpInfo {
/// Free-form case. Only for errors that are never caught!
Unsupported(String),
-
/// When const-prop encounters a situation it does not support, it raises this error.
/// This must not allocate for performance reasons (hence `str`, not `String`).
ConstPropUnsupported(&'static str),
-
/// Accessing an unsupported foreign static.
ReadForeignStatic(DefId),
-
/// Could not find MIR for a function.
NoMirFor(DefId),
-
/// Modified a static during const-eval.
/// FIXME: move this to `ConstEvalErrKind` through a machine hook.
ModifiedStatic,
-
/// Encountered a pointer where we needed raw bytes.
ReadPointerAsBytes,
-
/// Encountered raw bytes where we needed a pointer.
ReadBytesAsPointer,
}
int: u64,
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
Err((if int == 0 {
- err_ub!(InvalidNullPointerUsage)
+ // This is UB, seriously.
+ err_ub!(InvalidIntPointerUsage(0))
} else {
+ // This is just something we cannot support during const-eval.
err_unsup!(ReadBytesAsPointer)
})
.into())
assert!(size.bytes() == 0);
// Must be non-NULL.
if bits == 0 {
- throw_ub!(InvalidNullPointerUsage)
+ throw_ub!(InvalidIntPointerUsage(0))
}
// Must be aligned.
if let Some(align) = align {
return Ok(());
}
let caller_arg = caller_arg.next().ok_or_else(|| {
- err_ub_format!("calling a function passing fewer arguments than it requires")
+ err_ub_format!("calling a function with fewer arguments than it requires")
})?;
if rust_abi {
assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
// Now we should have no more caller args
if caller_iter.next().is_some() {
throw_ub_format!(
- "calling a function passing more arguments than it expected"
+ "calling a function with more arguments than it expected"
)
}
// Don't forget to check the return type!
place.ptr, size, align
);
match err.kind {
- err_ub!(InvalidNullPointerUsage) => {
+ err_ub!(InvalidIntPointerUsage(0)) => {
throw_validation_failure!(format_args!("a NULL {}", kind), self.path)
}
+ err_ub!(InvalidIntPointerUsage(i)) => throw_validation_failure!(
+ format_args!("a {} to unallocated address {}", kind, i),
+ self.path
+ ),
err_ub!(AlignmentCheckFailed { required, has }) => throw_validation_failure!(
format_args!(
- "an unaligned {} \
- (required {} byte alignment but found {})",
+ "an unaligned {} (required {} byte alignment but found {})",
kind,
required.bytes(),
has.bytes()
format_args!("a dangling {} (created from integer)", kind),
self.path
),
- err_ub!(PointerOutOfBounds { .. }) | err_ub!(PointerUseAfterFree(_)) => {
- throw_validation_failure!(
- format_args!("a dangling {} (not entirely in bounds)", kind),
- self.path
- )
- }
+ err_ub!(PointerOutOfBounds { .. }) => throw_validation_failure!(
+ format_args!(
+ "a dangling {} (going beyond the bounds of its allocation)",
+ kind
+ ),
+ self.path
+ ),
+ err_ub!(PointerUseAfterFree(_)) => throw_validation_failure!(
+ format_args!("a dangling {} (use-after-free)", kind),
+ self.path
+ ),
_ => bug!("Unexpected error during ptr inbounds test: {}", err),
}
}
--> $DIR/ub-wide-ptr.rs:32:1
|
LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (not entirely in bounds)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation)
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
--> $DIR/ub-wide-ptr.rs:62:1
|
LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (not entirely in bounds)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (going beyond the bounds of its allocation)
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
--> $DIR/ub-wide-ptr.rs:68:1
|
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (not entirely in bounds)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation)
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
LL | const VALUE: u8 = unsafe { *REG_ADDR };
| ---------------------------^^^^^^^^^---
| |
- | a memory access tried to interpret some bytes as a pointer
+ | unable to turn these bytes into a pointer
|
= note: `#[deny(const_err)]` on by default