* fix writing of goto node to ppu

* replace derefnode with resolveppuidx method that only needs to be
    implemented for nodes referencing other nodes
  * fix IE when a label is not defined in inline function

git-svn-id: trunk@11697 -
This commit is contained in:
peter 2008-09-03 20:46:04 +00:00
parent 7aee2f3d71
commit 060bdbcb47
9 changed files with 124 additions and 133 deletions

3
.gitattributes vendored
View File

@ -8508,6 +8508,8 @@ tests/webtbs/tw11568.pp svneol=native#text/plain
tests/webtbs/tw1157.pp svneol=native#text/plain tests/webtbs/tw1157.pp svneol=native#text/plain
tests/webtbs/tw1157b.pp svneol=native#text/plain tests/webtbs/tw1157b.pp svneol=native#text/plain
tests/webtbs/tw11619.pp svneol=native#text/plain tests/webtbs/tw11619.pp svneol=native#text/plain
tests/webtbs/tw11762.pp svneol=native#text/plain
tests/webtbs/tw11763.pp svneol=native#text/plain
tests/webtbs/tw1181.pp svneol=native#text/plain tests/webtbs/tw1181.pp svneol=native#text/plain
tests/webtbs/tw11846a.pp svneol=native#text/plain tests/webtbs/tw11846a.pp svneol=native#text/plain
tests/webtbs/tw11846b.pp svneol=native#text/plain tests/webtbs/tw11846b.pp svneol=native#text/plain
@ -9424,6 +9426,7 @@ tests/webtbs/uw0701d.pp svneol=native#text/plain
tests/webtbs/uw0701e.pp svneol=native#text/plain tests/webtbs/uw0701e.pp svneol=native#text/plain
tests/webtbs/uw0809.pp svneol=native#text/plain tests/webtbs/uw0809.pp svneol=native#text/plain
tests/webtbs/uw11182.pp svneol=native#text/plain tests/webtbs/uw11182.pp svneol=native#text/plain
tests/webtbs/uw11762.pp svneol=native#text/plain
tests/webtbs/uw1181.inc svneol=native#text/plain tests/webtbs/uw1181.inc svneol=native#text/plain
tests/webtbs/uw1279.pp svneol=native#text/plain tests/webtbs/uw1279.pp svneol=native#text/plain
tests/webtbs/uw1331.pp svneol=native#text/plain tests/webtbs/uw1331.pp svneol=native#text/plain

View File

@ -136,7 +136,6 @@ type
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure derefnode;override;
function dogetcopy: tnode; override; function dogetcopy: tnode; override;
function pass_1 : tnode; override; function pass_1 : tnode; override;
function pass_typecheck: tnode; override; function pass_typecheck: tnode; override;
@ -153,8 +152,8 @@ type
constructor create_offset(const temp: ttempcreatenode;aoffset:longint); constructor create_offset(const temp: ttempcreatenode;aoffset:longint);
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override; constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure resolveppuidx;override;
function dogetcopy: tnode; override; function dogetcopy: tnode; override;
procedure derefnode;override;
function pass_1 : tnode; override; function pass_1 : tnode; override;
function pass_typecheck : tnode; override; function pass_typecheck : tnode; override;
procedure mark_write;override; procedure mark_write;override;
@ -176,8 +175,8 @@ type
constructor create_normal_temp(const temp: ttempcreatenode); constructor create_normal_temp(const temp: ttempcreatenode);
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override; constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure resolveppuidx;override;
function dogetcopy: tnode; override; function dogetcopy: tnode; override;
procedure derefnode;override;
function pass_1: tnode; override; function pass_1: tnode; override;
function pass_typecheck: tnode; override; function pass_typecheck: tnode; override;
function docompare(p: tnode): boolean; override; function docompare(p: tnode): boolean; override;
@ -817,14 +816,6 @@ implementation
end; end;
procedure ttempcreatenode.derefnode;
begin
inherited derefnode;
if assigned(tempinfo^.withnode) then
tempinfo^.withnode.derefnode;
end;
function ttempcreatenode.pass_1 : tnode; function ttempcreatenode.pass_1 : tnode;
begin begin
result := nil; result := nil;
@ -933,11 +924,10 @@ implementation
end; end;
procedure ttemprefnode.derefnode; procedure ttemprefnode.resolveppuidx;
var var
temp : ttempcreatenode; temp : ttempcreatenode;
begin begin
inherited derefnode;
temp:=ttempcreatenode(nodeppuidxget(tempidx)); temp:=ttempcreatenode(nodeppuidxget(tempidx));
if temp.nodetype<>tempcreaten then if temp.nodetype<>tempcreaten then
internalerror(200311075); internalerror(200311075);
@ -1067,7 +1057,7 @@ implementation
end; end;
procedure ttempdeletenode.derefnode; procedure ttempdeletenode.resolveppuidx;
var var
temp : ttempcreatenode; temp : ttempcreatenode;
begin begin

