aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-08-15 11:05:30 +0200
committerBjörn Gustavsson <[email protected]>2012-08-15 11:05:30 +0200
commitc5e5cf792d87e0d23f80ff572f499f0e3e044933 (patch)
tree585bc144e76486ed0959e4675015fbb760c6c33c
parent9492bf7abbf5e43a9bdada5b0ace0432ce1f4223 (diff)
parent6cdc6b667a8db2b63a4613c63dc4f75a34a5ea7f (diff)
downloadotp-c5e5cf792d87e0d23f80ff572f499f0e3e044933.tar.gz
otp-c5e5cf792d87e0d23f80ff572f499f0e3e044933.tar.bz2
otp-c5e5cf792d87e0d23f80ff572f499f0e3e044933.zip
Merge branch 'bjorn/compiler/minor-fixes/OTP-10185' into maint
* bjorn/compiler/minor-fixes/OTP-10185: erl_lint: Add a deprecated warning for literal tuple funs beam_utils:live_opt/1: Correct handling of try_case_end/1 Correct guard_SUITE_tuple_size.S beam_type: Print the offending function if this pass crashes beam_validator: Validate the size operand in bs_init_bits and bs_init2
-rw-r--r--lib/compiler/src/beam_type.erl15
-rw-r--r--lib/compiler/src/beam_utils.erl5
-rw-r--r--lib/compiler/src/beam_validator.erl16
-rw-r--r--lib/compiler/test/guard_SUITE_data/guard_SUITE_tuple_size.S8
-rw-r--r--lib/compiler/test/misc_SUITE.erl9
-rw-r--r--lib/stdlib/src/erl_lint.erl5
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl25
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl8
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),