diff options
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 10 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 45 | ||||
-rw-r--r-- | lib/compiler/test/beam_type_SUITE.erl | 18 | ||||
-rw-r--r-- | lib/compiler/test/bs_construct_SUITE.erl | 18 | ||||
-rw-r--r-- | lib/compiler/test/bs_match_SUITE.erl | 18 | ||||
-rw-r--r-- | lib/compiler/test/compile_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/compiler/test/test_lib.erl | 11 |
7 files changed, 68 insertions, 56 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 4fba3fa1c6..efd2be94cb 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -2899,8 +2899,6 @@ lists_mod_return_type(filter, 2, _Vst) -> list; lists_mod_return_type(flatten, 1, _Vst) -> list; -lists_mod_return_type(flatten, 2, _Vst) -> - list; lists_mod_return_type(map, 2, Vst) -> same_length_type({x,1}, Vst); lists_mod_return_type(MF, 3, Vst) when MF =:= mapfoldl; MF =:= mapfoldr -> @@ -2912,8 +2910,6 @@ lists_mod_return_type(reverse, 1, Vst) -> same_length_type({x,0}, Vst); lists_mod_return_type(seq, 2, _Vst) -> list; -lists_mod_return_type(seq, 3, _Vst) -> - list; lists_mod_return_type(sort, 1, Vst) -> same_length_type({x,0}, Vst); lists_mod_return_type(sort, 2, Vst) -> @@ -2927,16 +2923,10 @@ lists_mod_return_type(unzip, 1, Vst) -> two_tuple(ListType, ListType); lists_mod_return_type(usort, 1, Vst) -> same_length_type({x,0}, Vst); -lists_mod_return_type(usort, 2, Vst) -> - same_length_type({x,1}, Vst); lists_mod_return_type(zip, 2, _Vst) -> list; -lists_mod_return_type(zip3, 3, _Vst) -> - list; lists_mod_return_type(zipwith, 3, _Vst) -> list; -lists_mod_return_type(zipwith3, 4, _Vst) -> - list; lists_mod_return_type(_, _, _) -> term. diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 7e219da0af..4939a94a92 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1997,53 +1997,22 @@ case_opt_compiler_generated(Core) -> %% case_expand_var(Expr0, Sub) -> Expr -%% If Expr0 is a variable that has been previously matched and -%% is known to be a tuple, return the tuple instead. Otherwise +%% If Expr0 is a variable that is known to be bound to a +%% constructed tuple, return the tuple instead. Otherwise %% return Expr0 unchanged. -%% + case_expand_var(E, #sub{t=Tdb}) -> Key = cerl:var_name(E), case Tdb of - #{Key:=T0} -> - case cerl:is_c_tuple(T0) of - false -> - E; - true -> - %% The pattern was a tuple. Now we must make sure - %% that the elements of the tuple are suitable. In - %% particular, we don't want binary or map - %% construction here, since that means that the - %% binary or map will be constructed in the 'case' - %% argument. That is wasteful for binaries. Even - %% worse is that any map pattern that use the ':=' - %% operator will fail when used in map - %% construction (only the '=>' operator is allowed - %% when constructing a map from scratch). - try - cerl_trees:map(fun coerce_to_data/1, T0) - catch - throw:impossible -> - %% Something unsuitable was found (map or - %% or binary). Keep the variable. - E - end + #{Key:=T} -> + case cerl:is_c_tuple(T) of + false -> E; + true -> T end; _ -> E end. -%% coerce_to_data(Core) -> Core' -%% Coerce an element originally from a pattern to an data item or or -%% variable. Throw an 'impossible' exception if non-data Core Erlang -%% terms such as binary construction or map construction are -%% encountered. - -coerce_to_data(C) -> - case cerl:is_data(C) orelse cerl:is_c_var(C) of - true -> C; - false -> throw(impossible) - end. - %% case_opt_nomatch(E, Clauses, LitExpr) -> Clauses' %% Remove all clauses that cannot possibly match. diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl index a7ffc3f60a..882e281a44 100644 --- a/lib/compiler/test/beam_type_SUITE.erl +++ b/lib/compiler/test/beam_type_SUITE.erl @@ -24,7 +24,7 @@ integers/1,numbers/1,coverage/1,booleans/1,setelement/1, cons/1,tuple/1,record_float/1,binary_float/1,float_compare/1, arity_checks/1,elixir_binaries/1,find_best/1, - test_size/1]). + test_size/1,cover_lists_functions/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -46,7 +46,8 @@ groups() -> arity_checks, elixir_binaries, find_best, - test_size + test_size, + cover_lists_functions ]}]. init_per_suite(Config) -> @@ -473,5 +474,18 @@ do_test_size(Term) when is_tuple(Term) -> do_test_size(Term) when is_binary(Term) -> size(Term). +cover_lists_functions(Config) -> + case lists:suffix([no|Config], Config) of + true -> + ct:fail(should_be_false); + false -> + ok + end, + Zipped = lists:zipwith(fun(A, B) -> {A,B} end, + lists:duplicate(length(Config), zip), + Config), + true = is_list(Zipped), + ok. + id(I) -> I. diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl index 69017d87e7..bccd70d6cb 100644 --- a/lib/compiler/test/bs_construct_SUITE.erl +++ b/lib/compiler/test/bs_construct_SUITE.erl @@ -27,6 +27,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2,end_per_testcase/2, + verify_highest_opcode/1, two/1,test1/1,fail/1,float_bin/1,in_guard/1,in_catch/1, nasty_literals/1,coerce_to_float/1,side_effect/1, opt/1,otp_7556/1,float_arith/1,otp_8054/1, @@ -43,7 +44,8 @@ all() -> groups() -> [{p,[parallel], - [two,test1,fail,float_bin,in_guard,in_catch, + [verify_highest_opcode, + two,test1,fail,float_bin,in_guard,in_catch, nasty_literals,side_effect,opt,otp_7556,float_arith, otp_8054,cover]}]. @@ -68,6 +70,20 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> ok. +verify_highest_opcode(_Config) -> + case ?MODULE of + bs_construct_r21_SUITE -> + {ok,Beam} = file:read_file(code:which(?MODULE)), + case test_lib:highest_opcode(Beam) of + Highest when Highest =< 163 -> + ok; + TooHigh -> + ct:fail({too_high_opcode_for_21,TooHigh}) + end; + _ -> + ok + end. + two(Config) when is_list(Config) -> <<0,1,2,3,4,6,7,8,9>> = two_1([0], [<<1,2,3,4>>,<<6,7,8,9>>]), ok. diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index 2cfcb841a7..41e4918b1e 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -24,6 +24,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2,end_per_testcase/2, + verify_highest_opcode/1, size_shadow/1,int_float/1,otp_5269/1,null_fields/1,wiger/1, bin_tail/1,save_restore/1, partitioned_bs_match/1,function_clause/1, @@ -60,7 +61,8 @@ all() -> groups() -> [{p,[], - [size_shadow,int_float,otp_5269,null_fields,wiger, + [verify_highest_opcode, + size_shadow,int_float,otp_5269,null_fields,wiger, bin_tail,save_restore, partitioned_bs_match,function_clause,unit, shared_sub_bins,bin_and_float,dec_subidentifiers, @@ -101,6 +103,20 @@ init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> end_per_testcase(Case, Config) when is_atom(Case), is_list(Config) -> ok. +verify_highest_opcode(_Config) -> + case ?MODULE of + bs_match_r21_SUITE -> + {ok,Beam} = file:read_file(code:which(?MODULE)), + case test_lib:highest_opcode(Beam) of + Highest when Highest =< 163 -> + ok; + TooHigh -> + ct:fail({too_high_opcode_for_21,TooHigh}) + end; + _ -> + ok + end. + size_shadow(Config) when is_list(Config) -> %% Originally OTP-5270. 7 = size_shadow_1(), diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 408af80dd9..53627b9d81 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -1431,9 +1431,7 @@ bc_options(Config) -> highest_opcode(DataDir, Mod, Opt) -> Src = filename:join(DataDir, atom_to_list(Mod)++".erl"), {ok,Mod,Beam} = compile:file(Src, [binary|Opt]), - {ok,{Mod,[{"Code",Code}]}} = beam_lib:chunks(Beam, ["Code"]), - <<16:32,0:32,HighestOpcode:32,_/binary>> = Code, - HighestOpcode. + test_lib:highest_opcode(Beam). deterministic_include(Config) when is_list(Config) -> DataDir = proplists:get_value(data_dir, Config), diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl index 39c26c6142..3348c6e9ea 100644 --- a/lib/compiler/test/test_lib.erl +++ b/lib/compiler/test/test_lib.erl @@ -22,7 +22,8 @@ -include_lib("common_test/include/ct.hrl"). -compile({no_auto_import,[binary_part/2]}). -export([id/1,recompile/1,parallel/0,uniq/0,opt_opts/1,get_data_dir/1, - is_cloned_mod/1,smoke_disasm/1,p_run/2]). + is_cloned_mod/1,smoke_disasm/1,p_run/2, + highest_opcode/1]). %% Used by test case that override BIFs. -export([binary_part/2,binary/1]). @@ -113,6 +114,14 @@ is_cloned_mod_1("_no_module_opt_SUITE") -> true; is_cloned_mod_1([_|T]) -> is_cloned_mod_1(T); is_cloned_mod_1([]) -> false. +%% Return the highest opcode use in the BEAM module. + +highest_opcode(Beam) -> + {ok,{_Mod,[{"Code",Code}]}} = beam_lib:chunks(Beam, ["Code"]), + FormatNumber = 0, + <<16:32,FormatNumber:32,HighestOpcode:32,_/binary>> = Code, + HighestOpcode. + %% p_run(fun(Data) -> ok|error, List) -> ok %% Will fail the test case if there were any errors. |