aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2015-08-31 16:07:46 +0200
committerBjörn-Egil Dahlberg <[email protected]>2015-09-04 17:58:03 +0200
commitd0784035abb22f4f385c8a8737a7b15c3741bbca (patch)
tree93713fcdc1aa0728b3a65ba6a7fef2ee82f641e9 /lib/stdlib
parentc9bbba0db169ece606b02162057e4681b8fb1ce4 (diff)
downloadotp-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/stdlib')
0 files changed, 0 insertions, 0 deletions