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

Double free with &mut pointers to temporaries #7972

Closed
dotdash opened this issue Jul 22, 2013 · 4 comments · Fixed by #9902
Closed

Double free with &mut pointers to temporaries #7972

dotdash opened this issue Jul 22, 2013 · 4 comments · Fixed by #9902
Labels
A-codegen Area: Code generation I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. P-medium Medium priority
Milestone

Comments

@dotdash
Copy link
Contributor

dotdash commented Jul 22, 2013

fn foo(x: &mut ~u8) {
    *x = ~5;
}

fn main() {
    foo(&mut ~4);
}

crashes with a double free, because the glue call in main tries to free the originally allocated memory that was already freed by the assignment in foo.

define void @"_ZN4main16_9c508369d68e95d7_0$x2e0E"({ i64, %tydesc*, i8*, i8*, i8 }*) #4 {
"function top level":
  %1 = alloca i8*
  %2 = alloca { i8*, i32 }
  %3 = alloca i8*
  %4 = alloca i8*
  %5 = call i8* @"_ZN2rt11global_heap15exchange_malloc16_a0e6b1fccad656a7_0$x2e0E"({ i64, %tydesc*, i8*, i8*, i8 }* undef, i64 1)
  store i8 4, i8* %5
  store i8* %5, i8** %1
  invoke void @"_ZN3foo17_6b2c235046b35a5e7_0$x2e0E"({ i64, %tydesc*, i8*, i8*, i8 }* undef, i8** %1)
          to label %"normal return" unwind label %unwind

"normal return":                                  ; preds = %"function top level"
  store i8* %5, i8** %4
  %6 = bitcast i8** %4 to i32**
  call void @"_ZN8_$UP$u3217_7656cd521ad1a3b614glue_free_3306E"({}* null, i32** %6)
  ret void

unwind:                                           ; preds = %"function top level"
  %7 = landingpad { i8*, i32 } personality i32 ()* @upcall_rust_personality
          cleanup
  call void @upcall_reset_stack_limit()
  store { i8*, i32 } %7, { i8*, i32 }* %2
  br label %cleanup

cleanup:                                          ; preds = %unwind
  store i8* %5, i8** %3     // BAD: %5 the original value, not the new one
  %8 = bitcast i8** %3 to i32**
  call void @"_ZN8_$UP$u3217_7656cd521ad1a3b614glue_free_3306E"({}* null, i32** %8)
  %9 = load { i8*, i32 }* %2
  resume { i8*, i32 } %9
}
@catamorphism
Copy link
Contributor

Reproduced with 9883a62. This seems pretty bad -- nominating for milestone 5, production-ready

@nikomatsakis
Copy link
Contributor

cc me

@thestinger
Copy link
Contributor

Maybe related to #9758.

@catamorphism
Copy link
Contributor

1.0, high priority

bors added a commit that referenced this issue Oct 17, 2013
The code generation previously assumed a reference could not alter the
value in a way the destructor would notice. This is an incorrect
assumption for `&mut`, and is also incorrect for an `&` pointer to a
non-`Freeze` type.

Closes #7972
flip1995 pushed a commit to flip1995/rust that referenced this issue Feb 24, 2022
…teffen

Improve `redundant_slicing` lint

fixes rust-lang#7972
fixes rust-lang#7257

This can supersede rust-lang#7976

changelog: Fix suggestion for `redundant_slicing` when re-borrowing for a method call
changelog: New lint `deref_as_slicing`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. P-medium Medium priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants