From bc4eb00a7a1d2c2050a8056d13abaf8656897bc0 Mon Sep 17 00:00:00 2001 From: Sven/Sarah Barth Date: Thu, 6 Jan 2022 21:59:11 +0100 Subject: [PATCH] * apply patch by Blaise.ru: proper code generation for assigning class non-static methods, accessed via a class reference type, to method pointers + added test --- compiler/pexpr.pas | 7 ++++++- tests/test/tprocvar16.pp | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/test/tprocvar16.pp diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index ae41777fd2..d44a27081d 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -1076,7 +1076,12 @@ implementation else begin typecheckpass(p1); - if (p1.resultdef.typ=objectdef) then + if (p1.resultdef.typ=classrefdef) and assigned(getprocvardef) then + begin + p1:=cloadvmtaddrnode.create(p1); + tloadnode(p2).set_mp(p1); + end + else if (p1.resultdef.typ=objectdef) then { so we can create the correct method pointer again in case this is a "objectprocvar:=@classname.method" expression } tloadnode(p2).symtable:=tobjectdef(p1.resultdef).symtable diff --git a/tests/test/tprocvar16.pp b/tests/test/tprocvar16.pp new file mode 100644 index 0000000000..a47d0dc315 --- /dev/null +++ b/tests/test/tprocvar16.pp @@ -0,0 +1,19 @@ +program tprocvar16; + +{$mode delphi} + +type C = class + class procedure Foo; +end; +class procedure C.Foo; begin end; + +type CC = class of C; + +var Z: procedure of object; +begin + Z := CC.Foo; + if TMethod(Z).Code <> @C.Foo then + Halt(1); + if TMethod(Z).Data <> Pointer(C) then + Halt(2); +end.