diff options
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 19 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_inline.erl | 3 | ||||
-rw-r--r-- | lib/compiler/test/beam_validator_SUITE.erl | 27 |
3 files changed, 40 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 46c689e034..3d53054f69 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -828,13 +828,14 @@ valfun_4({test,is_map,{f,Lbl},[Src]}, Vst0) -> _ -> kill_state(Vst0) end; -valfun_4({test,is_nil,{f,Lbl},[Src]}, Vst) -> - case get_term_type(Src, Vst) of - list -> - branch_state(Lbl, set_type_reg(cons, Src, Vst)); - _ -> - branch_state(Lbl, Vst) - end; +valfun_4({test,is_nil,{f,Lbl},[Src]}, Vst0) -> + Vst = case get_term_type(Src, Vst0) of + list -> + branch_state(Lbl, set_type_reg(cons, Src, Vst0)); + _ -> + branch_state(Lbl, Vst0) + end, + set_aliased_type(nil, Src, Vst); valfun_4({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst0) -> validate_src(Ss, Vst0), Infer = infer_types(Src, Vst0), @@ -1903,6 +1904,10 @@ merge_types({atom,A}, bool) -> merge_bool(A); merge_types(cons, {literal,[_|_]}) -> cons; +merge_types(cons, nil) -> + list; +merge_types(nil, cons) -> + list; merge_types({literal,[_|_]}, cons) -> cons; merge_types({literal,[_|_]}, {literal,[_|_]}) -> diff --git a/lib/compiler/src/sys_core_inline.erl b/lib/compiler/src/sys_core_inline.erl index 5a6cc45e4a..3380e3f1bd 100644 --- a/lib/compiler/src/sys_core_inline.erl +++ b/lib/compiler/src/sys_core_inline.erl @@ -195,6 +195,9 @@ kill_id_anns(Body) -> cerl_trees:map(fun(#c_fun{anno=A0}=CFun) -> A = kill_id_anns_1(A0), CFun#c_fun{anno=A}; + (#c_var{anno=A0}=Var) -> + A = kill_id_anns_1(A0), + Var#c_var{anno=A}; (Expr) -> %% Mark everything as compiler generated to %% suppress bogus warnings. diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 661b48a080..c9df066958 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -579,14 +579,23 @@ receive_stacked(Config) -> ok. +aliased_types(Config) -> + Seq = lists:seq(1, 5), + 1 = aliased_types_1(Seq, Config), + + {1,1} = aliased_types_2(Seq), + {42,none} = aliased_types_2([]), + + ok. + %% ERL-735: validator failed to track types on aliased registers, rejecting %% legitimate optimizations. %% %% move x0 y0 %% bif hd L1 x0 %% get_hd y0 %% The validator failed to see that y0 was a list -aliased_types(Config) when is_list(Config) -> - Bug = lists:seq(1, 5), +%% +aliased_types_1(Bug, Config) -> if Config =/= [gurka, gaffel] -> %% Pointless branch. _ = hd(Bug), @@ -594,6 +603,17 @@ aliased_types(Config) when is_list(Config) -> hd(Bug) end. +%% ERL-832: validator failed to realize that a Y register was a cons. +aliased_types_2(Bug) -> + Res = case Bug of + [] -> id(42); + _ -> hd(Bug) + end, + {Res,case Bug of + [] -> none; + _ -> hd(Bug) + end}. + %%%------------------------------------------------------------------------- transform_remove(Remove, Module) -> @@ -652,3 +672,6 @@ night(Turned) -> ok. participating(_, _, _, _) -> ok. + +id(I) -> + I. |