[fpc-devel] Assigning class methods, accessed via a class reference type, to procvars
Blaise at blaise.ru
Blaise at blaise.ru
Wed Dec 22 19:16:05 CET 2021
1) The attached metaclass_meth_to_procvar-1.patch fixes the internal error reported for:
[ICE] Assigning class methods, accessed via a class reference type, to incompatible procvars
-------8<-------
type C = class
class procedure NonStatic;
class procedure Static; static;
end;
class procedure C.NonStatic; begin end;
class procedure C.Static; begin end;
type CC = class of C;
var IncompatWNonStatic: procedure;
var IncompatWStatic: procedure of object;
begin
IncompatWNonStatic := CC.NonStatic; // ICE 200301042
IncompatWStatic := CC.Static // ICE 200301042
end.
-------8<-------
2) The attached metaclass_meth_to_procvar-2.patch fixes the invalid codegen produced for:
[BadCG] Assigning class non-static methods, accessed via a class reference type, to method pointers
-------8<-------
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;
writeln( TMethod(Z).Code = @C.Foo ); // "FALSE"
writeln( TMethod(Z).Data = Pointer(C) ); // "FALSE"
end.
-------8<-------
--
βþ
-------------- next part --------------
# HG changeset patch
# User Blaise.ru
# Date 1640147566 -10800
# Wed Dec 22 07:32:46 2021 +0300
! avoid ICE when assigning class methods, accessed via a class reference type, to incompatible procvars
diff -r d880e6695537 -r 250d0d636843 ncnv.pas
--- a/ncnv.pas Mon Dec 20 20:55:22 2021 +0300
+++ b/ncnv.pas Wed Dec 22 07:32:46 2021 +0300
@@ -2494,6 +2494,7 @@
aprocdef : tprocdef;
eq : tequaltype;
cdoptions : tcompare_defs_options;
+ selfnode: tnode;
newblock: tblocknode;
newstatement: tstatementnode;
tempnode: ttempcreatenode;
@@ -2657,8 +2658,13 @@
tprocdef(currprocdef),tcallnode(left).symtableproc);
if (tcallnode(left).symtableprocentry.owner.symtabletype=ObjectSymtable) then
begin
- if assigned(tcallnode(left).methodpointer) then
- tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy)
+ selfnode:=tcallnode(left).methodpointer;
+ if assigned(selfnode) then
+ begin
+ if selfnode.nodetype<>typen then
+ tloadnode(hp).set_mp(selfnode.getcopy)
+ // else: TODO: #BUGREPORT/TESTCASE
+ end
else
tloadnode(hp).set_mp(load_self_node);
end;
-------------- next part --------------
# HG changeset patch
# User Blaise.ru
# Date 1640149971 -10800
# Wed Dec 22 08:12:51 2021 +0300
! proper codegen for assigning class non-static methods, accessed via a class reference type, to method pointers
diff -r 250d0d636843 -r 31521fdb081e pexpr.pas
--- a/pexpr.pas Wed Dec 22 07:32:46 2021 +0300
+++ b/pexpr.pas Wed Dec 22 08:12:51 2021 +0300
@@ -1076,7 +1076,13 @@
else
begin
typecheckpass(p1);
- if (p1.resultdef.typ=objectdef) then
+ // TODO: #BUGREPORT/TESTCASE
+ 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
More information about the fpc-devel
mailing list