Bläddra i källkod

* when freeing a procdef that hasn't been registered for writing to the ppu
at the end of compiling a unit, also remove it from its owning procsym
in case the procsym does get written to the ppu (possible because you
can have extra overloads in the implementation) (mantis #25283)
o also fixes webtbf/tw4103 on the platforms where this still failed
(on the platforms where it worked, it worked by accedent since the
compiler was accessing memory of a freed procdef)

git-svn-id: trunk@35309 -

Jonas Maebe 8 år sedan
förälder
incheckning
048666a25c
4 ändrade filer med 48 tillägg och 8 borttagningar
  1. 2 0
      .gitattributes
  2. 17 8
      compiler/pmodules.pas
  3. 11 0
      tests/webtbf/tw25283.pp
  4. 18 0
      tests/webtbf/uw25283.pp

+ 2 - 0
.gitattributes

@@ -13766,6 +13766,7 @@ tests/webtbf/tw24588.pp svneol=native#text/pascal
 tests/webtbf/tw2478.pp svneol=native#text/plain
 tests/webtbf/tw25029.pp svneol=native#text/pascal
 tests/webtbf/tw25215.pp svneol=native#text/pascal
+tests/webtbf/tw25283.pp svneol=native#text/plain
 tests/webtbf/tw25318.pp svneol=native#text/pascal
 tests/webtbf/tw25504.pp svneol=native#text/plain
 tests/webtbf/tw2562.pp svneol=native#text/plain
@@ -13978,6 +13979,7 @@ tests/webtbf/uw0840a.pp svneol=native#text/plain
 tests/webtbf/uw0840b.pp svneol=native#text/plain
 tests/webtbf/uw0856.pp svneol=native#text/plain
 tests/webtbf/uw2414.pp svneol=native#text/plain
+tests/webtbf/uw25283.pp svneol=native#text/plain
 tests/webtbf/uw3450.pp svneol=native#text/plain
 tests/webtbf/uw3969.pp svneol=native#text/plain
 tests/webtbf/uw4103.pp svneol=native#text/plain

+ 17 - 8
compiler/pmodules.pas

@@ -577,6 +577,23 @@ implementation
         def: tdef;
         sym: tsym;
       begin
+        for i:=current_module.localsymtable.deflist.count-1 downto 0 do
+          begin
+            def:=tdef(current_module.localsymtable.deflist[i]);
+            { this also frees def, as the defs are owned by the symtable }
+            if not def.is_registered and
+               not(df_not_registered_no_free in def.defoptions) then
+              begin
+                { if it's a procdef, unregister it from its procsym first,
+                  unless that sym hasn't been registered either (it's possible
+                  to have one overload in the interface and another in the
+                  implementation) }
+                if (def.typ=procdef) and
+                   tprocdef(def).procsym.is_registered then
+                 tprocsym(tprocdef(def).procsym).ProcdefList.Remove(def);
+                current_module.localsymtable.deletedef(def);
+              end;
+          end;
         { from high to low so we hopefully have moves of less data }
         for i:=current_module.localsymtable.symlist.count-1 downto 0 do
           begin
@@ -585,14 +602,6 @@ implementation
             if not sym.is_registered then
               current_module.localsymtable.Delete(sym);
           end;
-        for i:=current_module.localsymtable.deflist.count-1 downto 0 do
-          begin
-            def:=tdef(current_module.localsymtable.deflist[i]);
-            { this also frees def, as the defs are owned by the symtable }
-            if not def.is_registered and
-               not(df_not_registered_no_free in def.defoptions) then
-              current_module.localsymtable.deletedef(def);
-          end;
       end;
 
 

+ 11 - 0
tests/webtbf/tw25283.pp

@@ -0,0 +1,11 @@
+{ %fail }
+
+program main;
+{$ifdef FPC}{$mode objfpc}{$h+}{$endif}
+uses bugunit;
+
+begin
+  proc( 1, 2 ); // no error with -B compiler flag
+end.
+
+

+ 18 - 0
tests/webtbf/uw25283.pp

@@ -0,0 +1,18 @@
+unit uw25283;
+{$ifdef FPC}{$mode objfpc}{$h+}{$endif}
+interface
+
+procedure proc( arg1: longint );
+
+implementation
+
+procedure proc( arg1: longint );
+begin
+end;
+
+procedure proc( arg1, arg2: longint ); 
+begin
+end;
+
+end.
+