diff options
| author | bors <bors@rust-lang.org> | 2021-09-12 20:48:09 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-09-12 20:48:09 +0000 |
| commit | 51e514c0fb4f9afcaae3b02dd9ccb93e15b30ef8 (patch) | |
| tree | 5cc0a4eaf3c88e826459f84b2a623026feed2195 /compiler/rustc_session/src | |
| parent | d2dfb0eb8e30d188fb1731e540bc1b418bcd046d (diff) | |
| parent | 5862a0004a65e32ea3a36d33c52e305cd75a69fe (diff) | |
Auto merge of #88759 - Amanieu:panic_in_drop, r=nagisa,eddyb
Add -Z panic-in-drop={unwind,abort} command-line option
This PR changes `Drop` to abort if an unwinding panic attempts to escape it, making the process abort instead. This has several benefits:
- The current behavior when unwinding out of `Drop` is very unintuitive and easy to miss: unwinding continues, but the remaining drops in scope are simply leaked.
- A lot of unsafe code doesn't expect drops to unwind, which can lead to unsoundness:
- https://github.com/servo/rust-smallvec/issues/14
- https://github.com/bluss/arrayvec/issues/3
- There is a code size and compilation time cost to this: LLVM needs to generate extra landing pads out of all calls in a drop implementation. This can compound when functions are inlined since unwinding will then continue on to process drops in the callee, which can itself unwind, etc.
- Initial measurements show a 3% size reduction and up to 10% compilation time reduction on some crates (`syn`).
One thing to note about `-Z panic-in-drop=abort` is that *all* crates must be built with this option for it to be sound since it makes the compiler assume that dropping `Box<dyn Any>` will never unwind.
cc https://github.com/rust-lang/lang-team/issues/97
Diffstat (limited to 'compiler/rustc_session/src')
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 447be84b5a7..bb29a87035e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -349,6 +349,7 @@ mod desc { pub const parse_threads: &str = parse_number; pub const parse_passes: &str = "a space-separated list of passes, or `all`"; pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; + pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `hwaddress`, `leak`, `memory` or `thread`"; @@ -549,7 +550,7 @@ mod parse { } } - crate fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool { + crate fn parse_opt_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool { match v { Some("unwind") => *slot = Some(PanicStrategy::Unwind), Some("abort") => *slot = Some(PanicStrategy::Abort), @@ -558,6 +559,15 @@ mod parse { true } + crate fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool { + match v { + Some("unwind") => *slot = PanicStrategy::Unwind, + Some("abort") => *slot = PanicStrategy::Abort, + _ => return false, + } + true + } + crate fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool { match v { Some(s) => match s.parse::<RelroLevel>() { @@ -958,7 +968,7 @@ options! { "optimization level (0-3, s, or z; default: 0)"), overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED], "use overflow checks for integer arithmetic"), - panic: Option<PanicStrategy> = (None, parse_panic_strategy, [TRACKED], + panic: Option<PanicStrategy> = (None, parse_opt_panic_strategy, [TRACKED], "panic strategy to compile crate with"), passes: Vec<String> = (Vec::new(), parse_list, [TRACKED], "a list of extra LLVM passes to run (space separated)"), @@ -1186,6 +1196,8 @@ options! { "pass `-install_name @rpath/...` to the macOS linker (default: no)"), panic_abort_tests: bool = (false, parse_bool, [TRACKED], "support compiling tests with panic=abort (default: no)"), + panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED], + "panic strategy for panics in drops"), parse_only: bool = (false, parse_bool, [UNTRACKED], "parse only; do not compile, assemble, or link (default: no)"), partially_uninit_const_threshold: Option<usize> = (None, parse_opt_number, [TRACKED], |
