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

UB dropping BTreeMap containing dangling items #18

Open
dtolnay opened this issue May 22, 2021 · 0 comments
Open

UB dropping BTreeMap containing dangling items #18

dtolnay opened this issue May 22, 2021 · 0 comments

Comments

@dtolnay
Copy link

dtolnay commented May 22, 2021

Based on rust-lang/unsafe-code-guidelines#283 I believe the following code illustrates UB:

use fallible_collections::btree::BTreeMap;

fn main() {
    let mut map;
    let s = "...".to_owned();
    map = BTreeMap::<&str, &str>::new();
    map.try_insert(&s, &s).unwrap();

    // s is dropped
    // then map is dropped
}

The drop of map is running this Drop impl:

unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
fn drop(&mut self) {
unsafe {
drop(ptr::read(self).into_iter());
}
}
}

Based on the IntoIterator impl for BTreeMap, that's converting BTreeMap<&'dangling str, &'dangling str> into IntoIter<&'dangling str, &'dangling str>:

impl<K, V> IntoIterator for BTreeMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;

and dropping the IntoIter using this impl:

impl<K, V> Drop for IntoIter<K, V> {
fn drop(&mut self) {
self.for_each(drop);

However, that ends up materializing a (&'dangling str, &'dangling str) as part of doing self.for_each(drop). As I understand it, it's UB to touch/pass/return dangling references like that by value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant