diff options
author | Björn Gustavsson <[email protected]> | 2012-01-18 09:04:05 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2012-01-18 15:50:57 +0100 |
commit | 4c6e2c2d775bc785db7de174e12227e87d2bc542 (patch) | |
tree | d4dc2557c3bbfca28169dbe5ff99f8d8d1620ca5 /lib/compiler/src | |
parent | 11d255627033bb96e7c737d35badbacae32a8631 (diff) | |
download | otp-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.erl | 11 |
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 |