View File

@ -121,7 +121,6 @@ interface
destructor destroy;override; destructor destroy;override;
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override; constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefnode;override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
function dogetcopy : tnode;override; function dogetcopy : tnode;override;
@ -995,20 +994,6 @@ implementation
end; end;
procedure tcallnode.derefnode;
begin
if assigned(callinitblock) then
callinitblock.derefnode;
if assigned(methodpointer) then
methodpointer.derefnode;
if assigned(callcleanupblock) then
callcleanupblock.derefnode;
if assigned(funcretnode) then
funcretnode.derefnode;
inherited derefnode;
end;
procedure tcallnode.buildderefimpl; procedure tcallnode.buildderefimpl;
begin begin
inherited buildderefimpl; inherited buildderefimpl;

View File

@ -63,7 +63,6 @@ interface
function dogetcopy : tnode;override; function dogetcopy : tnode;override;
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override; constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefnode;override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure insertintolist(l : tnodelist);override; procedure insertintolist(l : tnodelist);override;
@ -129,6 +128,9 @@ interface
tcontinuenodeclass = class of tcontinuenode; tcontinuenodeclass = class of tcontinuenode;
tgotonode = class(tnode) tgotonode = class(tnode)
private
labelnodeidx : longint;
public
labelsym : tlabelsym; labelsym : tlabelsym;
labelnode : tlabelnode; labelnode : tlabelnode;
exceptionblock : integer; exceptionblock : integer;
@ -137,6 +139,7 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure resolveppuidx;override;
function dogetcopy : tnode;override; function dogetcopy : tnode;override;
function pass_typecheck:tnode;override; function pass_typecheck:tnode;override;
function pass_1 : tnode;override; function pass_1 : tnode;override;
@ -269,15 +272,6 @@ implementation
end; end;
procedure tloopnode.derefnode;
begin
inherited derefnode;
if assigned(t1) then
t1.derefnode;
if assigned(t2) then
t2.derefnode;
end;
procedure tloopnode.buildderefimpl; procedure tloopnode.buildderefimpl;
begin begin
inherited buildderefimpl; inherited buildderefimpl;
@ -972,7 +966,7 @@ implementation
constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile); constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
begin begin
inherited ppuload(t,ppufile); inherited ppuload(t,ppufile);
labelnode:=tlabelnode(ppuloadnoderef(ppufile)); labelnodeidx:=ppufile.getlongint;
exceptionblock:=ppufile.getbyte; exceptionblock:=ppufile.getbyte;
end; end;
@ -980,7 +974,8 @@ implementation
procedure tgotonode.ppuwrite(ppufile:tcompilerppufile); procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
begin begin
inherited ppuwrite(ppufile); inherited ppuwrite(ppufile);
ppuwritenoderef(ppufile,labelnode); labelnodeidx:=labelnode.ppuidx;
ppufile.putlongint(labelnodeidx);
ppufile.putbyte(exceptionblock); ppufile.putbyte(exceptionblock);
end; end;
@ -988,14 +983,20 @@ implementation
procedure tgotonode.buildderefimpl; procedure tgotonode.buildderefimpl;
begin begin
inherited buildderefimpl; inherited buildderefimpl;
//!!! deref(labelnode);
end; end;
procedure tgotonode.derefimpl; procedure tgotonode.derefimpl;
begin begin
inherited derefimpl; inherited derefimpl;
//!!! deref(labelnode); end;
procedure tgotonode.resolveppuidx;
begin
labelnode:=tlabelnode(nodeppuidxget(labelnodeidx));
if labelnode.nodetype<>labeln then
internalerror(200809021);
end; end;
@ -1036,17 +1037,23 @@ implementation
p:=tgotonode(inherited dogetcopy); p:=tgotonode(inherited dogetcopy);
p.exceptionblock:=exceptionblock; p.exceptionblock:=exceptionblock;
{ force a valid labelnode } { generate labelnode if not done yet }
if not(assigned(labelnode)) then if not(assigned(labelnode)) then
begin begin
if assigned(labelsym) and assigned(labelsym.code) then if assigned(labelsym) and assigned(labelsym.code) then
labelnode:=tlabelnode(labelsym.code) labelnode:=tlabelnode(labelsym.code)
else
internalerror(200610291);
end; end;
p.labelsym:=labelsym; p.labelsym:=labelsym;
p.labelnode:=tlabelnode(labelnode.dogetcopy); if assigned(labelnode) then
p.labelnode:=tlabelnode(labelnode.dogetcopy)
else
begin
{ don't trigger IE when there was already an error, i.e. the
label is not defined. See tw11763 (PFV) }
if errorcount=0 then
internalerror(200610291);
end;
result:=p; result:=p;
end; end;

