aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-01-18 09:04:05 +0100
committerBjörn Gustavsson <[email protected]>2012-01-18 15:50:57 +0100
commit4c6e2c2d775bc785db7de174e12227e87d2bc542 (patch)
treed4dc2557c3bbfca28169dbe5ff99f8d8d1620ca5 /lib/compiler/src
parent11d255627033bb96e7c737d35badbacae32a8631 (diff)
downloadotp-4c6e2c2d775bc785db7de174e12227e87d2bc542.tar.gz
otp-4c6e2c2d775bc785db7de174e12227e87d2bc542.tar.bz2
otp-4c6e2c2d775bc785db7de174e12227e87d2bc542.zip
compiler: Correct live calculation when get/1 is used in try...catch
In the following code excerpt, the instruction marked below was incorrectly removed: . . . {'try',{y,2},{f,TryCaseLabel}}. {bif,get,{f,0},[{x,0}],{x,0}}. {move,{x,1},{y,0}}. {move,{x,3},{y,1}}. <======= Incorrectly removed {jump,{f,TryEndLabel}}. {label,TryEndLabel}. {try_end,{y,2}}. {deallocate,3}. return. {label,TryCaseLabel}. {try_case,{y,2}}. . . . beam_utils indicated that {y,1} was not used at TryEndLabel, which by itself is correct. But it is still not safe to remove the instruction, because {y,1} might be used at TryCaseLabel if an exception occurs. Noticed-by: Eric Merritt
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_utils.erl11
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index a631b8cd69..116ede0bc9 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -474,8 +474,15 @@ check_liveness(R, [{make_fun2,_,_,_,NumFree}|Is], St) ->
end;
check_liveness(R, [{try_end,Y}|Is], St) ->
case R of
- Y -> {killed,St};
- _ -> check_liveness(R, Is, St)
+ Y ->
+ {killed,St};
+ {y,_} ->
+ %% y registers will be used if an exception occurs and
+ %% control transfers to the label given in the previous
+ %% try/2 instruction.
+ {used,St};
+ _ ->
+ check_liveness(R, Is, St)
end;
check_liveness(R, [{catch_end,Y}|Is], St) ->
case R of