Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
0615-Eliminate-crash-in-beam_kernel_to_ssa.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0615-Eliminate-crash-in-beam_kernel_to_ssa.patch of Package erlang
From ff05beecae2e002914515e94ab59930026dc9a75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Mon, 19 Dec 2022 08:31:40 +0100 Subject: [PATCH] Eliminate crash in beam_kernel_to_ssa The `sys_core_fold` does a fixpoint iteration, limited to at most 20 iterations. One of the optimizations (coalescing two `let` constructs) would temporarily generate unsafe code, which would eventually be corrected, **unless** the 20 iteration limit was reached. Closes #6572 --- lib/compiler/src/sys_core_fold.erl | 28 +++++++++++++++-- lib/compiler/test/core_fold_SUITE.erl | 43 +++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 9021d9eb5c..206f39e190 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -2197,7 +2197,7 @@ simplify_fun_call(V, Values, #c_fun{vars=Vars,body=FunBody}, CallArgs) -> simplify_let(#c_let{arg=Arg}=Let, Sub) -> move_let_into_expr(Let, Arg, Sub). -move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner, +move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner0, #c_let{vars=OuterVs0,arg=Arg0,body=OuterBody0}=Outer, Sub0) -> %% %% let <InnerVars> = let <OuterVars> = <Arg> @@ -2218,8 +2218,30 @@ move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner, {InnerVs,Sub} = var_list(InnerVs0, Sub0), InnerBody = body(InnerBody0, Sub), - Outer#c_let{vars=OuterVs,arg=Arg, - body=Inner#c_let{vars=InnerVs,arg=OuterBody,body=InnerBody}}; + Inner = case will_fail(OuterBody) of + true -> + %% + %% Avoid creating potentially unsafe code that + %% depends on another iteration of the outer + %% fixpoint loop to clean up. If <OuterBody> + %% consists of nested lets, we may run out of + %% iterations before the unsafe code is + %% eliminated. + %% + %% let <InnerVars> = let <OuterVars> = <Arg> + %% in <OuterBody> + %% in <InnerBody> + %% + %% ==> + %% + %% let <OuterVars> = <Arg> + %% in <OuterBody> + %% + OuterBody; + false -> + Inner0#c_let{vars=InnerVs,arg=OuterBody,body=InnerBody} + end, + Outer#c_let{vars=OuterVs,arg=Arg,body=Inner}; move_let_into_expr(#c_let{vars=Lvs0,body=Lbody0}=Let, #c_case{arg=Cexpr0,clauses=[Ca0|Cs0]}=Case, Sub0) -> case not is_failing_clause(Ca0) andalso diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl index 4da55bed2e..de2b46e7a8 100644 --- a/lib/compiler/test/core_fold_SUITE.erl +++ b/lib/compiler/test/core_fold_SUITE.erl @@ -29,7 +29,7 @@ no_no_file/1,configuration/1,supplies/1, redundant_stack_frame/1,export_from_case/1, empty_values/1,cover_letrec_effect/1, - receive_effect/1]). + receive_effect/1,nested_lets/1]). -export([foo/0,foo/1,foo/2,foo/3]). @@ -50,7 +50,7 @@ groups() -> no_no_file,configuration,supplies, redundant_stack_frame,export_from_case, empty_values,cover_letrec_effect, - receive_effect]}]. + receive_effect,nested_lets]}]. init_per_suite(Config) -> @@ -700,4 +700,43 @@ receive_effect(_Config) -> do_receive_effect() -> {} = receive _ -> {} = {} end. +nested_lets(_Config) -> + {'EXIT',{{case_clause,ok},_}} = catch nested_lets_gh_6572(<<42>>), + ok. + +nested_lets_gh_6572(<<X>>) -> + Y = + case ok of + X -> + true = (ok > ((Y = _) = -1)), + <<>> = + {id( + << + (ok - ok), + (bnot ok), + (nested_lets_gh_6572_f() band ok), + (nested_lets_gh_6572_f()), + (not ok), + (ok or nested_lets_gh_6572_f()), + (id( + id( + << + (id( + << + (id( + <<0 || _ <- []>> + )) + >> + ) * ok) + >> + ) + )) + >> + )} + end. + +nested_lets_gh_6572_f() -> + ok. + +%%% Common utility functions. id(I) -> I. -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor