File 4221-Don-t-allow-local-calls-from-record-init-in-guards.patch of Package erlang

From 68ee2a3373c27b96d96a8f6a48573d86f83fb3fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 17 Nov 2022 06:23:43 +0100
Subject: [PATCH] Don't allow local calls from record init in guards

Calling functions in guards is forbidden, but the compiler would
fail to reject a function call from a default record initializer
used in a guard. For example:

    -record(test, {a = mk_a()}).
    mk_a() -> 1.

    test_rec(Rec) when Rec =:= #test{} ->
        true.

Before this commit, the compiler would fail to reject the illegal call
to `mk_a/0`, and crash in a later pass. The compiler will now give the
following error message:

    t.erl:7:36: call to local/imported function mk_a/0 is illegal in guard
    %    7|         test_rec(Rec) when Rec =:= #test{} ->
    %     |                                    ^

Closes #6465
Closes #6466
---
 lib/stdlib/src/erl_lint.erl        |  5 ++---
 lib/stdlib/test/erl_lint_SUITE.erl | 16 ++++++++++++++--
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 7c717e47d1..8329d3be0c 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2826,9 +2826,8 @@ ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) ->
     Defs = init_fields(Ifs, Line, Dfs),
     St2 = St1#lint{errors = []},
     {_,St3} = check_fields(Defs, Name, Dfs, Vt1, St2, fun gexpr/3),
-    #lint{usage = Usage, errors = Errors} = St3,
-    IllErrs = [E || {_File,{_Line,erl_lint,illegal_guard_expr}}=E <- Errors],
-    St4 = St1#lint{usage = Usage, errors = IllErrs ++ St1#lint.errors},
+    #lint{usage = Usage, errors = IllErrors} = St3,
+    St4 = St1#lint{usage = Usage, errors = IllErrors ++ St1#lint.errors},
     {Vt1,St4}.
 
 %% Default initializations to be carried out
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index aa941e61b6..bfc6935835 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1626,8 +1626,20 @@ guard(Config) when is_list(Config) ->
             [],
             {error,
 	     [{2,erl_lint,{obsolete_guard_overridden,port}}],
-	     [{2,erl_lint,{obsolete_guard,{port,1}}}]}}
-	  ],
+	     [{2,erl_lint,{obsolete_guard,{port,1}}}]}},
+           {guard11,
+            <<"-record(bar, {a = mk_a()}).
+               mk_a() -> 1.
+
+               test_rec(Rec) when Rec =:= #bar{} -> true.
+               map_pattern(#{#bar{} := _}) -> ok.
+              ">>,
+            [],
+            {errors,
+             [{4,erl_lint,{illegal_guard_local_call,{mk_a,0}}},
+              {5,erl_lint,{illegal_guard_local_call,{mk_a,0}}}],
+             []}}
+          ],
     [] = run(Config, Ts1),
     ok.
 
-- 
2.35.3

openSUSE Build Service is sponsored by