* improvements to the prevention of dangling pointers in tmodule.deflist,

introduced in r49417. Now it no longer depends on current_module, so it
  handles the case when current_module changes between the time the tdef was
  registered and the time it was freed. It also supports freeing the tmodule
  before the defs, so the freeing order of the object is once again flexible.

git-svn-id: trunk@49426 -
This commit is contained in:
nickysn 2021-06-01 15:02:26 +00:00
parent 1957ea11cb
commit 3ecb41cd2d
3 changed files with 31 additions and 8 deletions

View File

@ -731,7 +731,14 @@ implementation
memsymtable.start;
{$endif}
derefdata.free;
deflist.free;
if assigned(deflist) then
begin
for i:=0 to deflist.Count-1 do
if assigned(deflist[i]) and (deflist[i] is tstoreddef) and
(tstoreddef(deflist[i]).registered_in_module=self) then
tstoreddef(deflist[i]).registered_in_module:=nil;
deflist.free;
end;
symlist.free;
ptrdefs.free;
arraydefs.free;

View File

@ -1987,12 +1987,6 @@ implementation
{$ifndef symansistr}
stringdispose(_fullownerhierarchyname);
{$endif not symansistr}
{ set self to nil in current_module's deflist, if the def has been
registered, in order to avoid dangling pointers in current_module.deflist }
if registered and assigned(current_module) and
(defid>=0) and (defid<current_module.deflist.Count) and
(current_module.deflist[defid]=self) then
current_module.deflist[defid]:=nil;
inherited destroy;
end;
@ -2537,6 +2531,7 @@ implementation
begin
current_module.deflist.Add(self);
defid:=current_module.deflist.Count-1;
registered_in_module:=current_module;
end;
maybe_put_in_symtable_stack;
end

View File

@ -33,7 +33,8 @@ interface
{ symtable }
symconst,symbase,
{ aasm }
aasmbase,ppu
aasmbase,ppu,
finput
;
type
@ -65,6 +66,7 @@ interface
function XMLPrintType: ansistring; virtual;
{$endif DEBUG_NODE_XML}
public
registered_in_module : tmodulebase;
typesym : tsym; { which type the definition was generated this def }
{ stabs debugging }
stab_number : word;
@ -72,6 +74,7 @@ interface
defoptions : tdefoptions;
defstates : tdefstates;
constructor create(dt:tdeftyp);
destructor destroy; override;
procedure buildderef;virtual;abstract;
procedure buildderefimpl;virtual;abstract;
procedure deref;virtual;abstract;
@ -383,6 +386,23 @@ implementation
end;
destructor tdef.destroy;
begin
{ set self to nil in registered_in_module's deflist, if the def has been
registered, in order to avoid dangling pointers in registered_in_module.deflist }
if assigned(registered_in_module) then
begin
if defid>=0 then
tmodule(registered_in_module).deflist[defid]:=nil
else if defid<defid_not_registered then
tmodule(registered_in_module).deflist[-(defid-defid_not_registered+1)]:=nil
else
internalerror(2021060101);
end;
inherited;
end;
function tdef.typename:string;
begin
result:=OwnerHierarchyName;
@ -446,6 +466,7 @@ implementation
if not assigned(current_module) then
internalerror(2015102505);
current_module.deflist.Add(self);
registered_in_module:=current_module;
{ invert the defid to indicate that it was only set because we
needed a unique number -- then add defid_not_registered so we
don't get the values between defid_registered and 0 }