Преглед изворни кода

* 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 -

nickysn пре 4 година
родитељ
комит
3ecb41cd2d
3 измењених фајлова са 31 додато и 8 уклоњено
  1. 8 1
      compiler/fmodule.pas
  2. 1 6
      compiler/symdef.pas
  3. 22 1
      compiler/symtype.pas

+ 8 - 1
compiler/fmodule.pas

@@ -731,7 +731,14 @@ implementation
         memsymtable.start;
         memsymtable.start;
 {$endif}
 {$endif}
         derefdata.free;
         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;
         symlist.free;
         ptrdefs.free;
         ptrdefs.free;
         arraydefs.free;
         arraydefs.free;

+ 1 - 6
compiler/symdef.pas

@@ -1987,12 +1987,6 @@ implementation
 {$ifndef symansistr}
 {$ifndef symansistr}
         stringdispose(_fullownerhierarchyname);
         stringdispose(_fullownerhierarchyname);
 {$endif not symansistr}
 {$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;
         inherited destroy;
       end;
       end;
 
 
@@ -2537,6 +2531,7 @@ implementation
              begin
              begin
                current_module.deflist.Add(self);
                current_module.deflist.Add(self);
                defid:=current_module.deflist.Count-1;
                defid:=current_module.deflist.Count-1;
+               registered_in_module:=current_module;
              end;
              end;
            maybe_put_in_symtable_stack;
            maybe_put_in_symtable_stack;
          end
          end

+ 22 - 1
compiler/symtype.pas

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