LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File 0128-Point-out-the-correct-line-in-an-exception-for-a-bad.patch of Package erlang (Project home:Ledest:erlang:20)

From eb5892eec6480a89e574e0d7bdd9126844f32108 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 14 Mar 2018 12:47:46 +0100
Subject: [PATCH] Point out the correct line in an exception for a bad
 generator

When a generator in a list comprehension was given some
other term than a list, the wrong line could be pointed
out in the exception. Here is an example:

    bad_generator() ->
        [I ||               %%This line would be pointed out.
            I <- not_a_list].

https://bugs.erlang.org/browse/ERL-572
---
 lib/compiler/src/v3_core.erl   | 10 +++++-----
 lib/compiler/test/lc_SUITE.erl | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 6029b91cdc..8cf8c69fef 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1152,7 +1152,7 @@ fun_tq(Cs0, L, St0, NameInfo) ->
 %% lc_tq(Line, Exp, [Qualifier], Mc, State) -> {LetRec,[PreExp],State}.
 %%  This TQ from Simon PJ pp 127-138.  
 
-lc_tq(Line, E, [#igen{anno=GAnno,ceps=Ceps,
+lc_tq(Line, E, [#igen{anno=#a{anno=GA}=GAnno,ceps=Ceps,
 		      acc_pat=AccPat,acc_guard=AccGuard,
                       skip_pat=SkipPat,tail=Tail,tail_pat=TailPat,
                       arg={Pre,Arg}}|Qs], Mc, St0) ->
@@ -1162,7 +1162,7 @@ lc_tq(Line, E, [#igen{anno=GAnno,ceps=Ceps,
     F = #c_var{anno=LA,name={Name,1}},
     Nc = #iapply{anno=GAnno,op=F,args=[Tail]},
     {Var,St2} = new_var(St1),
-    Fc = function_clause([Var], LA, {Name,1}),
+    Fc = function_clause([Var], GA, {Name,1}),
     TailClause = #iclause{anno=LAnno,pats=[TailPat],guard=[],body=[Mc]},
     Cs0 = case {AccPat,AccGuard} of
               {SkipPat,[]} ->
@@ -1185,9 +1185,9 @@ lc_tq(Line, E, [#igen{anno=GAnno,ceps=Ceps,
                                   body=Lps ++ [Lc]}|Cs0],
                         St3}
                end,
-    Fun = #ifun{anno=LAnno,id=[],vars=[Var],clauses=Cs,fc=Fc},
-    {#iletrec{anno=LAnno#a{anno=[list_comprehension|LA]},defs=[{{Name,1},Fun}],
-              body=Pre ++ [#iapply{anno=LAnno,op=F,args=[Arg]}]},
+    Fun = #ifun{anno=GAnno,id=[],vars=[Var],clauses=Cs,fc=Fc},
+    {#iletrec{anno=GAnno#a{anno=[list_comprehension|GA]},defs=[{{Name,1},Fun}],
+              body=Pre ++ [#iapply{anno=GAnno,op=F,args=[Arg]}]},
      Ceps,St4};
 lc_tq(Line, E, [#ifilter{}=Filter|Qs], Mc, St) ->
     filter_tq(Line, E, Filter, Mc, St, Qs, fun lc_tq/5);
diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl
index 9ad417b09b..699081470d 100644
--- a/lib/compiler/test/lc_SUITE.erl
+++ b/lib/compiler/test/lc_SUITE.erl
@@ -107,6 +107,31 @@ basic(Config) when is_list(Config) ->
     [] = [X || X <- L1, X+1 < 2],
     {'EXIT',_} = (catch [X || X <- L1, odd(X)]),
     fc([x], catch [E || E <- id(x)]),
+
+    %% Make sure that line numbers point out the generator.
+    case ?MODULE of
+        lc_inline_SUITE ->
+            ok;
+        _ ->
+            {'EXIT',{function_clause,
+                     [{?MODULE,_,_,
+                       [{file,"bad_lc.erl"},{line,4}]}|_]}} =
+                (catch bad_generator(a)),
+            {'EXIT',{function_clause,
+                     [{?MODULE,_,_,
+                       [{file,"bad_lc.erl"},{line,4}]}|_]}} =
+                (catch bad_generator([a|b])),
+            {'EXIT',{badarg,
+                     [{erlang,length,_,_},
+                      {?MODULE,bad_generator_bc,1,
+                       [{file,"bad_lc.erl"},{line,7}]}|_]}} =
+                (catch bad_generator_bc(a)),
+            {'EXIT',{badarg,
+                     [{erlang,length,_,_},
+                      {?MODULE,bad_generator_bc,1,
+                       [{file,"bad_lc.erl"},{line,7}]}|_]}} =
+                (catch bad_generator_bc([a|b]))
+    end,
     ok.
 
 tuple_list() ->
@@ -249,3 +274,11 @@ fc(Args, {'EXIT',{function_clause,[{?MODULE,_,Arity,_}|_]}})
 fc(Args, {'EXIT',{{case_clause,ActualArgs},_}})
   when ?MODULE =:= lc_inline_SUITE ->
     Args = tuple_to_list(ActualArgs).
+
+-file("bad_lc.erl", 1).
+bad_generator(List) ->                          %Line 2
+    [I ||                                       %Line 3
+        I <- List].                             %Line 4
+bad_generator_bc(List) ->                       %Line 5
+    << <<I:4>> ||                               %Line 6
+        I <- List>>.                            %Line 7
-- 
2.16.3