Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Box sometimes forgets to drop its allocator when the Box is conditionally initialized. #131082

Open
theemathas opened this issue Oct 1, 2024 · 2 comments · May be fixed by #131146
Open

Box sometimes forgets to drop its allocator when the Box is conditionally initialized. #131082

theemathas opened this issue Oct 1, 2024 · 2 comments · May be fixed by #131146
Assignees
Labels
A-box Area: Our favorite opsem complication A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@theemathas
Copy link
Contributor

theemathas commented Oct 1, 2024

I tried this code:

#![feature(allocator_api)]

use std::alloc::{Allocator, AllocError, Layout, Global};
use std::ptr::NonNull;

struct LoudDropAllocator;

unsafe impl Allocator for LoudDropAllocator {
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
        Global.allocate(layout)
    }
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
        Global.deallocate(ptr, layout);
    }
}
impl Drop for LoudDropAllocator {
    fn drop(&mut self) {
        println!("dropping allocator...");
    }
}

struct HasDrop;
impl Drop for HasDrop {
    fn drop(&mut self) {}
}

fn foo() {
    println!("foo()");
    let b = Box::new_in(HasDrop, LoudDropAllocator);
    if true {
        drop(*b);
    } else {
        drop(b);
    }
}

fn bar() {
    println!("bar()");
    let b = Box::new_in(HasDrop, LoudDropAllocator);
    if true {
        drop(*b);
    } else {
        // drop(b);
    }
}

fn main() {
    foo();
    bar();
}

I expected the program to output:

foo()
dropping allocator...
bar()
dropping allocator...

Instead it output:

foo()
bar()
dropping allocator...

Seems like there's something wrong with the drop flags.

Making HasDrop not implement Drop causes the program to behave as expected.

Meta

Reproducible on the playground with version 1.83.0-nightly (2024-09-30 fb4aebddd18d258046dd)

@theemathas theemathas added the C-bug Category: This is a bug. label Oct 1, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Oct 1, 2024
@beepster4096
Copy link
Contributor

@rustbot claim

@workingjubilee workingjubilee added the A-box Area: Our favorite opsem complication label Oct 1, 2024
@theemathas theemathas changed the title Box sometimes leaks its allocator when its contents are conditionally initialized. Box sometimes forgets to drop its allocator when the Box is conditionally initialized. Oct 1, 2024
@tmiasko tmiasko added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 1, 2024
@beepster4096
Copy link
Contributor

Likely caused by #100036. Tried it out on godbolt, and it doesn't reproduce before 1.72. (with RUSTC_BOOTSTRAP=1)

@beepster4096 beepster4096 linked a pull request Oct 2, 2024 that will close this issue
beepster4096 added a commit to beepster4096/rust that referenced this issue Oct 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-box Area: Our favorite opsem complication A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants