Explorar o código

* fix #39981: retrieve the symbol that returns the desired procdef/procvardef not maybe the Self or something else as we need that symbol to differentiate the procdefs
+ added test

Sven/Sarah Barth %!s(int64=2) %!d(string=hai) anos
pai
achega
a714e2ff35
Modificáronse 2 ficheiros con 54 adicións e 0 borrados
  1. 2 0
      compiler/procdefutil.pas
  2. 52 0
      tests/webtbs/tw39981.pp

+ 2 - 0
compiler/procdefutil.pas

@@ -755,6 +755,8 @@ implementation
       result:=fen_false;
       if n.nodetype<>loadn then
         exit;
+      if not (n.resultdef.typ in [procdef,procvardef]) then
+        exit;
       sym^:=tloadnode(n).symtableentry;
       result:=fen_norecurse_true;
     end;

+ 52 - 0
tests/webtbs/tw39981.pp

@@ -0,0 +1,52 @@
+program tw39981;
+
+{$mode objfpc}{$H+}
+{$ModeSwitch functionreferences}
+
+type
+  TNotifyProc = reference to procedure();
+
+  TMyClass = class
+  public
+    procedure One;
+    procedure Two;
+  end;
+
+{ TMyClass }
+
+var
+  OneCounter: Integer = 0;
+  TwoCounter: Integer = 0;
+
+procedure TMyClass.One;
+begin
+  Writeln('One');
+  Inc(OneCounter);
+end;
+
+procedure TMyClass.Two;
+begin
+  Writeln('Two');
+  Inc(TwoCounter);
+end;
+
+var
+  One, Two: TNotifyProc;
+  MyObject: TMyClass;
+  HasError: Boolean = False;
+begin
+  MyObject := TMyClass.Create;
+  One := @MyObject.One;
+  Two := @MyObject.Two;
+  One(); // writes out One - OK
+  Two(); // writes out One - Error
+
+  if One=Two then // yes, they are equal - Error
+    HasError := True;
+  if not ((OneCounter=1) and (TwoCounter=1)) then // Error: OneCounter=2, TwoCounter=0
+    HasError := True;
+
+  if HasError then
+    Halt(1);
+end.
+