diff options
| author | Björn Gustavsson <[email protected]> | 2016-06-02 06:40:09 +0200 | 
|---|---|---|
| committer | Björn Gustavsson <[email protected]> | 2016-06-02 15:49:56 +0200 | 
| commit | a04289a5f30f39b62c7d245f272f486cfd70e6a8 (patch) | |
| tree | f3792edb6a5acf8afd0914df8f4135d250765117 /lib/compiler | |
| parent | 5facb518a9ee2d756564eccd92a2c11f334d6282 (diff) | |
| download | otp-a04289a5f30f39b62c7d245f272f486cfd70e6a8.tar.gz otp-a04289a5f30f39b62c7d245f272f486cfd70e6a8.tar.bz2 otp-a04289a5f30f39b62c7d245f272f486cfd70e6a8.zip | |
Avoid the dreaded "no_file" in warnings
Add more filename/line number annotations while translating to
Core Erlang in v3_core, and ensure that sys_core_fold retains
existing annotations. The goal is to avoid that sys_core_fold
generate warnings with "no_file" instead of a filename.
Diffstat (limited to 'lib/compiler')
| -rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 14 | ||||
| -rw-r--r-- | lib/compiler/src/v3_core.erl | 11 | ||||
| -rw-r--r-- | lib/compiler/test/core_fold_SUITE.erl | 49 | 
3 files changed, 61 insertions, 13 deletions
| diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index dbc27db377..e0de50f3ae 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -786,7 +786,7 @@ fold_lit_args(Call, Module, Name, Args0) ->  	Val ->  	    case cerl:is_literal_term(Val) of  		true -> -		    cerl:abstract(Val); +		    cerl:ann_abstract(cerl:get_ann(Call), Val);  		false ->  		    %% Successful evaluation, but it was not possible  		    %% to express the computed value as a literal. @@ -2176,24 +2176,22 @@ opt_not_in_let_1(V, Call, Body) ->  	#c_call{module=#c_literal{val=erlang},  		name=#c_literal{val='not'},  		args=[#c_var{name=V}]} -> -	    opt_not_in_let_2(Body); +	    opt_not_in_let_2(Body, Call);  	_ ->  	    no      end. -opt_not_in_let_2(#c_case{clauses=Cs0}=Case) -> +opt_not_in_let_2(#c_case{clauses=Cs0}=Case, NotCall) ->      Vars = make_vars([], 1), -    Body = #c_call{module=#c_literal{val=erlang}, -		   name=#c_literal{val='not'}, -		   args=Vars}, +    Body = NotCall#c_call{args=Vars},      Cs = [begin  	      Let = #c_let{vars=Vars,arg=B,body=Body},  	      C#c_clause{body=opt_not_in_let(Let)}  	  end || #c_clause{body=B}=C <- Cs0],      {yes,Case#c_case{clauses=Cs}}; -opt_not_in_let_2(#c_call{}=Call0) -> +opt_not_in_let_2(#c_call{}=Call0, _NotCall) ->      invert_call(Call0); -opt_not_in_let_2(_) -> no. +opt_not_in_let_2(_, _) -> no.  invert_call(#c_call{module=#c_literal{val=erlang},  		    name=#c_literal{val=Name0}, diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index a3b0236134..d71411de80 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -868,12 +868,16 @@ try_exception(Ecs0, St0) ->      {Evs,St1} = new_vars(3, St0), % Tag, Value, Info      {Ecs1,Ceps,St2} = clauses(Ecs0, St1),      [_,Value,Info] = Evs, -    Ec = #iclause{anno=#a{anno=[compiler_generated]}, +    LA = case Ecs1 of +	     [] -> []; +	     [C|_] -> get_lineno_anno(C) +	 end, +    Ec = #iclause{anno=#a{anno=[compiler_generated|LA]},  		  pats=[c_tuple(Evs)],guard=[#c_literal{val=true}],  		  body=[#iprimop{anno=#a{},       %Must have an #a{}  				 name=#c_literal{val=raise},  				 args=[Info,Value]}]}, -    Hs = [#icase{anno=#a{},args=[c_tuple(Evs)],clauses=Ecs1,fc=Ec}], +    Hs = [#icase{anno=#a{anno=LA},args=[c_tuple(Evs)],clauses=Ecs1,fc=Ec}],      {Evs,Ceps++Hs,St2}.  try_after(As, St0) -> @@ -2098,7 +2102,8 @@ upattern(#c_var{name=V}=Var, Ks, St0) ->  	true ->  	    {N,St1} = new_var_name(St0),  	    New = #c_var{name=N}, -	    Test = #icall{anno=#a{us=add_element(N, [V])}, +	    LA = get_lineno_anno(Var), +	    Test = #icall{anno=#a{anno=LA,us=add_element(N, [V])},  			  module=#c_literal{val=erlang},  			  name=#c_literal{val='=:='},  			  args=[New,Var]}, diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl index 442b2d424c..376d2c8e9a 100644 --- a/lib/compiler/test/core_fold_SUITE.erl +++ b/lib/compiler/test/core_fold_SUITE.erl @@ -25,7 +25,8 @@  	 eq/1,nested_call_in_case/1,guard_try_catch/1,coverage/1,  	 unused_multiple_values_error/1,unused_multiple_values/1,  	 multiple_aliases/1,redundant_boolean_clauses/1, -	 mixed_matching_clauses/1,unnecessary_building/1]). +	 mixed_matching_clauses/1,unnecessary_building/1, +	 no_no_file/1]).  -export([foo/0,foo/1,foo/2,foo/3]). @@ -43,7 +44,8 @@ groups() ->         eq,nested_call_in_case,guard_try_catch,coverage,         unused_multiple_values_error,unused_multiple_values,         multiple_aliases,redundant_boolean_clauses, -       mixed_matching_clauses,unnecessary_building]}]. +       mixed_matching_clauses,unnecessary_building, +       no_no_file]}].  init_per_suite(Config) -> @@ -454,4 +456,47 @@ do_unnecessary_building_2({a,_,_}=T) ->       [_,_] = [T,none],       x}. +%% This test tests that v3_core has provided annotations and that +%% sys_core_fold retains them, so that warnings produced by +%% sys_core_fold will have proper filenames and line numbers. Thus, no +%% "no_file" warnings. +no_no_file(_Config) -> +    {'EXIT',{{case_clause,0},_}} = (catch source(true, any)), +    surgery = (tim(#{reduction => any}))(), + +    false = soul(#{[] => true}), +    {'EXIT',{{case_clause,true},_}} = (catch soul(#{[] => false})), + +    ok = experiment(), +    ok. + +source(true, Activities) -> +    case 0 of +	Activities when [] -> +	    Activities +    end. + +tim(#{reduction := Emergency}) -> +    try +	fun() -> surgery end +    catch +	_ when [] -> +	    planet +    end. + +soul(#{[] := Properly}) -> +    not case true of +	    Properly -> true; +	    Properly -> 0 +	end. + +experiment() -> +    case kingdom of +	_ -> +	    +case "map" of +		 _ -> 0.0 +	     end +    end, +    ok. +  id(I) -> I. | 
