LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File 1031-Fix-number-of-values-for-after-infinity-clause.patch of Package erlang (Project home:Ledest:erlang:20)

From ec1ef628c6582bd2666031105c11ecdbd0b67211 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sat, 2 Dec 2017 07:33:18 +0100
Subject: [PATCH 1/5] Fix number of values for 'after infinity' clause

We used to not care about the number of values returned from the
'after infinity' clause in a receive (because it could never be
executed). It is time to start caring because this will cause problem
when we will soon start to do some more aggressive optimizizations.
---
 lib/compiler/src/core_lint.erl      |  6 ------
 lib/compiler/src/sys_core_fold.erl  | 10 +++++++---
 lib/compiler/src/v3_core.erl        |  4 +++-
 lib/compiler/test/receive_SUITE.erl |  8 ++++++++
 4 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl
index 7d3513c0ba..6e2114be56 100644
--- a/lib/compiler/src/core_lint.erl
+++ b/lib/compiler/src/core_lint.erl
@@ -353,12 +353,6 @@ expr(#c_case{arg=Arg,clauses=Cs}, Def, Rt, St0) ->
     Pc = case_patcount(Cs),
     St1 = body(Arg, Def, Pc, St0),
     clauses(Cs, Def, Pc, Rt, St1);
-expr(#c_receive{clauses=Cs,timeout=#c_literal{val=infinity},
-		action=#c_literal{}},
-     Def, Rt, St) ->
-    %% If the timeout is 'infinity', the after code can never
-    %% be reached. We don't care if the return count is wrong.
-    clauses(Cs, Def, 1, Rt, St);
 expr(#c_receive{clauses=Cs,timeout=T,action=A}, Def, Rt, St0) ->
     St1 = expr(T, Def, 1, St0),
     St2 = body(A, Def, Rt, St1),
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index df880ff784..15ced196a7 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -2622,9 +2622,13 @@ delay_build_expr_1(#c_receive{clauses=Cs0,
 			      timeout=Timeout,
 			      action=A0}=Rec, TypeSig) ->
     Cs = delay_build_cs(Cs0, TypeSig),
-    A = case Timeout of
-	    #c_literal{val=infinity} -> A0;
-	    _ -> delay_build_expr(A0, TypeSig)
+    A = case {Timeout,A0} of
+	    {#c_literal{val=infinity},#c_literal{}} ->
+                {_Type,Arity} = TypeSig,
+                Es = lists:duplicate(Arity, A0),
+                core_lib:make_values(Es);
+	    _ ->
+                delay_build_expr(A0, TypeSig)
 	end,
     Rec#c_receive{clauses=Cs,action=A};
 delay_build_expr_1(#c_seq{body=B0}=Seq, TypeSig) ->
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 20cb3343fb..66ddf6fcb9 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -2462,9 +2462,11 @@ cexpr(#icase{anno=A,args=Largs,clauses=Lcs,fc=Lfc}, As, St0) ->
 cexpr(#ireceive1{anno=A,clauses=Lcs}, As, St0) ->
     Exp = intersection(A#a.ns, As),		%Exports
     {Ccs,St1} = cclauses(Lcs, Exp, St0),
+    True = #c_literal{val=true},
+    Action = core_lib:make_values(lists:duplicate(1+length(Exp), True)),
     {#c_receive{anno=A#a.anno,
 		clauses=Ccs,
-		timeout=#c_literal{val=infinity},action=#c_literal{val=true}},
+		timeout=#c_literal{val=infinity},action=Action},
      Exp,A#a.us,St1};
 cexpr(#ireceive2{anno=A,clauses=Lcs,timeout=Lto,action=Les}, As, St0) ->
     Exp = intersection(A#a.ns, As),		%Exports
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 8304672558..3001bb421b 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -265,6 +265,10 @@ export(Config) when is_list(Config) ->
     self() ! {result,Ref,42},
     42 = export_1(Ref),
     {error,timeout} = export_1(Ref),
+
+    self() ! {result,Ref},
+    {ok,Ref} = export_2(),
+
     ok.
 
 export_1(Reference) ->
@@ -281,6 +285,10 @@ export_1(Reference) ->
     id({build,self()}),
     Result.
 
+export_2() ->
+    receive {result,Result} -> ok end,
+    {ok,Result}.
+
 wait(Config) when is_list(Config) ->
     self() ! <<42>>,
     <<42>> = wait_1(r, 1, 2),
-- 
2.15.1