aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_block.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-02-14 08:04:04 +0100
committerGitHub <[email protected]>2018-02-14 08:04:04 +0100
commit57b5a2bff8b69a1afb6f661a5be6718f0848c616 (patch)
tree16d5ebf3e0473bce4be2a4a4b45e05c27c0c3596 /lib/compiler/src/beam_block.erl
parentdb7c5ee3c64a7039fe1efda939167ebb954c31bf (diff)
parenta48ec9a2750260845f035c2e968244cb5cd33a3d (diff)
downloadotp-57b5a2bff8b69a1afb6f661a5be6718f0848c616.tar.gz
otp-57b5a2bff8b69a1afb6f661a5be6718f0848c616.tar.bz2
otp-57b5a2bff8b69a1afb6f661a5be6718f0848c616.zip
Merge pull request #1713 from bjorng/bjorn/compiler/fix-unsafe-allocate
Fix unsafe use of 'allocate' where 'allocate_zero' should be used
Diffstat (limited to 'lib/compiler/src/beam_block.erl')
-rw-r--r--lib/compiler/src/beam_block.erl10
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 9543aa1355..7183381334 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -206,7 +206,7 @@ move_allocates([]) -> [].
move_allocates_1([{'%anno',_}|Is], Acc) ->
move_allocates_1(Is, Acc);
-move_allocates_1([I|Is], [{set,[],[],{alloc,Live0,Info}}|Acc]=Acc0) ->
+move_allocates_1([I|Is], [{set,[],[],{alloc,Live0,Info0}}|Acc]=Acc0) ->
case alloc_may_pass(I) of
false ->
move_allocates_1(Is, [I|Acc0]);
@@ -215,6 +215,7 @@ move_allocates_1([I|Is], [{set,[],[],{alloc,Live0,Info}}|Acc]=Acc0) ->
not_possible ->
move_allocates_1(Is, [I|Acc0]);
Live when is_integer(Live) ->
+ Info = safe_info(Info0),
A = {set,[],[],{alloc,Live,Info}},
move_allocates_1(Is, [A,I|Acc])
end
@@ -230,6 +231,13 @@ alloc_may_pass({set,_,_,put_list}) -> false;
alloc_may_pass({set,_,_,put}) -> false;
alloc_may_pass({set,_,_,_}) -> true.
+safe_info({nozero,Stack,Heap,_}) ->
+ %% nozero is not safe if the allocation instruction is moved
+ %% upwards past an instruction that may throw an exception
+ %% (such as element/2).
+ {zero,Stack,Heap,[]};
+safe_info(Info) -> Info.
+
%% opt([Instruction]) -> [Instruction]
%% Optimize the instruction stream inside a basic block.