Skip to content

unsized_fn_params allows some unsized locals #111175

Open
@RalfJung

Description

@RalfJung

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);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlF-unsized_fn_params`#![feature(unsized_fn_params)]`requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions