2
0
Эх сурвалжийг харах

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

Sven/Sarah Barth 2 жил өмнө
parent
commit
5d7e3ca240

+ 9 - 1
compiler/pdecsub.pas

@@ -1130,7 +1130,15 @@ implementation
         pd.procsym:=aprocsym;
         pd.procsym:=aprocsym;
         pd.proctypeoption:=potype;
         pd.proctypeoption:=potype;
         if ppf_anonymous in flags then
         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
         if assigned(genericparams) then
           begin
           begin

+ 2 - 0
compiler/procdefutil.pas

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

+ 52 - 0
tests/webtbs/tw40060.pp

@@ -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.
+