Sign in or sign up before continuing. Don't have an account yet? Register now to get started.
OptVMTs whole-program optimization optimizes away virtual methods of “object”s whose constructor address was taken.
I don’t really care as I stopped using WPO and object
s long ago, but after I seen #40200 (closed) I remembered the problem I faced once, and checked it’s still present.
Run this program compiled with OptVMTs
whole-program optimization.
{$mode objfpc} {$longstrings on}
uses
Objects;
type
MyObjBase = object
constructor Create;
function GetVirt: string; virtual; abstract;
end;
MyObjA = object(MyObjBase)
constructor Create;
function GetVirt: string; virtual;
end;
MyObjB = object(MyObjBase)
constructor Create;
function GetVirt: string; virtual;
end;
constructor MyObjBase.Create; begin end;
constructor MyObjA.Create; begin end;
function MyObjA.GetVirt: string; begin result := 'MyObjA.GetVirt'; end;
constructor MyObjB.Create; begin end;
function MyObjB.GetVirt: string; begin result := 'MyObjB.GetVirt'; end;
type
MyObjFactory = record
ctr: CodePointer;
vmt: pointer;
end;
const
MyObjFactories: array[0 .. 1] of MyObjFactory =
(
(ctr: @MyObjA.Create; vmt: TypeOf(MyObjA)),
(ctr: @MyObjB.Create; vmt: TypeOf(MyObjB))
);
var
o: MyObjBase;
fact: MyObjFactory;
begin
for fact in MyObjFactories do
begin
CallVoidConstructor(fact.ctr, @o, fact.vmt);
writeln(o.GetVirt);
end;
end.
Without WPO, it works correctly:
MyObjA.GetVirt
MyObjB.GetVirt
With WPO, it throws 211 Call to abstract method
.