* fix #40060: ensure that Self is not added for anonymous functions that are part of a static class method

+ added test
This commit is contained in:
Sven/Sarah Barth 2022-12-30 15:26:33 +01:00
parent 4c6338207f
commit 5d7e3ca240
3 changed files with 63 additions and 1 deletions

View File

@ -1130,7 +1130,15 @@ implementation
pd.procsym:=aprocsym;
pd.proctypeoption:=potype;
if ppf_anonymous in flags then
include(pd.procoptions,po_anonymous);
begin
include(pd.procoptions,po_anonymous);
{ inherit the "static" and "class" flag from the method the anonymous function
is contained in }
if (st.symtabletype=localsymtable) and
(st.defowner.typ=procdef) and
([po_staticmethod,po_classmethod]*tprocdef(st.defowner).procoptions<>[]) then
pd.procoptions:=pd.procoptions+([po_staticmethod,po_classmethod]*tprocdef(st.defowner).procoptions);
end;
if assigned(genericparams) then
begin

View File

@ -1196,6 +1196,8 @@ implementation
pd.struct:=capturedef;
exclude(pd.procoptions,po_anonymous);
exclude(pd.procoptions,po_delphi_nested_cc);
exclude(pd.procoptions,po_staticmethod);
exclude(pd.procoptions,po_classmethod);
pd.was_anonymous:=true;
pd.procsym.ChangeOwnerAndName(capturedef.symtable,upcase(invokename));
pd.procsym.realname:=invokename;

52
tests/webtbs/tw40060.pp Normal file
View File

@ -0,0 +1,52 @@
{ %NORUN }
program tw40060;
{$mode objfpc}{$H+}
{$modeswitch AnonymousFunctions}
{$modeswitch AdvancedRecords}
uses
sysutils;
type
TSomeRec = record
a: integer;
procedure print;
function text: string;
class procedure main; static;
end;
function some_fun_0: TSomeRec;
begin
result.a := 4;
end;
procedure TSomeRec.print;
begin
writeln('a = ', a);
end;
function TSomeRec.text: string;
begin
result := format('a = %d', [a]);
end;
procedure main;
begin
some_fun_0().print;
(function: TSomeRec begin result.a := 5 end()).print;
writeln((function: TSomeRec begin result.a := 10 end()).text);
end;
class procedure TSomeRec.main; static;
begin
some_fun_0().print;
(function: TSomeRec begin result.a := 5 end()).print;
writeln((function: TSomeRec begin result.a := 10 end()).text);
end;
begin
main;
TSomeRec.main;
end.