Skip to content

if true { ... } runs destructors twice #10734

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

Closed
alexcrichton opened this issue Nov 30, 2013 · 7 comments · Fixed by #10735
Closed

if true { ... } runs destructors twice #10734

alexcrichton opened this issue Nov 30, 2013 · 7 comments · Fixed by #10735
Labels
A-codegen Area: Code generation

Comments

@alexcrichton
Copy link
Member

$ cat foo.rs                        
fn main() {
    if true {
        let _a = ~2;
    } else {
        fail!()
    }
}
$ rustc foo.rs 
$ ./foo    
foo(23204,0x107be0000) malloc: *** error for object 0x7fd132c02790: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
zsh: abort      ./foo

Doesn't get much worse than that. Nominating because this is terrible.

@alexcrichton
Copy link
Member Author

(editing previous comment about unsure destructors are running twice)

Correction, I'm now 100% sure that destructors are running twice:

struct Foo;                      

impl Drop for Foo {              
    fn drop(&mut self) {         
        println!("dropping");
    }                            
}                                
fn main() {                      
    if true {                    
        let _a = Foo;            
    }                            
}                                

That code prints dropping twice.

@emberian
Copy link
Member

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println("dropping");
    }
}

fn main() {
    let x = true;
    if x {
        let a = Foo;
    }
}

does not reproduce. Also cannot reproduce on 0.8; bisecting.

@lilyball
Copy link
Contributor

I can't reproduce with static x: bool = true either, or if { true } { ... }. I can reproduce with if !!!false { ... } though, which is interesting. Also if 0 == 0 { ... }

@emberian
Copy link
Member

My bisection says #9751 broke it.

@lilyball
Copy link
Contributor

Disabling the if true { .. } special-case in middle::trans::controlflow::trans_if() fixes the issue.

@emberian
Copy link
Member

However, with #[unsafe_no_drop_flag] on the struct, this reproduces on 0.8

@lilyball
Copy link
Contributor

Whoa.

if false {
} else {
    let _a = Foo;
}

drops a whopping three times.

bors added a commit that referenced this issue Nov 30, 2013
Turns out `with_scope` already translates destructors, so by manually
translating destructors we end up running them all twice (bad).

Closes #10734
mstewartgallus added a commit to mstewartgallus/rust that referenced this issue Mar 24, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue May 5, 2023
Update macros.rs (typo)

r? `@Alexendoo`

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants