Skip to content

ICE when dealloc causes Stacked Borrows error #2693

Closed
@RalfJung

Description

@RalfJung

I realized we don't have a test hitting this, and indeed trying to do so currently ICEs:

use std::alloc::{alloc, dealloc, Layout};

fn main() { unsafe {
    let x = alloc(Layout::from_size_align_unchecked(1, 1));
    let ptr1 = (&mut *x) as *mut u8;
    let ptr2 = (&mut *ptr1) as *mut u8;
    // Invalidate ptr2 by writing to ptr1.
    ptr1.write(0);
    // Deallocate through ptr2.
    dealloc(ptr2, Layout::from_size_align_unchecked(1, 1));
} }

produces

thread '<unnamed>' panicked at 'internal error: entered unreachable code: access_error should only be called during an access', src/stacked_borrows/diagnostics.rs:398:13

The trouble is here:

// Step 1: Make a write access.
// As part of this we do regular protector checking, i.e. even weakly protected items cause UB when popped.
self.access(AccessKind::Write, tag, global, dcx, exposed_tags)
.map_err(|_| dcx.dealloc_error())?;

We try to use map_err to make this a deallocation error, but when that happens access has already called dcx.access_error, causing the ICE. (The ICE is a regression introduced by #2684.)

@saethlin any idea how to best fix this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions