Open
Description
Miri executes this program without error, but I believe our lowering to LLVM IR adds UB:
#![feature(strict_provenance, exposed_provenance)]
#[no_mangle]
pub fn from_exposed_null(addr: usize) -> *const u8 {
let ptr = 0x0 as *const u8;
ptr.with_addr(addr)
}
// Main for Miri
fn main() {
let data = 0u8;
let addr = std::ptr::addr_of!(data).expose_provenance();
let ptr = from_exposed_null(addr);
unsafe {
println!("{}", *ptr);
}
}
With optimizations enabled, LLVM cleans up from_exposed_null
to
define noalias noundef ptr @from_exposed_null(i64 noundef %addr) unnamed_addr #0 !dbg !7 {
%0 = getelementptr i8, ptr null, i64 %addr, !dbg !12
ret ptr %0, !dbg !28
}
With -Cno-prepopulate-passes
I believe the codegen also returns a pointer that definitely has no provenance, though it's just harder to read.
godbolt: https://godbolt.org/z/s414rfK44
I think this happens because codegen is implicitly const-propagating through the int-to-pointer cast via OperandValue
. At least I don't see any other way to get from this MIR:
bb0: {
_2 = const 0_usize as *const u8 (PointerWithExposedProvenance);
StorageLive(_3);
StorageLive(_5);
StorageLive(_6);
StorageLive(_4);
_4 = copy _2 as usize (Transmute);
_3 = move _4 as isize (IntToInt);
StorageDead(_4);
_5 = copy _1 as isize (IntToInt);
_6 = Sub(copy _5, copy _3);
_0 = arith_offset::<u8>(move _2, move _6) -> [return: bb1, unwind unreachable];
}
bb1: {
StorageLive(_7);
_7 = copy _0 as *const () (PtrToPtr);
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
StorageDead(_3);
return;
}
To this LLVM IR
define noundef ptr @from_exposed_null(i64 noundef %addr) unnamed_addr #0 !dbg !7 {
start:
%0 = alloca [8 x i8], align 8, !dbg !12
%offset = sub i64 %addr, 0, !dbg !12
call void @llvm.lifetime.start.p0(i64 8, ptr %0), !dbg !28
%1 = getelementptr i8, ptr null, i64 %offset, !dbg !28
store ptr %1, ptr %0, align 8, !dbg !28
%self = load ptr, ptr %0, align 8, !dbg !28
call void @llvm.lifetime.end.p0(i64 8, ptr %0), !dbg !28
ret ptr %self, !dbg !34
}
godbolt: https://godbolt.org/z/MjPvcdj9h