mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-17 05:00:37 +01:00
* don't mark classes used in "is"- or "as"-expressions as potentially
instantiated (for wpo)
* also replace vmt-entries for classes for which we don't have any
information at all with FPC_ABSTRACTERROR (since that means they
certainly are not instantiated), except for their published and
virtual class methods
* fixed check for published methods in wpo
git-svn-id: trunk@13219 -
This commit is contained in:
parent
380e957a79
commit
66c14c8a88
@ -3202,6 +3202,11 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
{ Passing a class type to an "is" expression cannot result in a class
|
||||||
|
of that type to be constructed.
|
||||||
|
}
|
||||||
|
include(right.flags,nf_ignore_for_wpo);
|
||||||
|
|
||||||
if (right.resultdef.typ=classrefdef) then
|
if (right.resultdef.typ=classrefdef) then
|
||||||
begin
|
begin
|
||||||
{ left must be a class }
|
{ left must be a class }
|
||||||
@ -3399,6 +3404,10 @@ implementation
|
|||||||
procname: string;
|
procname: string;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
|
{ Passing a class type to an "as" expression cannot result in a class
|
||||||
|
of that type to be constructed.
|
||||||
|
}
|
||||||
|
include(right.flags,nf_ignore_for_wpo);
|
||||||
if not assigned(call) then
|
if not assigned(call) then
|
||||||
begin
|
begin
|
||||||
if is_class(left.resultdef) and
|
if is_class(left.resultdef) and
|
||||||
|
|||||||
@ -172,9 +172,10 @@ implementation
|
|||||||
expectloc:=LOC_REGISTER;
|
expectloc:=LOC_REGISTER;
|
||||||
if left.nodetype<>typen then
|
if left.nodetype<>typen then
|
||||||
firstpass(left)
|
firstpass(left)
|
||||||
else if not assigned(current_procinfo) or
|
else if not(nf_ignore_for_wpo in flags) and
|
||||||
(po_inline in current_procinfo.procdef.procoptions) or
|
(not assigned(current_procinfo) or
|
||||||
wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname) then
|
(po_inline in current_procinfo.procdef.procoptions) or
|
||||||
|
wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
|
||||||
begin
|
begin
|
||||||
{ keep track of which classes might be instantiated via a classrefdef }
|
{ keep track of which classes might be instantiated via a classrefdef }
|
||||||
if (left.resultdef.typ=classrefdef) then
|
if (left.resultdef.typ=classrefdef) then
|
||||||
|
|||||||
@ -255,7 +255,16 @@ interface
|
|||||||
nf_get_asm_position,
|
nf_get_asm_position,
|
||||||
|
|
||||||
{ tblocknode }
|
{ tblocknode }
|
||||||
nf_block_with_exit
|
nf_block_with_exit,
|
||||||
|
|
||||||
|
{ tloadvmtaddrnode }
|
||||||
|
nf_ignore_for_wpo { we know that this loadvmtaddrnode cannot be used to construct a class instance }
|
||||||
|
|
||||||
|
{ WARNING: there are now 32 elements in this type, and a set of this
|
||||||
|
type is written to the PPU. So before adding any more elements,
|
||||||
|
either move some flags to specific nodes, or stream a normalset
|
||||||
|
to the ppu
|
||||||
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1054,18 +1054,6 @@ unit optvirt;
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ get the component names for the class/procdef combo }
|
|
||||||
defsdecompose(realobjdef,tprocdef(procdef),unitid,classid,vmtentry);
|
|
||||||
|
|
||||||
{ do we have any info for this unit? }
|
|
||||||
unitdevirtinfo:=findunit(unitid^);
|
|
||||||
result:=false;
|
|
||||||
if not assigned(unitdevirtinfo) then
|
|
||||||
exit;
|
|
||||||
{ and for this class? }
|
|
||||||
classdevirtinfo:=unitdevirtinfo.findclass(classid^);
|
|
||||||
if not assigned(classdevirtinfo) then
|
|
||||||
exit;
|
|
||||||
{ if it's for a vmtentry of an objdef and the objdef is
|
{ if it's for a vmtentry of an objdef and the objdef is
|
||||||
not instantiated, then we can fill the vmt with pointers
|
not instantiated, then we can fill the vmt with pointers
|
||||||
to FPC_ABSTRACTERROR, except for published methods
|
to FPC_ABSTRACTERROR, except for published methods
|
||||||
@ -1073,7 +1061,34 @@ unit optvirt;
|
|||||||
to the original method)
|
to the original method)
|
||||||
}
|
}
|
||||||
if forvmtentry and
|
if forvmtentry and
|
||||||
(tprocdef(procdef).procsym.visibility=vis_published) then
|
(tprocdef(procdef).visibility=vis_published) then
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ get the component names for the class/procdef combo }
|
||||||
|
defsdecompose(realobjdef,tprocdef(procdef),unitid,classid,vmtentry);
|
||||||
|
|
||||||
|
{ If we don't have information about a particular unit/class/method,
|
||||||
|
it means that such class cannot be instantiated. So if we are
|
||||||
|
looking up information for a vmt entry, we can always safely return
|
||||||
|
FPC_ABSTRACTERROR if we do not find anything, unless it's a
|
||||||
|
published method (but those are handled already above) or a
|
||||||
|
class method (can be called even if the class is not instantiated).
|
||||||
|
}
|
||||||
|
result:=
|
||||||
|
forvmtentry and
|
||||||
|
not(po_classmethod in tprocdef(procdef).procoptions);
|
||||||
|
staticname:='FPC_ABSTRACTERROR';
|
||||||
|
|
||||||
|
{ do we have any info for this unit? }
|
||||||
|
unitdevirtinfo:=findunit(unitid^);
|
||||||
|
if not assigned(unitdevirtinfo) then
|
||||||
|
exit;
|
||||||
|
{ and for this class? }
|
||||||
|
classdevirtinfo:=unitdevirtinfo.findclass(classid^);
|
||||||
|
if not assigned(classdevirtinfo) then
|
||||||
exit;
|
exit;
|
||||||
if forvmtentry and
|
if forvmtentry and
|
||||||
(objdef.typ=objectdef) and
|
(objdef.typ=objectdef) and
|
||||||
@ -1081,7 +1096,9 @@ unit optvirt;
|
|||||||
{ virtual class methods can be called even if the class is not instantiated }
|
{ virtual class methods can be called even if the class is not instantiated }
|
||||||
not(po_classmethod in tprocdef(procdef).procoptions) then
|
not(po_classmethod in tprocdef(procdef).procoptions) then
|
||||||
begin
|
begin
|
||||||
staticname:='FPC_ABSTRACTERROR';
|
{ already set above
|
||||||
|
staticname:='FPC_ABSTRACTERROR';
|
||||||
|
}
|
||||||
result:=true;
|
result:=true;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user