From 6c968a18962ea85f9b426d98fbd3c7b3e527c038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 25 Sep 2018 14:03:52 +0200 Subject: beam_validator: Use set_aliased_type in more operations The following code broke because aliases weren't tracked for hd/1: bug(Bool) -> Bug = remote:call(), if Bool -> %% Branch of some kind. _ = hd(Bug), remote:call(), hd(Bug) end. Related to 1f221b27f1336e747f7409692f260055dd3ddf79 --- lib/compiler/src/beam_validator.erl | 8 ++++---- lib/compiler/test/beam_validator_SUITE.erl | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 8d699f2abd..e76b097500 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -572,7 +572,7 @@ valfun_4({bif,tuple_size,{f,Fail},[Tuple],Dst}=I, Vst0) -> TupleType0 = get_term_type(Tuple, Vst0), Vst1 = branch_state(Fail, Vst0), TupleType = upgrade_tuple_type({tuple,[0]}, TupleType0), - Vst = set_type(TupleType, Tuple, Vst1), + Vst = set_aliased_type(TupleType, Tuple, Vst1), set_type_reg_expr({integer,[]}, I, Dst, Vst); valfun_4({bif,element,{f,Fail},[Pos,Tuple],Dst}, Vst0) -> TupleType0 = get_term_type(Tuple, Vst0), @@ -589,20 +589,20 @@ valfun_4(raw_raise=I, Vst) -> valfun_4({bif,map_get,{f,Fail},[_Key,Map]=Src,Dst}, Vst0) -> validate_src(Src, Vst0), Vst1 = branch_state(Fail, Vst0), - Vst = set_type(map, Map, Vst1), + Vst = set_aliased_type(map, Map, Vst1), Type = propagate_fragility(term, Src, Vst), set_type_reg(Type, Dst, Vst); valfun_4({bif,is_map_key,{f,Fail},[_Key,Map]=Src,Dst}, Vst0) -> validate_src(Src, Vst0), Vst1 = branch_state(Fail, Vst0), - Vst = set_type(map, Map, Vst1), + Vst = set_aliased_type(map, Map, Vst1), Type = propagate_fragility(bool, Src, Vst), set_type_reg(Type, Dst, Vst); valfun_4({bif,Op,{f,Fail},[Cons]=Src,Dst}, Vst0) when Op =:= hd; Op =:= tl -> validate_src(Src, Vst0), Vst1 = branch_state(Fail, Vst0), - Vst = set_type(cons, Cons, Vst1), + Vst = set_aliased_type(cons, Cons, Vst1), Type0 = bif_type(Op, Src, Vst), Type = propagate_fragility(Type0, Src, Vst), set_type_reg(Type, Dst, Vst); diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index d3e544a9cc..661b48a080 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -34,7 +34,7 @@ undef_label/1,illegal_instruction/1,failing_gc_guard_bif/1, map_field_lists/1,cover_bin_opt/1, val_dsetel/1,bad_tuples/1,bad_try_catch_nesting/1, - receive_stacked/1]). + receive_stacked/1,aliased_types/1]). -include_lib("common_test/include/ct.hrl"). @@ -63,7 +63,7 @@ groups() -> undef_label,illegal_instruction,failing_gc_guard_bif, map_field_lists,cover_bin_opt,val_dsetel, bad_tuples,bad_try_catch_nesting, - receive_stacked]}]. + receive_stacked,aliased_types]}]. init_per_suite(Config) -> test_lib:recompile(?MODULE), @@ -579,6 +579,21 @@ receive_stacked(Config) -> 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), + if + Config =/= [gurka, gaffel] -> %% Pointless branch. + _ = hd(Bug), + lists:seq(1, 5), + hd(Bug) + end. + %%%------------------------------------------------------------------------- transform_remove(Remove, Module) -> -- cgit v1.2.3