aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-01-16 07:02:54 +0100
committerBjörn Gustavsson <[email protected]>2015-01-26 12:58:11 +0100
commit62c1dd9d9994367da43212f1b33c9e2dacb27e4b (patch)
tree49cf924637c44c6e5fcd6f493017fc7c736289b0
parent3f7ab0ea59deedd63da8dbaa9dbdbf5666294d6c (diff)
downloadotp-62c1dd9d9994367da43212f1b33c9e2dacb27e4b.tar.gz
otp-62c1dd9d9994367da43212f1b33c9e2dacb27e4b.tar.bz2
otp-62c1dd9d9994367da43212f1b33c9e2dacb27e4b.zip
core_lib: Teach is_var_used/2 to handle keys in map patterns
is_var_used/2 did not notice that variable keys in map patterns were used, which could cause sys_core_fold to do unsafe optimizations.
-rw-r--r--lib/compiler/src/core_lib.erl13
-rw-r--r--lib/compiler/test/match_SUITE.erl18
2 files changed, 25 insertions, 6 deletions
diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl
index 0d95971f91..730e3a5317 100644
--- a/lib/compiler/src/core_lib.erl
+++ b/lib/compiler/src/core_lib.erl
@@ -236,10 +236,15 @@ vu_pat_seg_list(V, Ss, St) ->
end
end, St, Ss).
-vu_map_pairs(V, [#c_map_pair{val=Pat}|T], St0) ->
- case vu_pattern(V, Pat, St0) of
- {true,_}=St -> St;
- St -> vu_map_pairs(V, T, St)
+vu_map_pairs(V, [#c_map_pair{key=Key,val=Pat}|T], St0) ->
+ case vu_expr(V, Key) of
+ true ->
+ {true,false};
+ false ->
+ case vu_pattern(V, Pat, St0) of
+ {true,_}=St -> St;
+ St -> vu_map_pairs(V, T, St)
+ end
end;
vu_map_pairs(_, [], St) -> St.
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index e5aaf49d6f..1234197cd7 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -22,7 +22,8 @@
init_per_group/2,end_per_group/2,
pmatch/1,mixed/1,aliases/1,match_in_call/1,
untuplify/1,shortcut_boolean/1,letify_guard/1,
- selectify/1,underscore/1,match_map/1,coverage/1]).
+ selectify/1,underscore/1,match_map/1,map_vars_used/1,
+ coverage/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -36,7 +37,7 @@ groups() ->
[{p,test_lib:parallel(),
[pmatch,mixed,aliases,match_in_call,untuplify,
shortcut_boolean,letify_guard,selectify,
- underscore,match_map,coverage]}].
+ underscore,match_map,map_vars_used,coverage]}].
init_per_suite(Config) ->
@@ -412,6 +413,19 @@ do_match_map(#s{map=#{key:=Val}}=S) ->
%% Would crash with a 'badarg' exception.
S#s{t=Val}.
+map_vars_used(Config) when is_list(Config) ->
+ {some,value} = do_map_vars_used(a, b, #{{a,b}=>42,v=>{some,value}}),
+ ok.
+
+do_map_vars_used(X, Y, Map) ->
+ case {X,Y} of
+ T ->
+ %% core_lib:is_var_used/2 would not consider T used.
+ #{T:=42,v:=Val} = Map,
+ Val
+ end.
+
+
coverage(Config) when is_list(Config) ->
%% Cover beam_dead.
ok = coverage_1(x, a),