Open
Description
Found in rust-lang/miri#2872: this code
#![feature(core_intrinsics, unsized_fn_params)]
use std::intrinsics;
pub fn forget_unsized(t: [i32]) {
intrinsics::forget(t)
}
with -Zmir-opt-level=0
generates this LLVM IR
define void @_ZN4test14forget_unsized17h6fbb3409c8556ed4E(ptr %0, i64 %1) unnamed_addr #0 {
start:
%_2 = alloca { ptr, i64 }, align 8
%t = alloca { ptr, i64 }, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 0
store ptr %0, ptr %2, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 1
store i64 %1, ptr %3, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 0
%5 = load ptr, ptr %4, align 8, !noundef !2
%6 = getelementptr inbounds { ptr, i64 }, ptr %t, i32 0, i32 1
%7 = load i64, ptr %6, align 8, !noundef !2
%8 = mul nsw i64 %7, 4
%9 = alloca i8, i64 %8, align 16
call void @llvm.memcpy.p0.p0.i64(ptr align 16 %9, ptr align 1 %5, i64 %8, i1 false)
%10 = getelementptr inbounds { ptr, i64 }, ptr %_2, i32 0, i32 0
store ptr %9, ptr %10, align 8
%11 = getelementptr inbounds { ptr, i64 }, ptr %_2, i32 0, i32 1
store i64 %7, ptr %11, align 8
ret void
}
Notice the alloca
. This is bad! Our alloca code path is unsound (it does not properly account for alignment); the point of the unsized_fn_params
feature gate (separate from unsized_locals
) was to avoid hitting that code path.
I repeat my stance that we should remove the unsound alloca code path (effectively de-imlementing unsized locals) to ensure this can never happen.
We don't have a MIR building ping group AFAIK, so Cc @rust-lang/wg-mir-opt I guess.
Here's a Miri testcase:
#![feature(forget_unsized, unsized_fn_params)]
fn main() {
let b: Box<[u32]> = Box::new([1, 2, 3]);
std::mem::forget_unsized(*b);
}