File 1011-Correct-erlang-is_builtin-3-for-apply-2-and-yield-0.patch of Package erlang

From 696f47b64c8ad5da71cbffd8fecf0f3bae1e7466 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 26 Oct 2017 12:57:24 +0200
Subject: [PATCH] Correct erlang:is_builtin/3 for apply/2 and yield/0

erlang:is_builtin(erlang, M, F) returns false for apply/2 and
yield/0. The documentation for erlang:is_builtin/3 says that it
returns true for BIFs that are implemented in C. apply/2 and
yield/0 are implemented in C (as BEAM instructions), and
therefore the correct return value is true.

Also see a similar argument that was made for apply/3 in the past:

    http://erlang.org/pipermail/erlang-bugs/2015-October/005101.html

https://bugs.erlang.org/browse/ERL-500
---
 erts/emulator/beam/beam_emu.c    | 17 ++++++++++-------
 erts/emulator/test/bif_SUITE.erl | 18 ++++++++++++------
 lib/tools/test/xref_SUITE.erl    | 22 +++++++++++-----------
 3 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index aa94fbf536..60d0008d8f 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3199,13 +3199,16 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity)
     Export e;
     Export* ep;
 
-    if (Mod == am_erlang && Name == am_apply && arity == 3) {
-	/*
-	 * Special case. apply/3 is built-in (implemented in C),
-	 * but implemented in a different way than all other
-	 * BIFs.
-	 */
-	return 1;
+    if (Mod == am_erlang) {
+        /*
+         * Special case for built-in functions that are implemented
+         * as instructions as opposed to SNIFs.
+         */
+        if (Name == am_apply && (arity == 2 || arity == 3)) {
+            return 1;
+        } else if (Name == am_yield && arity == 0) {
+            return 1;
+        }
     }
 
     e.info.mfa.module = Mod;
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index 146c37b118..e1b42e5d85 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -781,14 +781,20 @@ is_builtin(_Config) ->
 		       {F,A} <- M:module_info(exports)],
     Exp = ordsets:from_list(Exp0),
 
-    %% erlang:apply/3 is considered to be built-in, but is not
-    %% implemented as other BIFs.
+    %% Built-ins implemented as special instructions.
+    Instructions = [{erlang,apply,2},{erlang,apply,3},{erlang,yield,0}],
 
-    Builtins0 = [{erlang,apply,3}|erlang:system_info(snifs)],
+    Builtins0 = Instructions ++ erlang:system_info(snifs),
     Builtins = ordsets:from_list(Builtins0),
-    NotBuiltin = ordsets:subtract(Exp, Builtins),
-    _ = [true = erlang:is_builtin(M, F, A) || {M,F,A} <- Builtins],
-    _ = [false = erlang:is_builtin(M, F, A) || {M,F,A} <- NotBuiltin],
+
+    Fakes = [{M,F,42} || {M,F,_} <- Instructions],
+    All = ordsets:from_list(Fakes ++ Exp),
+    NotBuiltin = ordsets:subtract(All, Builtins),
+
+    _ = [{true,_} = {erlang:is_builtin(M, F, A),MFA} ||
+            {M,F,A}=MFA <- Builtins],
+    _ = [{false,_} = {erlang:is_builtin(M, F, A),MFA} ||
+            {M,F,A}=MFA <- NotBuiltin],
 
     ok.
 
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index d651cbcfee..018f632948 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -1112,27 +1112,16 @@ read_expected(Version) ->
           {POS7+2,{FF,{erlang,spawn_opt,4}}},
           {POS8+1,{FF,{hej,san,1}}},
           {POS8+4,{FF,{a,b,1}}},
-          {POS8+4,{FF,{erlang,apply,2}}},
-          {POS8+5,{FF,{erlang,apply,2}}},
           {POS8+6,{FF,{m,f,1}}},
           {POS9+1,{FF,{read,bi,0}}},
           {POS9+2,{FF,{a,b,1}}},
-          {POS9+2,{FF,{erlang,apply,2}}},
-          {POS9+3,{FF,{erlang,apply,2}}},
-          {POS9+4,{FF,{erlang,apply,2}}},
           {POS9+4,{FF,{erlang,not_a_function,1}}},
           {POS9+5,{FF,{mod,func,2}}},
           {POS9+6,{FF,{erlang,apply,1}}},
-          {POS9+7,{FF,{erlang,apply,2}}},
           {POS9+7,{FF,{math,add3,1}}},
           {POS9+8,{FF,{q,f,1}}},
-          {POS10+4,{FF,{erlang,apply,2}}},
           {POS10+5,{FF,{mod1,fun1,1}}},
-          {POS11+6,{FF,{erlang,apply,2}}},
-          {POS12+1,{FF,{erlang,apply,2}}},
-          {POS12+4,{FF,{erlang,apply,2}}},
           {POS12+5,{FF,{m3,f3,2}}},
-          {POS12+7,{FF,{erlang,apply,2}}},
           {POS13+1,{FF,{dm,df,1}}},
           {POS13+6,{{read,bi,0},{foo,module_info,0}}},
           {POS13+7,{{read,bi,0},{read,module_info,0}}},
@@ -1162,15 +1151,26 @@ read_expected(Version) ->
             {POS3+3,  {FF,{erlang,spawn_link,3}}},
             {POS3+4, {FF,{erlang,spawn_link,3}}},
             {POS6+4, {FF,{erlang,spawn,3}}},
+            {POS8+4,{FF,{erlang,apply,2}}},
+            {POS8+5,{FF,{erlang,apply,2}}},
             {POS8+6,{FF,{erlang,apply,3}}},
             {POS8+7,{FF,{erlang,apply,3}}},
             {POS9+1,{FF,{erlang,apply,3}}},
+            {POS9+2,{FF,{erlang,apply,2}}},
+            {POS9+3,{FF,{erlang,apply,2}}},
+            {POS9+4,{FF,{erlang,apply,2}}},
             {POS9+5,{FF,{erlang,apply,3}}},
+            {POS9+7,{FF,{erlang,apply,2}}},
+            {POS10+4,{FF,{erlang,apply,2}}},
             {POS11+1,{FF,{erlang,apply,3}}},
             {POS11+2,{FF,{erlang,apply,3}}},
             {POS11+3,{FF,{erlang,apply,3}}},
             {POS11+4,{FF,{erlang,apply,3}}},
+            {POS11+6,{FF,{erlang,apply,2}}},
+            {POS12+1,{FF,{erlang,apply,2}}},
+            {POS12+4,{FF,{erlang,apply,2}}},
             {POS12+5,{FF,{erlang,apply,3}}},
+            {POS12+7,{FF,{erlang,apply,2}}},
             {POS12+8,{FF,{erlang,apply,3}}},
             {POS13+5, {{read,bi,0},{erlang,length,1}}},
             {POS14+3, {{read,bi,0},{erlang,length,1}}}],
-- 
2.14.3