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