diff options
| -rw-r--r-- | lib/compiler/src/beam_type.erl | 15 | ||||
| -rw-r--r-- | lib/compiler/src/beam_utils.erl | 5 | ||||
| -rw-r--r-- | lib/compiler/src/beam_validator.erl | 16 | ||||
| -rw-r--r-- | lib/compiler/test/guard_SUITE_data/guard_SUITE_tuple_size.S | 8 | ||||
| -rw-r--r-- | lib/compiler/test/misc_SUITE.erl | 9 | ||||
| -rw-r--r-- | lib/stdlib/src/erl_lint.erl | 5 | ||||
| -rw-r--r-- | lib/stdlib/test/erl_lint_SUITE.erl | 25 | ||||
| -rw-r--r-- | lib/stdlib/test/qlc_SUITE.erl | 8 | 
8 files changed, 66 insertions, 25 deletions
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl index 6f0ffb5b25..d307d192b2 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -29,10 +29,17 @@ module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->      {ok,{Mod,Exp,Attr,Fs,Lc}}.  function({function,Name,Arity,CLabel,Asm0}) -> -    Asm1 = beam_utils:live_opt(Asm0), -    Asm2 = opt(Asm1, [], tdb_new()), -    Asm = beam_utils:delete_live_annos(Asm2), -    {function,Name,Arity,CLabel,Asm}. +    try +	Asm1 = beam_utils:live_opt(Asm0), +	Asm2 = opt(Asm1, [], tdb_new()), +	Asm = beam_utils:delete_live_annos(Asm2), +	{function,Name,Arity,CLabel,Asm} +    catch +	Class:Error -> +	    Stack = erlang:get_stacktrace(), +	    io:fwrite("Function: ~w/~w\n", [Name,Arity]), +	    erlang:raise(Class, Error, Stack) +    end.  %% opt([Instruction], Accumulator, TypeDb) -> {[Instruction'],TypeDb'}  %%  Keep track of type information; try to simplify. diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index abcd93f280..194f089ba1 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -741,6 +741,9 @@ live_opt([{badmatch,Src}=I|Is], _, D, Acc) ->  live_opt([{case_end,Src}=I|Is], _, D, Acc) ->      Regs = x_live([Src], 0),      live_opt(Is, Regs, D, [I|Acc]); +live_opt([{try_case_end,Src}=I|Is], _, D, Acc) -> +    Regs = x_live([Src], 0), +    live_opt(Is, Regs, D, [I|Acc]);  live_opt([if_end=I|Is], _, D, Acc) ->      Regs = 0,      live_opt(Is, Regs, D, [I|Acc]); @@ -802,8 +805,6 @@ live_opt([{deallocate,_}=I|Is], Regs, D, Acc) ->      live_opt(Is, Regs, D, [I|Acc]);  live_opt([{kill,_}=I|Is], Regs, D, Acc) ->      live_opt(Is, Regs, D, [I|Acc]); -live_opt([{try_case_end,_}=I|Is], Regs, D, Acc) -> -    live_opt(Is, Regs, D, [I|Acc]);  live_opt([{try_end,_}=I|Is], Regs, D, Acc) ->      live_opt(Is, Regs, D, [I|Acc]);  live_opt([{loop_rec_end,_}=I|Is], Regs, D, Acc) -> diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index a52e7bb761..9f0bca9dd5 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -783,15 +783,27 @@ valfun_4({bs_utf16_size,{f,Fail},A,Dst}, Vst) ->  valfun_4({bs_bits_to_bytes,{f,Fail},Src,Dst}, Vst) ->      assert_term(Src, Vst),      set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst)); -valfun_4({bs_init2,{f,Fail},_,Heap,Live,_,Dst}, Vst0) -> +valfun_4({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) ->      verify_live(Live, Vst0), +    if +	is_integer(Sz) -> +	    ok; +	true -> +	    assert_term(Sz, Vst0) +    end,      Vst1 = heap_alloc(Heap, Vst0),      Vst2 = branch_state(Fail, Vst1),      Vst3 = prune_x_regs(Live, Vst2),      Vst = bs_zero_bits(Vst3),      set_type_reg(binary, Dst, Vst); -valfun_4({bs_init_bits,{f,Fail},_,Heap,Live,_,Dst}, Vst0) -> +valfun_4({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) ->      verify_live(Live, Vst0), +    if +	is_integer(Sz) -> +	    ok; +	true -> +	    assert_term(Sz, Vst0) +    end,      Vst1 = heap_alloc(Heap, Vst0),      Vst2 = branch_state(Fail, Vst1),      Vst3 = prune_x_regs(Live, Vst2), diff --git a/lib/compiler/test/guard_SUITE_data/guard_SUITE_tuple_size.S b/lib/compiler/test/guard_SUITE_data/guard_SUITE_tuple_size.S index c0bf04ed8f..cffb792920 100644 --- a/lib/compiler/test/guard_SUITE_data/guard_SUITE_tuple_size.S +++ b/lib/compiler/test/guard_SUITE_data/guard_SUITE_tuple_size.S @@ -19,10 +19,10 @@      {get_tuple_element,{x,0},1,{x,2}}.      {get_tuple_element,{x,0},2,{x,3}}.      {get_tuple_element,{x,0},3,{x,4}}. -    {gc_bif,'+',{f,0},5,[{x,1},{x,2}],{x,0}}. -    {gc_bif,'+',{f,0},5,[{x,0},{x,3}],{x,0}}. -    {gc_bif,'+',{f,0},5,[{x,0},{x,4}],{x,0}}. -    {gc_bif,'+',{f,0},5,[{x,0},{x,5}],{x,0}}. +    {gc_bif,'+',{f,0},6,[{x,1},{x,2}],{x,0}}. +    {gc_bif,'+',{f,0},6,[{x,0},{x,3}],{x,0}}. +    {gc_bif,'+',{f,0},6,[{x,0},{x,4}],{x,0}}. +    {gc_bif,'+',{f,0},6,[{x,0},{x,5}],{x,0}}.      return.    {label,3}.      {badmatch,{x,0}}. diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl index 5e13a93c52..b53d0dba1d 100644 --- a/lib/compiler/test/misc_SUITE.erl +++ b/lib/compiler/test/misc_SUITE.erl @@ -190,6 +190,15 @@ silly_coverage(Config) when is_list(Config) ->  		     {label,2}|non_proper_list]}],99},      ?line expect_error(fun() -> beam_block:module(BlockInput, []) end), +    %% beam_type +    TypeInput = {?MODULE,[{foo,0}],[], +		   [{function,foo,0,2, +		     [{label,1}, +		      {line,loc}, +		      {func_info,{atom,?MODULE},{atom,foo},0}, +		      {label,2}|non_proper_list]}],99}, +    expect_error(fun() -> beam_type:module(TypeInput, []) end), +      %% beam_except      ExceptInput = {?MODULE,[{foo,0}],[],  		   [{function,foo,0,2, diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index abab81d31f..648ff349a4 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -248,6 +248,8 @@ format_error({illegal_guard_local_call, {F,A}}) ->      io_lib:format("call to local/imported function ~w/~w is illegal in guard",  		  [F,A]);  format_error(illegal_guard_expr) -> "illegal guard expression"; +format_error(deprecated_tuple_fun) -> +    "tuple funs are deprecated and will be removed in R16";  %% --- exports ---  format_error({explicit_export,F,A}) ->      io_lib:format("in this release, the call to ~w/~w must be written " @@ -1914,7 +1916,8 @@ gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Vt, St0) ->          true -> {Asvt,St1};          false -> {Asvt,add_error(Line, illegal_guard_expr, St1)}      end; -gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, Vt, St) -> +gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, Vt, St0) -> +    St = add_warning(L, deprecated_tuple_fun, St0),      gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, Vt, St);  gexpr({op,Line,Op,A}, Vt, St0) ->      {Avt,St1} = gexpr(A, Vt, St0), diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index dcd622b984..9f9d97b619 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -1331,17 +1331,20 @@ guard(Config) when is_list(Config) ->                     foo.              ">>,              [warn_unused_vars, nowarn_obsolete_guard], -            {errors,[{2,erl_lint,illegal_guard_expr}, -                     {4,erl_lint,illegal_guard_expr}, -                     {6,erl_lint,illegal_guard_expr}, -                     {8,erl_lint,illegal_guard_expr}, -		     {10,erl_lint,illegal_guard_expr}, -		     {12,erl_lint,illegal_guard_expr}, -		     {14,erl_lint,illegal_guard_expr}, -		     {16,erl_lint,illegal_guard_expr}, -		     {18,erl_lint,illegal_guard_expr}, -		     {20,erl_lint,illegal_guard_expr}], -             []}}, +            {error,[{2,erl_lint,illegal_guard_expr}, +		    {4,erl_lint,illegal_guard_expr}, +		    {6,erl_lint,illegal_guard_expr}, +		    {8,erl_lint,illegal_guard_expr}, +		    {10,erl_lint,illegal_guard_expr}, +		    {12,erl_lint,illegal_guard_expr}, +		    {14,erl_lint,illegal_guard_expr}, +		    {16,erl_lint,illegal_guard_expr}, +		    {18,erl_lint,illegal_guard_expr}, +		    {20,erl_lint,illegal_guard_expr}], +	     [{8,erl_lint,deprecated_tuple_fun}, +	      {14,erl_lint,deprecated_tuple_fun}, +	      {20,erl_lint,deprecated_tuple_fun}, +	      {28,erl_lint,deprecated_tuple_fun}]}},             {guard6,              <<"-record(apa,{a=a,b=foo:bar()}).                apa() -> diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl index 1e74ad7727..192268f90e 100644 --- a/lib/stdlib/test/qlc_SUITE.erl +++ b/lib/stdlib/test/qlc_SUITE.erl @@ -2969,12 +2969,14 @@ lookup1(Config) when is_list(Config) ->                  [3] = lookup_keys(Q)          end, [{1,a},{3,3}])">>, +      {cres,         <<"A = 3,            etsc(fun(E) ->                  Q = qlc:q([X || X <- ets:table(E), A =:= {erlang,element}(1, X)]),                  [{3,3}] = qlc:e(Q),                  [3] = lookup_keys(Q)          end, [{1,a},{3,3}])">>, +       {warnings,[{3,erl_lint,deprecated_tuple_fun}]}},         <<"etsc(fun(E) ->                  A = 3, @@ -3439,12 +3441,14 @@ lookup2(Config) when is_list(Config) ->                   [r] = qlc:e(Q),                   [r] = lookup_keys(Q)           end, [{keypos,1}], [#r{}])">>, +       {cres,         <<"etsc(fun(E) ->                  Q = qlc:q([element(1, X) || X <- ets:table(E),                                               {erlang,is_record}(X, r, 2)]),                   [r] = qlc:e(Q),                   [r] = lookup_keys(Q)           end, [{keypos,1}], [#r{}])">>, +        {warnings,[{4,erl_lint,deprecated_tuple_fun}]}},         {cres,          <<"etsc(fun(E) ->                  Q = qlc:q([element(1, X) || X <- ets:table(E),  @@ -3465,12 +3469,14 @@ lookup2(Config) when is_list(Config) ->                   [r] = qlc:e(Q),                   [r] = lookup_keys(Q)           end, [{keypos,1}], [#r{}])">>, +       {cres,         <<"etsc(fun(E) ->                  Q = qlc:q([element(1, X) || X <- ets:table(E),                                               {erlang,is_record}(X, r)]),                   [r] = qlc:e(Q),                   [r] = lookup_keys(Q) -         end, [{keypos,1}], [#r{}])">> +         end, [{keypos,1}], [#r{}])">>, +        {warnings,[{4,erl_lint,deprecated_tuple_fun}]}}         ],      ?line run(Config, <<"-record(r, {a}).\n">>, TsR),  | 
