rust-lang/rust · error
const_alloc_to_gcc_uncached: could not read relocation point
Error message
const_alloc_to_gcc_uncached: could not read relocation pointer
What it means
`const_alloc_to_gcc_uncached` (consts.rs:315-348) walks an allocation's provenance pointers and, for each, reads `pointer_size` bytes as a target-endian integer via `read_target_uint(dl.endian, ...).expect("const_alloc_to_gcc_uncached: could not read relocation pointer")` at line 347. The panic means those bytes could not be decoded into a `u64` relocation offset. This is an interpreter/codegen contract violation: the provenance range must contain exactly a pointer-sized, endian-correct integer.
Source
Thrown at compiler/rustc_codegen_gcc/src/consts.rs:347
let offset = offset as usize;
if offset > next_offset {
// This `inspect` is okay since we have checked that it is not within a pointer with provenance, it
// is within the bounds of the allocation, and it doesn't affect interpreter execution
// (we inspect the result after interpreter execution). Any undef byte is replaced with
// some arbitrary byte value.
//
// FIXME: relay undef bytes to codegen as undef const bytes
let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(next_offset..offset);
llvals.push(cx.const_bytes(bytes));
}
let ptr_offset = read_target_uint(
dl.endian,
// This `inspect` is okay since it is within the bounds of the allocation, it doesn't
// affect interpreter execution (we inspect the result after interpreter execution),
// and we properly interpret the provenance as a relocation pointer offset.
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
)
.expect("const_alloc_to_gcc_uncached: could not read relocation pointer")
as u64;
let address_space = cx.tcx.global_alloc(alloc_id).address_space(cx);
llvals.push(cx.scalar_to_backend(
InterpScalar::from_pointer(
interpret::Pointer::new(prov, Size::from_bytes(ptr_offset)),
&cx.tcx,
),
abi::Scalar::Initialized {
value: Primitive::Pointer(address_space),
valid_range: WrappingRange::full(dl.pointer_size()),
},
cx.type_i8p_ext(address_space),
));
next_offset = offset + pointer_size;
}
if alloc.len() >= next_offset {View on GitHub (pinned to 22057b88b0)
Solutions
- Clean incremental artifacts (`cargo clean` / remove `target/`) and rebuild — a stale corrupt allocation cache is a cheap first check.
- Verify the target triple and data layout match the pointer width the code was compiled for; a 64-bit target with a 32-bit-pointer data layout (or vice versa) is the usual cause.
- Reproduce against the rustc version this rustc_codegen_gcc checkout is pinned to; provenance encoding has changed across rustc releases.
- If you control the target spec, confirm `data_layout` pointer size and endianness are correct; dump the bytes at the failing offset and compare to the expected relocation value.
Example fix
// before (consts.rs:340-348)
let ptr_offset = read_target_uint(
dl.endian,
alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
)
.expect("const_alloc_to_gcc_uncached: could not read relocation pointer") as u64;
// after (diagnose pointer-size / endianness mismatch instead of opaque panic)
let reloc_bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size));
let ptr_offset = read_target_uint(dl.endian, reloc_bytes).unwrap_or_else(|e| {
panic!("relocation read failed at offset {offset}: pointer_size={pointer_size}, endian={:?}, bytes={reloc_bytes:?}, err={e:?}", dl.endian);
}) as u64; Defensive patterns
Strategy: validation
Validate before calling
// consts.rs:347 -> read_target_uint over the relocation slot panics if the
// byte slice is shorter than pointer_size or the offset is out of bounds.
// Validate the allocation window before const lowering:
fn reloc_slot_ok(alloc_bytes: &[u8], offset: usize, ptr_size: usize) -> bool {
match offset.checked_add(ptr_size) {
Some(end) => end <= alloc_bytes.len(),
None => false,
}
}
// Also confirm dl.endian and pointer_size match the target data layout. Prevention
- Treat this panic as a malformed const allocation: the relocation offset points past the alloc, or pointer_size is wrong for the target.
- Verify the target pointer size and endianness match the allocation's data layout before lowering a const with relocations.
- Reproduce the same const under miri or LLVM first; if they accept it, file an upstream bug with the allocation dump.
When it happens
Trigger: Reached when an allocation has provenance (`alloc.provenance().ptrs()` non-empty) and `read_target_uint` overflows or otherwise fails on the bytes at `[offset, offset+pointer_size)`. Concretely: pointer-size mismatch (e.g. the data layout's `pointer_size` differs from what the interpreter wrote), a truncated/corrupt allocation buffer, or an unsupported relocation encoding for the target's endianness.
Common situations: Cross-compiling between pointer-width targets (32 vs 64-bit) with a misconfigured target spec / data layout; using a rustc version whose const-eval writes provenance in a shape this backend doesn't expect; corrupted incremental-cache artifacts; custom targets with non-standard pointer sizes.
Related errors
- func
- struct type
- `static_addr_of_mut` did not add the global to `self.global_
- Can't get the layout of `i128`
- last arg
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/eeea581f847005fe.json.
Report an issue: GitHub.