diff options
author | Björn Gustavsson <[email protected]> | 2017-06-13 12:52:44 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-06-13 12:58:19 +0200 |
commit | 2820003c58097805f5ec8d2c82c3006e20662fcb (patch) | |
tree | b118507460c9450da43c68dfbe5775080ffb4771 /lib/compiler/src | |
parent | bcfa6c109f44f5d7d0d51e1a497321fdee8d166a (diff) | |
download | otp-2820003c58097805f5ec8d2c82c3006e20662fcb.tar.gz otp-2820003c58097805f5ec8d2c82c3006e20662fcb.tar.bz2 otp-2820003c58097805f5ec8d2c82c3006e20662fcb.zip |
sys_core_fold: Ensure that orddict keys are unique
All keys in an orddict must be unique. sys_core_fold:sub_sub_scope/1
broke that rule. It was probably harmless, but it is better to
avoid such rule violations.
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index cbf6e256f7..7acf08129a 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1458,8 +1458,19 @@ sub_add_scope(Vs, #sub{s=Scope0}=Sub) -> Sub#sub{s=Scope}. sub_subst_scope(#sub{v=S0,s=Scope}=Sub) -> - S = [{-1,#c_var{name=Sv}} || Sv <- cerl_sets:to_list(Scope)]++S0, - Sub#sub{v=S}. + Initial = case S0 of + [{NegInt,_}|_] when is_integer(NegInt), NegInt < 0 -> + NegInt - 1; + _ -> + -1 + end, + S = sub_subst_scope_1(cerl_sets:to_list(Scope), Initial, S0), + Sub#sub{v=orddict:from_list(S)}. + +%% The keys in an orddict must be unique. Make them so! +sub_subst_scope_1([H|T], Key, Acc) -> + sub_subst_scope_1(T, Key-1, [{Key,#c_var{name=H}}|Acc]); +sub_subst_scope_1([], _, Acc) -> Acc. sub_is_val(#c_var{name=V}, #sub{v=S,s=Scope}) -> %% When the bottleneck in sub_del_var/2 was eliminated, this |