View File

@ -271,6 +271,9 @@ interface
pnode = ^tnode; pnode = ^tnode;
{ basic class for the intermediated representation fpc uses } { basic class for the intermediated representation fpc uses }
tnode = class tnode = class
private
fppuidx : longint;
function getppuidx:longint;
public public
{ type of this node } { type of this node }
nodetype : tnodetype; nodetype : tnodetype;
@ -291,7 +294,6 @@ interface
successor : tnode; successor : tnode;
{ there are some properties about the node stored } { there are some properties about the node stored }
flags : tnodeflags; flags : tnodeflags;
ppuidx : longint;
resultdef : tdef; resultdef : tdef;
resultdefderef : tderef; resultdefderef : tderef;
fileinfo : tfileposinfo; fileinfo : tfileposinfo;
@ -306,7 +308,7 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);virtual; procedure ppuwrite(ppufile:tcompilerppufile);virtual;
procedure buildderefimpl;virtual; procedure buildderefimpl;virtual;
procedure derefimpl;virtual; procedure derefimpl;virtual;
procedure derefnode;virtual; procedure resolveppuidx;virtual;
{ toggles the flag } { toggles the flag }
procedure toggleflag(f : tnodeflag); procedure toggleflag(f : tnodeflag);
@ -362,6 +364,7 @@ interface
{ ensures that the optimizer info record is allocated } { ensures that the optimizer info record is allocated }
function allocoptinfo : poptinfo;inline; function allocoptinfo : poptinfo;inline;
property ppuidx:longint read getppuidx;
end; end;
tnodeclass = class of tnode; tnodeclass = class of tnode;
@ -380,7 +383,6 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure derefnode;override;
procedure concattolist(l : tlinkedlist);override; procedure concattolist(l : tlinkedlist);override;
function ischild(p : tnode) : boolean;override; function ischild(p : tnode) : boolean;override;
function docompare(p : tnode) : boolean;override; function docompare(p : tnode) : boolean;override;
@ -398,7 +400,6 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure derefnode;override;
procedure concattolist(l : tlinkedlist);override; procedure concattolist(l : tlinkedlist);override;
function ischild(p : tnode) : boolean;override; function ischild(p : tnode) : boolean;override;
function docompare(p : tnode) : boolean;override; function docompare(p : tnode) : boolean;override;
@ -418,7 +419,6 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure derefnode;override;
procedure concattolist(l : tlinkedlist);override; procedure concattolist(l : tlinkedlist);override;
function ischild(p : tnode) : boolean;override; function ischild(p : tnode) : boolean;override;
function docompare(p : tnode) : boolean;override; function docompare(p : tnode) : boolean;override;
@ -441,8 +441,6 @@ interface
procedure ppuwritenode(ppufile:tcompilerppufile;n:tnode); procedure ppuwritenode(ppufile:tcompilerppufile;n:tnode);
function ppuloadnodetree(ppufile:tcompilerppufile):tnode; function ppuloadnodetree(ppufile:tcompilerppufile):tnode;
procedure ppuwritenodetree(ppufile:tcompilerppufile;n:tnode); procedure ppuwritenodetree(ppufile:tcompilerppufile;n:tnode);
procedure ppuwritenoderef(ppufile:tcompilerppufile;n:tnode);
function ppuloadnoderef(ppufile:tcompilerppufile) : tnode;
const const
printnodespacing = ' '; printnodespacing = ' ';
@ -481,40 +479,59 @@ implementation
****************************************************************************} ****************************************************************************}
var var
nodeppudata : tdynamicarray; nodeppulist : TFPObjectList;
nodeppuidx : longint; nodeppuidx : longint;
procedure nodeppuidxcreate; procedure nodeppuidxcreate;
begin begin
nodeppudata:=tdynamicarray.create(1024); nodeppulist:=TFPObjectList.Create(false);
nodeppuidx:=0; nodeppuidx:=0;
end; end;
procedure nodeppuidxresolve;
var
i : longint;
n : tnode;
begin
for i:=0 to nodeppulist.count-1 do
begin
n:=tnode(nodeppulist[i]);
if assigned(n) then
n.resolveppuidx;
end;
end;
procedure nodeppuidxfree; procedure nodeppuidxfree;
begin begin
nodeppudata.free; nodeppulist.free;
nodeppudata:=nil; nodeppulist:=nil;
nodeppuidx:=0;
end; end;
procedure nodeppuidxadd(n:tnode); procedure nodeppuidxadd(n:tnode);
var
i : longint;
begin begin
if n.ppuidx<0 then i:=n.ppuidx;
if i<=0 then
internalerror(200311072); internalerror(200311072);
nodeppudata.seek(n.ppuidx*sizeof(pointer)); if i>=nodeppulist.capacity then
nodeppudata.write(n,sizeof(pointer)); nodeppulist.capacity:=((i div 1024)+1)*1024;
if i>=nodeppulist.count then
nodeppulist.count:=i+1;
nodeppulist[i]:=n;
end; end;
function nodeppuidxget(i:longint):tnode; function nodeppuidxget(i:longint):tnode;
begin begin
if i<0 then if i<=0 then
internalerror(200311072);
nodeppudata.seek(i*sizeof(pointer));
if nodeppudata.read(result,sizeof(pointer))<>sizeof(pointer) then
internalerror(200311073); internalerror(200311073);
result:=tnode(nodeppulist[i]);
end; end;
@ -540,7 +557,7 @@ implementation
//writeln('load: ',nodetype2str[t]); //writeln('load: ',nodetype2str[t]);
{ generate node of the correct class } { generate node of the correct class }
result:=nodeclass[t].ppuload(t,ppufile); result:=nodeclass[t].ppuload(t,ppufile);
result.ppuidx:=hppuidx; result.fppuidx:=hppuidx;
nodeppuidxadd(result); nodeppuidxadd(result);
end end
else else
@ -555,10 +572,6 @@ implementation
{ type, read by ppuloadnode } { type, read by ppuloadnode }
if assigned(n) then if assigned(n) then
begin begin
if n.ppuidx=-1 then
internalerror(200311071);
n.ppuidx:=nodeppuidx;
inc(nodeppuidx);
ppufile.putbyte(byte(n.nodetype)); ppufile.putbyte(byte(n.nodetype));
ppufile.putlongint(n.ppuidx); ppufile.putlongint(n.ppuidx);
//writeln('write: ',nodetype2str[n.nodetype]); //writeln('write: ',nodetype2str[n.nodetype]);
@ -569,38 +582,23 @@ implementation
end; end;
procedure ppuwritenoderef(ppufile:tcompilerppufile;n:tnode);
begin
{ writing of node references isn't implemented yet (FK) }
internalerror(200506181);
end;
function ppuloadnoderef(ppufile:tcompilerppufile) : tnode;
begin
{ reading of node references isn't implemented yet (FK) }
internalerror(200506182);
{ avoid warning }
result := nil;
end;
function ppuloadnodetree(ppufile:tcompilerppufile):tnode; function ppuloadnodetree(ppufile:tcompilerppufile):tnode;
begin begin
if ppufile.readentry<>ibnodetree then if ppufile.readentry<>ibnodetree then
Message(unit_f_ppu_read_error); Message(unit_f_ppu_read_error);
nodeppuidxcreate; nodeppuidxcreate;
result:=ppuloadnode(ppufile); result:=ppuloadnode(ppufile);
result.derefnode; nodeppuidxresolve;
nodeppuidxfree; nodeppuidxfree;
end; end;
procedure ppuwritenodetree(ppufile:tcompilerppufile;n:tnode); procedure ppuwritenodetree(ppufile:tcompilerppufile;n:tnode);
begin begin
nodeppuidx:=0; nodeppuidxcreate;
ppuwritenode(ppufile,n); ppuwritenode(ppufile,n);
ppufile.writeentry(ibnodetree); ppufile.writeentry(ibnodetree);
nodeppuidxfree;
end; end;
@ -691,7 +689,6 @@ implementation
localswitches:=current_settings.localswitches; localswitches:=current_settings.localswitches;
resultdef:=nil; resultdef:=nil;
flags:=[]; flags:=[];
ppuidx:=-1;
end; end;
constructor tnode.createforcopy; constructor tnode.createforcopy;
@ -713,7 +710,6 @@ implementation
expectloc:=LOC_INVALID; expectloc:=LOC_INVALID;
{ updated by secondpass } { updated by secondpass }
location.loc:=LOC_INVALID; location.loc:=LOC_INVALID;
ppuidx:=-1;
end; end;
@ -727,6 +723,22 @@ implementation
end; end;
function tnode.getppuidx:longint;
begin
if fppuidx=0 then
begin
inc(nodeppuidx);
fppuidx:=nodeppuidx;
end;
result:=fppuidx;
end;
procedure tnode.resolveppuidx;
begin
end;
procedure tnode.buildderefimpl; procedure tnode.buildderefimpl;
begin begin
resultdefderef.build(resultdef); resultdefderef.build(resultdef);
@ -739,11 +751,6 @@ implementation
end; end;
procedure tnode.derefnode;
begin
end;
procedure tnode.toggleflag(f : tnodeflag); procedure tnode.toggleflag(f : tnodeflag);
begin begin
if f in flags then if f in flags then
@ -944,14 +951,6 @@ implementation
end; end;
procedure tunarynode.derefnode;
begin
inherited derefnode;
if assigned(left) then
left.derefnode;
end;
function tunarynode.docompare(p : tnode) : boolean; function tunarynode.docompare(p : tnode) : boolean;
begin begin
docompare:=(inherited docompare(p) and docompare:=(inherited docompare(p) and
@ -1047,14 +1046,6 @@ implementation
end; end;
procedure tbinarynode.derefnode;
begin
inherited derefnode;
if assigned(right) then
right.derefnode;
end;
procedure tbinarynode.concattolist(l : tlinkedlist); procedure tbinarynode.concattolist(l : tlinkedlist);
begin begin
{ we could change that depending on the number of } { we could change that depending on the number of }
@ -1188,14 +1179,6 @@ implementation
end; end;
procedure ttertiarynode.derefnode;
begin
inherited derefnode;
if assigned(third) then
third.derefnode;
end;
function ttertiarynode.docompare(p : tnode) : boolean; function ttertiarynode.docompare(p : tnode) : boolean;
begin begin
docompare:=(inherited docompare(p) and docompare:=(inherited docompare(p) and

View File

@ -83,7 +83,6 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure buildderefimpl;override; procedure buildderefimpl;override;
procedure derefimpl;override; procedure derefimpl;override;
procedure derefnode;override;
function dogetcopy : tnode;override; function dogetcopy : tnode;override;
procedure insertintolist(l : tnodelist);override; procedure insertintolist(l : tnodelist);override;
function pass_typecheck:tnode;override; function pass_typecheck:tnode;override;
@ -590,18 +589,6 @@ implementation
end; end;
procedure tcasenode.derefnode;
var
i : integer;
begin
inherited derefnode;
if assigned(elseblock) then
elseblock.derefnode;
for i:=0 to blocks.count-1 do
pcaseblock(blocks[i])^.statement.derefnode;
end;
function tcasenode.pass_typecheck : tnode; function tcasenode.pass_typecheck : tnode;
begin begin
result:=nil; result:=nil;

11
tests/webtbs/tw11762.pp Normal file
View File

@ -0,0 +1,11 @@
uses uw11762;
begin
i:=0;
p;
p;
p;
p;
if i<>4 then
halt(1);
end.

8
tests/webtbs/tw11763.pp Normal file
View File

@ -0,0 +1,8 @@
procedure p; inline;
label x;
begin
goto x
end;
begin
end.

17
tests/webtbs/uw11762.pp Normal file
View File

@ -0,0 +1,17 @@
unit uw11762;
interface
procedure p; inline;
var
i : longint;
implementation
procedure p; inline;
label x;
begin
goto x;
i:=i+10;
x:
i:=i+1;
end;
begin
end.