Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compiler: Don't apply beam_ssa_type to unreachable functions #7512

Closed
wants to merge 1 commit into from

Conversation

frej
Copy link
Contributor

@frej frej commented Jul 26, 2023

The beam_ssa_type:opt_continue/4 pass requires that type information is available for all arguments or else it will crash with a back trace similar to this:

Sub pass ssa_opt_type_continue
Function: '-f3/1-lc$^0/1-3-'/1
test362604.erl: internal error in pass beam_ssa_opt: exception error: no function clause matching beam_types:join([])
  in function  beam_ssa_type:join_arg_types/3 (beam_ssa_type.erl, line 449)
  in call from beam_ssa_type:opt_continue/4 (beam_ssa_type.erl, line 432)
  in call from beam_ssa_opt:ssa_opt_type_continue/1 (beam_ssa_opt.erl, line 449)
  in call from compile:run_sub_passes_1/3 (compile.erl, line 424)
  in call from beam_ssa_opt:phase/4 (beam_ssa_opt.erl, line 116)
  in call from beam_ssa_opt:fixpoint/6 (beam_ssa_opt.erl, line 99)
  in call from beam_ssa_opt:run_phases/3 (beam_ssa_opt.erl, line 85)

If type analysis during beam_ssa_type:opt_start/2 concludes that a function is never called, type information for the callee will never be recorded, thus leaving no type information for the arguments in the function's entry in the function database, leading to the crash above.

Although naively unreachable functions are pruned when the list of functions is first traversed in beam_ssa_type:opt_start/2, it doesn't handle they case when type inference concludes that a function is never called. This patch extends beam_ssa_type:opt_start/2 to, when all functions have been processed, prune non-exported functions for which #func_info.arg_types is just a list of empty dictionaries. That a function of zero arity is always considered reachable, is harmless as it won't crash opt_continue/4.

Closes #7509
Closes #7478

@github-actions
Copy link
Contributor

github-actions bot commented Jul 26, 2023

CT Test Results

       2 files     296 suites   12m 55s ⏱️
   778 tests    776 ✔️ 2 💤 0
4 921 runs  4 919 ✔️ 2 💤 0

Results for commit b3ca23f.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@RobinMorisset RobinMorisset left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I don't know that code well, so I recommend waiting for a review by @jhogberg or @bjorng.

@@ -109,8 +109,40 @@ opt_start_1([Id | Ids], ArgDb, StMap0, FuncDb0, MetaCache) ->
opt_start_1(Ids, ArgDb, StMap, FuncDb, MetaCache)
end;
opt_start_1([], _CommittedArgs, StMap, FuncDb, _MetaCache) ->
%% Although unreachable functions are pruned when the list of
%% functions is first traversed above, it doesn't handle they case
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: they -> the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

The beam_ssa_type:opt_continue/4 pass requires that type information
is available for all arguments or else it will crash with a back trace
similar to this:

Sub pass ssa_opt_type_continue
Function: '-f3/1-lc$^0/1-3-'/1
test362604.erl: internal error in pass beam_ssa_opt:
exception error: no function clause matching beam_types:join([])
  in function  beam_ssa_type:join_arg_types/3 (beam_ssa_type.erl, line 449)
  in call from beam_ssa_type:opt_continue/4 (beam_ssa_type.erl, line 432)
  in call from beam_ssa_opt:ssa_opt_type_continue/1 (beam_ssa_opt.erl, line 449)
  in call from compile:run_sub_passes_1/3 (compile.erl, line 424)
  in call from beam_ssa_opt:phase/4 (beam_ssa_opt.erl, line 116)
  in call from beam_ssa_opt:fixpoint/6 (beam_ssa_opt.erl, line 99)
  in call from beam_ssa_opt:run_phases/3 (beam_ssa_opt.erl, line 85)

If type analysis during beam_ssa_type:opt_start/2 concludes that a
function is never called, type information for the callee will never
be recorded, thus leaving no type information for the arguments in the
function's entry in the function database, leading to the crash above.

Although naively unreachable functions are pruned when the list of
functions is first traversed in beam_ssa_type:opt_start/2, it doesn't
handle they case when type inference concludes that a function is
never called. This patch extends beam_ssa_type:opt_start/2 to, when
all functions have been processed, prune non-exported functions for
which #func_info.arg_types is just a list of empty dictionaries.  That
a function of zero arity is always considered reachable, is harmless
as it won't crash opt_continue/4.

Closes erlang#7509
Closes erlang#7478
@frej
Copy link
Contributor Author

frej commented Jul 27, 2023

Withdrawn as it masks the real bug.

@frej frej closed this Jul 27, 2023
@frej frej deleted the frej/fix-7478-7509 branch February 9, 2024 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants