Skip to content

Commit

Permalink
beam_utils: Fix check_liveness/3 for receive loops
Browse files Browse the repository at this point in the history
Sometimes the beam_bool pass wants to know whether an
y register will be killed by the code that follows and
will do (effectively):

  beam_utils:is_killed({y,Y}, Code, L)

When asked to calculate the liveness for an y register,
beam_utils:is_killed/3 will loop forever if the code
includes a receive loop.

Since this rarely occurs, fix the problem in the simplest
and most conservative way.

Reported-by: Christopher Williams
  • Loading branch information
bjorng committed Dec 2, 2010
1 parent 8836ebc commit 2b03fba
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
9 changes: 6 additions & 3 deletions lib/compiler/src/beam_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,13 @@ check_liveness(R, [{bs_context_to_binary,S}|Is], St) ->
S -> {used,St};
_ -> check_liveness(R, Is, St)
end;
check_liveness(R, [{loop_rec,{f,_},{x,0}}|Is], St) ->
check_liveness(R, [{loop_rec,{f,_},{x,0}}|_], St) ->
case R of
{x,_} -> {killed,St};
_ -> check_liveness(R, Is, St)
{x,_} ->
{killed,St};
_ ->
%% y register. Rarely happens. Be very conversative.
{unknown,St}
end;
check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) ->
check_liveness_at(R, Fail, St);
Expand Down
20 changes: 19 additions & 1 deletion lib/compiler/test/compilation_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ all(suite) ->
trycatch_4, opt_crash,
otp_5404,otp_5436,otp_5481,otp_5553,otp_5632,
otp_5714,otp_5872,otp_6121,otp_6121a,otp_6121b,
otp_7202,otp_7345,on_load,string_table,otp_8949_a
otp_7202,otp_7345,on_load,string_table,otp_8949_a,otp_8949_a
].

-define(comp(N),
Expand Down Expand Up @@ -628,5 +628,23 @@ otp_8949_a() ->
end
end.

otp_8949_b(Config) when is_list(Config) ->
self() ! something,
?line value = otp_8949_b([], false),
?line {'EXIT',_} = (catch otp_8949_b([], true)),
ok.

%% Would cause an endless loop in beam_utils.
otp_8949_b(A, B) ->
Var = id(value),
if
A == [], B == false ->
ok
end,
receive
something ->
id(Var)
end.


id(I) -> I.

0 comments on commit 2b03fba

Please sign in to comment.