{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/30530","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/30530/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/30530/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/30530/events","html_url":"https://github.com/rust-lang/rust/issues/30530","id":123522792,"number":30530,"title":"Segfault in an unconditional drop call after a match","user":{"login":"sfackler","id":1455697,"avatar_url":"https://avatars.githubusercontent.com/u/1455697?v=3","gravatar_id":"","url":"https://api.github.com/users/sfackler","html_url":"https://github.com/sfackler","followers_url":"https://api.github.com/users/sfackler/followers","following_url":"https://api.github.com/users/sfackler/following{/other_user}","gists_url":"https://api.github.com/users/sfackler/gists{/gist_id}","starred_url":"https://api.github.com/users/sfackler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sfackler/subscriptions","organizations_url":"https://api.github.com/users/sfackler/orgs","repos_url":"https://api.github.com/users/sfackler/repos","events_url":"https://api.github.com/users/sfackler/events{/privacy}","received_events_url":"https://api.github.com/users/sfackler/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/I-crash","name":"I-crash","color":"e10c02"},{"url":"https://api.github.com/repos/rust-lang/rust/labels/P-high","name":"P-high","color":"eb6420"},{"url":"https://api.github.com/repos/rust-lang/rust/labels/T-compiler","name":"T-compiler","color":"bfd4f2"}],"state":"open","locked":false,"assignee":{"login":"pnkfelix","id":173127,"avatar_url":"https://avatars.githubusercontent.com/u/173127?v=3","gravatar_id":"","url":"https://api.github.com/users/pnkfelix","html_url":"https://github.com/pnkfelix","followers_url":"https://api.github.com/users/pnkfelix/followers","following_url":"https://api.github.com/users/pnkfelix/following{/other_user}","gists_url":"https://api.github.com/users/pnkfelix/gists{/gist_id}","starred_url":"https://api.github.com/users/pnkfelix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pnkfelix/subscriptions","organizations_url":"https://api.github.com/users/pnkfelix/orgs","repos_url":"https://api.github.com/users/pnkfelix/repos","events_url":"https://api.github.com/users/pnkfelix/events{/privacy}","received_events_url":"https://api.github.com/users/pnkfelix/received_events","type":"User","site_admin":false},"milestone":null,"comments":5,"created_at":"2015-12-22T17:26:36Z","updated_at":"2016-01-08T17:10:29Z","closed_at":null,"body":"This code will segfault running drop glue for `Box<Box<Fn()>>`, even though a value of that type is not actually created.\r\n```rust\r\nenum Handler {\r\n    Default,\r\n    Custom(*mut Box<Fn()>),\r\n}\r\n\r\nfn main() {\r\n    take();\r\n}\r\n\r\nfn take() -> Box<Fn()> {\r\n    unsafe {\r\n        match Handler::Default {\r\n            Handler::Default => Box::new(main),\r\n            Handler::Custom(ptr) => *Box::from_raw(ptr),\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nInterestingly, it exits successfully if the second match body is wrapped in a block."},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/170059552","html_url":"https://github.com/rust-lang/rust/issues/30530#issuecomment-170059552","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/30530","id":170059552,"user":{"login":"pnkfelix","id":173127,"avatar_url":"https://avatars.githubusercontent.com/u/173127?v=3","gravatar_id":"","url":"https://api.github.com/users/pnkfelix","html_url":"https://github.com/pnkfelix","followers_url":"https://api.github.com/users/pnkfelix/followers","following_url":"https://api.github.com/users/pnkfelix/following{/other_user}","gists_url":"https://api.github.com/users/pnkfelix/gists{/gist_id}","starred_url":"https://api.github.com/users/pnkfelix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pnkfelix/subscriptions","organizations_url":"https://api.github.com/users/pnkfelix/orgs","repos_url":"https://api.github.com/users/pnkfelix/repos","events_url":"https://api.github.com/users/pnkfelix/events{/privacy}","received_events_url":"https://api.github.com/users/pnkfelix/received_events","type":"User","site_admin":false},"created_at":"2016-01-08T17:10:29Z","updated_at":"2016-01-08T17:10:29Z","body":"> Seems like a case where we failed to initialize the temporary storage slot to 0, even though it is only conditionally initialized.\r\n\r\nYes, this looks right.\r\n\r\nIn particular, the code in trans is structured in a somewhat misleading way: there's this `populate` callback on `lvalue_scratch_datum`, where `populate` is supposed to initialize the scratch data that has been created via an `alloca()`.\r\n\r\nThe problem, I *think*, is that there is no guarantee that the populate call will dominates the cleanup code generated at the end of the scope.  The `bcx` (Block context) and the `scope` are separate inputs to `lvalue_scratch_datum`, and I think in examples like the one from this bug, the `bcx` corresponds to the match arm, while the scope is the parent of the match itself. :(\r\n\r\nI'm not completely sure the best way to fix this quickly. My current plan is to try to inject initialization code (for types that need the drop flag) that will run right after the `alloca()` does, and hopefully LLVM will be smart enough to eliminate that initialization when it is effectively dead-code due to the code generated by `populate`."}}