* 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 -
This commit is contained in:
Jonas Maebe 2017-01-15 17:41:27 +00:00
parent 382bbc1201
commit 048666a25c
4 changed files with 48 additions and 8 deletions

2
.gitattributes vendored
View File

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

View File

@ -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
tests/webtbf/tw25283.pp Normal file
View File

@ -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
tests/webtbf/uw25283.pp Normal file
View File

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