aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-03-31 06:55:31 +0200
committerBjörn Gustavsson <[email protected]>2016-03-31 10:03:38 +0200
commit7d06e5ecd47ef071eb8c4e58ead70e79fa4b02b2 (patch)
tree54dffc98449cde17cdd12b73101508afae16b40b /erts/emulator/test
parentd166fec5d5c901a93e21a1ea7b3165b6fe68d320 (diff)
downloadotp-7d06e5ecd47ef071eb8c4e58ead70e79fa4b02b2.tar.gz
otp-7d06e5ecd47ef071eb8c4e58ead70e79fa4b02b2.tar.bz2
otp-7d06e5ecd47ef071eb8c4e58ead70e79fa4b02b2.zip
Fix unsafe transformation of apply/3 with fixed arguments
62473daf introduced an unsafe optimization in the loader. See the comments in the test case for an explanation of the problem.
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/beam_SUITE.erl45
1 files changed, 42 insertions, 3 deletions
diff --git a/erts/emulator/test/beam_SUITE.erl b/erts/emulator/test/beam_SUITE.erl
index 07dfeb6633..f61ab431e9 100644
--- a/erts/emulator/test/beam_SUITE.erl
+++ b/erts/emulator/test/beam_SUITE.erl
@@ -24,9 +24,9 @@
init_per_group/2,end_per_group/2,
packed_registers/1, apply_last/1, apply_last_bif/1,
buildo_mucho/1, heap_sizes/1, big_lists/1, fconv/1,
- select_val/1]).
+ select_val/1, swap_temp_apply/1]).
--export([applied/2]).
+-export([applied/2,swap_temp_applied/1]).
-include_lib("common_test/include/ct.hrl").
@@ -34,7 +34,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[packed_registers, apply_last, apply_last_bif,
- buildo_mucho, heap_sizes, big_lists, select_val].
+ buildo_mucho, heap_sizes, big_lists, select_val,
+ swap_temp_apply].
groups() ->
[].
@@ -346,3 +347,41 @@ do_select_val(X) ->
Int when is_integer(Int) ->
integer
end.
+
+swap_temp_apply(_Config) ->
+ {swap_temp_applied,42} = do_swap_temp_apply(41),
+ not_an_integer = do_swap_temp_apply(not_an_integer),
+ ok.
+
+do_swap_temp_apply(Msg) ->
+ case swap_temp_apply_function(Msg) of
+ undefined -> Msg;
+ Type ->
+ %% The following sequence:
+ %% move {x,0} {x,2}
+ %% move {y,0} {x,0}
+ %% move {x,2} {y,0}
+ %% apply 1
+ %%
+ %% Would be incorrectly transformed to:
+ %% swap {x,0} {y,0}
+ %% apply 1
+ %%
+ %% ({x,1} is the module, {x,2} the function to be applied).
+ %%
+ %% If the instructions are to be transformed, the correct
+ %% transformation is:
+ %%
+ %% swap_temp {x,0} {y,0} {x,2}
+ %% apply 1
+ Fields = ?MODULE:Type(Msg),
+ {Type,Fields}
+ end.
+
+swap_temp_apply_function(Int) when is_integer(Int) ->
+ swap_temp_applied;
+swap_temp_apply_function(_) ->
+ undefined.
+
+swap_temp_applied(Int) ->
+ Int+1.