File 0427-stdlib-Fix-guard-check-for-is_record-2.patch of Package erlang
From cbacd22b394a7b8ad9ce4e1f4d9659f9fca92896 Mon Sep 17 00:00:00 2001
From: Isabell Huang <isabell@erlang.org>
Date: Mon, 7 Jul 2025 11:44:35 +0200
Subject: [PATCH] stdlib: Fix guard check for is_record/2
Fix https://github.com/erlang/otp/issues/10020
---
lib/compiler/test/lc_SUITE.erl | 12 ++++++++++--
lib/stdlib/src/erl_lint.erl | 16 ++++++++++++----
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/lib/compiler/test/lc_SUITE.erl b/lib/compiler/test/lc_SUITE.erl
index 155e749277..ad80d358a9 100644
--- a/lib/compiler/test/lc_SUITE.erl
+++ b/lib/compiler/test/lc_SUITE.erl
@@ -26,7 +26,7 @@
init_per_testcase/2,end_per_testcase/2,
basic/1,deeply_nested/1,no_generator/1,
empty_generator/1,no_export/1,shadow/1,
- effect/1]).
+ effect/1,gh10020/1]).
-include_lib("common_test/include/ct.hrl").
@@ -45,7 +45,8 @@ groups() ->
empty_generator,
no_export,
shadow,
- effect
+ effect,
+ gh10020
]}].
init_per_suite(Config) ->
@@ -286,6 +287,13 @@ do_effect(Lc, L) ->
ok = Lc(F, L),
lists:reverse(erase(?MODULE)).
+gh10020(Config) when is_list(Config) ->
+ L = lists:seq(1, 10),
+ do_gh10020(L).
+
+do_gh10020(L) ->
+ [] = [Rec || {_, Rec} <- L, is_record(L, L)].
+
id(I) -> I.
-file("bad_lc.erl", 1).
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 314ac7d1a2..091faea654 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2582,13 +2582,21 @@ is_guard_test(Expression, Forms, IsOverridden) ->
%% is_guard_test2(Expression, RecordDefs :: dict:dict()) -> boolean().
is_guard_test2({call,Anno,{atom,Ar,record},[E,A]}, Info) ->
is_gexpr({call,Anno,{atom,Ar,is_record},[E,A]}, Info);
+is_guard_test2({call,Anno,{remote,_Ar,{atom,_Am,erlang},
+ {atom,Af,is_record}},[E,A]}, Info) ->
+ is_guard_test2({call,Anno,{atom,Af,is_record},[E,A]}, Info);
is_guard_test2({call,_Anno,{atom,_Aa,Test},As}=Call, {_,IsOverridden}=Info) ->
A = length(As),
not IsOverridden({Test,A}) andalso
- case erl_internal:type_test(Test, A) of
- true -> is_gexpr_list(As, Info);
- false -> is_gexpr(Call, Info)
- end;
+ case erl_internal:type_test(Test, A) of
+ true when Test =:= is_record, A =:= 2 ->
+ case As of
+ [_,{atom,_,_}] -> is_gexpr_list(As, Info);
+ _ -> false
+ end;
+ true -> is_gexpr_list(As, Info);
+ false -> is_gexpr(Call, Info)
+ end;
is_guard_test2(G, Info) ->
%%Everything else is a guard expression.
is_gexpr(G, Info).
--
2.43.0