diff options
author | Björn-Egil Dahlberg <[email protected]> | 2015-08-31 16:07:46 +0200 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2015-09-04 17:58:03 +0200 |
commit | d0784035abb22f4f385c8a8737a7b15c3741bbca (patch) | |
tree | 93713fcdc1aa0728b3a65ba6a7fef2ee82f641e9 /lib/diameter/src/base/diameter_watchdog.erl | |
parent | c9bbba0db169ece606b02162057e4681b8fb1ce4 (diff) | |
download | otp-d0784035abb22f4f385c8a8737a7b15c3741bbca.tar.gz otp-d0784035abb22f4f385c8a8737a7b15c3741bbca.tar.bz2 otp-d0784035abb22f4f385c8a8737a7b15c3741bbca.zip |
compiler: Fix get_map_elements register corruption
Instruction get_map_elements might destroy target registers when the fail-label is taken.
Only seen for patterns with two, and only two, target registers.
Specifically: we copy one register, and then jump.
foo(A,#{a := V1, b := V2}) -> ...
foo(A,#{b := V}) -> ...
call foo(value, #{a=>whops, c=>42}).
corresponding assembler:
{test,is_map,{f,5},[{x,1}]}.
{get_map_elements,{f,7},{x,1},{list,[{atom,a},{x,1},{atom,b},{x,2}]}}.
%% if 'a' exists but not 'b' {x,1} is overwritten, jump {f,7}
{move,{integer,1},{x,0}}.
{call_only,3,{f,10}}.
{label,7}.
{get_map_elements,{f,8},{x,1},{list,[{atom,b},{x,2}]}}.
%% {x,1} (src) is read with a corrupt value
{move,{x,0},{x,1}}.
{move,{integer,2},{x,0}}.
{call_only,3,{f,10}}.
The fix is to remove 'opt_moves' pass for get_map_elements instruction
in the case of two or more destinations.
Reported-by: Valery Tikhonov
Diffstat (limited to 'lib/diameter/src/base/diameter_watchdog.erl')
0 files changed, 0 insertions, 0 deletions