Browse Source

* 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 năm trước cách đây
mục cha
commit
3ecb41cd2d
3 tập tin đã thay đổi với 31 bổ sung8 xóa
  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;
 {$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;

+ 1 - 6
compiler/symdef.pas

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

+ 22 - 1
compiler/symtype.pas

@@ -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 }