diff options
| author | bors <bors@rust-lang.org> | 2020-05-07 00:03:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-05-07 00:03:23 +0000 |
| commit | 97f3eeec8216d7155c24674b9be55e7c672bcae3 (patch) | |
| tree | 5e5b22df21838a464ae5cf900d0b4a27855edc3c /src/librustc_interface | |
| parent | 29457dd92c5c754027c18b28c9e1307a345aafec (diff) | |
| parent | 935a05f1beaa5ed872e66e521e510bba61509b48 (diff) | |
Auto merge of #55617 - oli-obk:stacker, r=nagisa,oli-obk
Prevent compiler stack overflow for deeply recursive code
I was unable to write a test that
1. runs in under 1s
2. overflows on my machine without this patch
The following reproduces the issue, but I don't think it's sensible to include a test that takes 30s to compile. We can now easily squash newly appearing overflows by the strategic insertion of calls to `ensure_sufficient_stack`.
```rust
// compile-pass
#![recursion_limit="1000000"]
macro_rules! chain {
(EE $e:expr) => {$e.sin()};
(RECURSE $i:ident $e:expr) => {chain!($i chain!($i chain!($i chain!($i $e))))};
(Z $e:expr) => {chain!(RECURSE EE $e)};
(Y $e:expr) => {chain!(RECURSE Z $e)};
(X $e:expr) => {chain!(RECURSE Y $e)};
(A $e:expr) => {chain!(RECURSE X $e)};
(B $e:expr) => {chain!(RECURSE A $e)};
(C $e:expr) => {chain!(RECURSE B $e)};
// causes overflow on x86_64 linux
// less than 1 second until overflow on test machine
// after overflow has been fixed, takes 30s to compile :/
(D $e:expr) => {chain!(RECURSE C $e)};
(E $e:expr) => {chain!(RECURSE D $e)};
(F $e:expr) => {chain!(RECURSE E $e)};
// more than 10 seconds
(G $e:expr) => {chain!(RECURSE F $e)};
(H $e:expr) => {chain!(RECURSE G $e)};
(I $e:expr) => {chain!(RECURSE H $e)};
(J $e:expr) => {chain!(RECURSE I $e)};
(K $e:expr) => {chain!(RECURSE J $e)};
(L $e:expr) => {chain!(RECURSE L $e)};
}
fn main() {
let x = chain!(D 42.0_f32);
}
```
fixes #55471
fixes #41884
fixes #40161
fixes #34844
fixes #32594
cc @alexcrichton @rust-lang/compiler
I looked at all code that checks the recursion limit and inserted stack growth calls where appropriate.
Diffstat (limited to 'src/librustc_interface')
| -rw-r--r-- | src/librustc_interface/util.rs | 9 |
1 files changed, 1 insertions, 8 deletions
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index c5a4d28d151..0797ab33827 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -81,14 +81,7 @@ pub fn create_session( (Lrc::new(sess), Lrc::new(codegen_backend), source_map) } -// Temporarily have stack size set to 32MB to deal with various crates with long method -// chains or deep syntax trees, except when on Haiku. -// FIXME(oli-obk): get https://github.com/rust-lang/rust/pull/55617 the finish line -#[cfg(not(target_os = "haiku"))] -const STACK_SIZE: usize = 32 * 1024 * 1024; - -#[cfg(target_os = "haiku")] -const STACK_SIZE: usize = 16 * 1024 * 1024; +const STACK_SIZE: usize = 8 * 1024 * 1024; fn get_stack_size() -> Option<usize> { // FIXME: Hacks on hacks. If the env is trying to override the stack size |
