diff options
| author | bors <bors@rust-lang.org> | 2023-01-11 08:50:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-01-11 08:50:38 +0000 |
| commit | 8ecaad85f61375b18e1667b51a3ef350121d2ca0 (patch) | |
| tree | 86486584ce6a8c1aeca6d135f3680209f5e5eea1 | |
| parent | ca855e6e42787ecd062d81d53336fe6788ef51a9 (diff) | |
| parent | 6bb2bda23eb0ced0375ebd119454f8e95dc36db8 (diff) | |
| download | rust-8ecaad85f61375b18e1667b51a3ef350121d2ca0.tar.gz rust-8ecaad85f61375b18e1667b51a3ef350121d2ca0.zip | |
Auto merge of #105919 - uweigand:s390x-stack-overflow, r=Nilstrieb
Fix stack overflow in recursive AST walk in early lint
The src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs test case added to verify https://github.com/rust-lang/rust/issues/74564 still crashes with a stack overflow on s390x-ibm-linux.
Symptom is a very deep recursion in compiler/rustc_lint/src/early.rs:
fn visit_expr(&mut self, e: &'a ast::Expr) {
self.with_lint_attrs(e.id, &e.attrs, |cx| {
lint_callback!(cx, check_expr, e);
ast_visit::walk_expr(cx, e);
})
}
(where walk_expr recursively calls back into visit_expr). The crash happens at a nesting depth of over 17000 stack frames when using the default 8 MB stack size on s390x.
This patch fixes the problem by adding a ensure_sufficient_stack call to the with_lint_attrs routine (which also should take care of all the other mutually recursive visitors here).
Fixes part of https://github.com/rust-lang/rust/issues/105383.
| -rw-r--r-- | compiler/rustc_lint/src/early.rs | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index c18abaef8e2..d757471dcee 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -19,6 +19,7 @@ use crate::passes::{EarlyLintPass, EarlyLintPassObject}; use rustc_ast::ptr::P; use rustc_ast::visit::{self as ast_visit, Visitor}; use rustc_ast::{self as ast, walk_list, HasAttrs}; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_middle::ty::RegisteredTools; use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass}; use rustc_session::Session; @@ -71,7 +72,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { self.inlined_check_id(id); debug!("early context: enter_attrs({:?})", attrs); lint_callback!(self, enter_lint_attrs, attrs); - f(self); + ensure_sufficient_stack(|| f(self)); debug!("early context: exit_attrs({:?})", attrs); lint_callback!(self, exit_lint_attrs, attrs); self.context.builder.pop(push); |
