I wrote:
It doesn't actually check for abstract object types, but now that you mention it, I think it should. Though it's not easy to get an object with a VMT pointer to an abstract type (the compiler will normally prevent it), it is possible with some tricks (and of course, due to dangling pointers, memory corruption etc., which such runtime checks are meant to catch).
There are several ways to achieve it.
(I.e., to achieve the checking, not producing the problem.)
One is to check for Size = 0. Since all object types in GPC have at least the VMT pointer, their size can never be 0, and GPC explicitly sets the Size field to 0 for abstract types. Another way is to produce an intentional mismatch of the NegatedSize field for abstract type VMTs. The following patch does the latter, as it avoids one more runtime check, and only changes the initialization of abstract VMTs.
PS: Necessary test program adjustment:
--- p/test/fjf636e.pas.orig Sat Jan 11 15:23:13 2003 +++ p/test/fjf636e.pas Thu Aug 3 21:02:10 2006 @@ -71,16 +71,16 @@ WriteLn ('failed 20 ', Name^, ' d') else with TypeOf (C)^ do if Size <> 0 then WriteLn ('failed 21 ', Size, ' ', 0) - else if NegatedSize <> 0 then - WriteLn ('failed 22 ', NegatedSize, ' ', 0) + else if NegatedSize <> -1 then + WriteLn ('failed 22 ', NegatedSize, ' ', -1) else if Parent <> nil then WriteLn ('failed 23 ', PtrInt (Parent), ' ', 0) else if Name^ <> 'C' then WriteLn ('failed 24 ', Name^, ' C') else with TypeOf (Ee)^ do if Size <> 0 then WriteLn ('failed 25 ', Size, ' ', 0) - else if NegatedSize <> 0 then - WriteLn ('failed 26 ', NegatedSize, ' ', 0) + else if NegatedSize <> -1 then + WriteLn ('failed 26 ', NegatedSize, ' ', -1) else if Parent <> nil then WriteLn ('failed 27 ', PtrInt (Parent), ' ', 0) else if Name^ <> 'Ee' then
Frank