Rollup merge of #147576 - Mark-Simulacrum:fix-offset-zst, r=nnethercote,RalfJung

Fix ICE on offsetted ZST pointer

I'm not sure this is the *right* fix, but it's simple enough and does roughly what I'd expect. Like with the previous optimization to codegen usize rather than a zero-sized static, there's no guarantee that we continue returning a particular value from the offsetting.

A grep for `const_usize.*align` found the same code copied to rustc_codegen_gcc and cranelift but a quick skim didn't find other cases of similar 'optimization'. That said, I'm not convinced I caught everything, it's not trivial to search for this.

Closes rust-lang/rust#147516
This commit is contained in:
Matthias Krüger
2025-10-16 19:35:24 +02:00
committed by GitHub
+8 -3
View File
@@ -5,7 +5,9 @@
use cranelift_module::*;
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint};
use rustc_middle::mir::interpret::{
AllocId, GlobalAlloc, PointerArithmetic, Scalar, read_target_uint,
};
use rustc_middle::ty::{ExistentialTraitRef, ScalarInt};
use crate::prelude::*;
@@ -138,8 +140,11 @@ pub(crate) fn codegen_const_value<'tcx>(
let base_addr = match fx.tcx.global_alloc(alloc_id) {
GlobalAlloc::Memory(alloc) => {
if alloc.inner().len() == 0 {
assert_eq!(offset, Size::ZERO);
fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64)
let val = alloc.inner().align.bytes().wrapping_add(offset.bytes());
fx.bcx.ins().iconst(
fx.pointer_type,
fx.tcx.truncate_to_target_usize(val) as i64,
)
} else {
let data_id = data_id_for_alloc_id(
&mut fx.constants_cx,