mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 18:49:14 +02:00
* fixed bug that sporadically caused the column of certain nodes to
change, resulting in slightly different DWARF debug information (mantis #13508) The cause was saving a node pointer in a local variable, processing it further, and later on checking whether it changed by comparing the stored and the current instance pointer. The problem was that the node could have been freed and reallocated at the same address (but with different contents), so this check sometimes resulted in (hard to reproduce) false negatives. git-svn-id: trunk@13580 -
This commit is contained in:
parent
2f7457f37e
commit
a64c5a7b23
@ -30,6 +30,7 @@ interface
|
||||
|
||||
procedure typecheckpass(var p : tnode);
|
||||
function do_typecheckpass(var p : tnode) : boolean;
|
||||
function do_typecheckpass_changed(var p : tnode; out nodechanged: boolean) : boolean;
|
||||
|
||||
procedure firstpass(var p : tnode);
|
||||
function do_firstpass(var p : tnode) : boolean;
|
||||
@ -57,7 +58,7 @@ implementation
|
||||
Global procedures
|
||||
*****************************************************************************}
|
||||
|
||||
procedure typecheckpass(var p : tnode);
|
||||
procedure typecheckpass_internal(var p : tnode; out node_changed: boolean);
|
||||
var
|
||||
oldcodegenerror : boolean;
|
||||
oldlocalswitches : tlocalswitches;
|
||||
@ -65,6 +66,7 @@ implementation
|
||||
oldpos : tfileposinfo;
|
||||
hp : tnode;
|
||||
begin
|
||||
node_changed:=false;
|
||||
if (p.resultdef=nil) then
|
||||
begin
|
||||
oldcodegenerror:=codegenerror;
|
||||
@ -79,6 +81,7 @@ implementation
|
||||
{ should the node be replaced? }
|
||||
if assigned(hp) then
|
||||
begin
|
||||
node_changed:=true;
|
||||
p.free;
|
||||
{ run typecheckpass }
|
||||
typecheckpass(hp);
|
||||
@ -106,11 +109,27 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function do_typecheckpass(var p : tnode) : boolean;
|
||||
procedure typecheckpass(var p : tnode);
|
||||
var
|
||||
node_changed: boolean;
|
||||
begin
|
||||
typecheckpass_internal(p,node_changed);
|
||||
end;
|
||||
|
||||
|
||||
function do_typecheckpass_changed(var p : tnode; out nodechanged: boolean) : boolean;
|
||||
begin
|
||||
codegenerror:=false;
|
||||
typecheckpass(p);
|
||||
do_typecheckpass:=codegenerror;
|
||||
typecheckpass_internal(p,nodechanged);
|
||||
do_typecheckpass_changed:=codegenerror;
|
||||
end;
|
||||
|
||||
|
||||
function do_typecheckpass(var p : tnode) : boolean;
|
||||
var
|
||||
nodechanged: boolean;
|
||||
begin
|
||||
result:=do_typecheckpass_changed(p,nodechanged);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -1283,7 +1283,7 @@ implementation
|
||||
Factor_read_id
|
||||
---------------------------------------------}
|
||||
|
||||
procedure factor_read_id(var p1:tnode;var again:boolean);
|
||||
procedure factor_read_id(out p1:tnode;var again:boolean);
|
||||
var
|
||||
pc : pchar;
|
||||
srsym : tsym;
|
||||
@ -1702,7 +1702,8 @@ implementation
|
||||
PostFixOperators
|
||||
---------------------------------------------}
|
||||
|
||||
procedure postfixoperators(var p1:tnode;var again:boolean);
|
||||
{ returns whether or not p1 has been changed }
|
||||
function postfixoperators(var p1:tnode;var again:boolean): boolean;
|
||||
|
||||
{ tries to avoid syntax errors after invalid qualifiers }
|
||||
procedure recoverconsume_postfixops;
|
||||
@ -1819,14 +1820,17 @@ implementation
|
||||
{ shouldn't be used that often, so the extra overhead is ok to save
|
||||
stack space }
|
||||
dispatchstring : ansistring;
|
||||
nodechanged : boolean;
|
||||
label
|
||||
skipreckklammercheck;
|
||||
begin
|
||||
result:=false;
|
||||
again:=true;
|
||||
while again do
|
||||
begin
|
||||
{ we need the resultdef }
|
||||
do_typecheckpass(p1);
|
||||
do_typecheckpass_changed(p1,nodechanged);
|
||||
result:=result or nodechanged;
|
||||
|
||||
if codegenerror then
|
||||
begin
|
||||
@ -1887,6 +1891,7 @@ implementation
|
||||
begin
|
||||
consume(_LECKKLAMMER);
|
||||
repeat
|
||||
{ in all of the cases below, p1 is changed }
|
||||
case p1.resultdef.typ of
|
||||
pointerdef:
|
||||
begin
|
||||
@ -2152,6 +2157,11 @@ implementation
|
||||
again:=false;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ we only try again if p1 was changed }
|
||||
if again or
|
||||
(p1.nodetype=errorn) then
|
||||
result:=true;
|
||||
end; { while again }
|
||||
end;
|
||||
|
||||
@ -2164,10 +2174,8 @@ implementation
|
||||
l : longint;
|
||||
ic : int64;
|
||||
qc : qword;
|
||||
oldp1,
|
||||
p1 : tnode;
|
||||
code : integer;
|
||||
again : boolean;
|
||||
srsym : tsym;
|
||||
srsymtable : TSymtable;
|
||||
pd : tprocdef;
|
||||
@ -2177,8 +2185,13 @@ implementation
|
||||
hs,hsorg : string;
|
||||
hdef : tdef;
|
||||
filepos : tfileposinfo;
|
||||
again,
|
||||
updatefpos,
|
||||
nodechanged : boolean;
|
||||
begin
|
||||
oldp1:=nil;
|
||||
{ can't keep a copy of p1 and compare pointers afterwards, because
|
||||
p1 may be freed and reallocated in the same place! }
|
||||
updatefpos:=false;
|
||||
p1:=nil;
|
||||
filepos:=current_tokenpos;
|
||||
again:=false;
|
||||
@ -2197,20 +2210,20 @@ implementation
|
||||
else
|
||||
factor_read_id(p1,again);
|
||||
|
||||
if again then
|
||||
begin
|
||||
if (p1<>oldp1) then
|
||||
begin
|
||||
if assigned(p1) then
|
||||
begin
|
||||
{ factor_read_id will set the filepos to after the id,
|
||||
and in case of _SELF the filepos will already be the
|
||||
same as filepos (so setting it again doesn't hurt). }
|
||||
p1.fileinfo:=filepos;
|
||||
oldp1:=p1;
|
||||
filepos:=current_tokenpos;
|
||||
end;
|
||||
{ handle post fix operators }
|
||||
postfixoperators(p1,again);
|
||||
end;
|
||||
updatefpos:=postfixoperators(p1,again);
|
||||
end
|
||||
else
|
||||
begin
|
||||
updatefpos:=true;
|
||||
case token of
|
||||
_RETURN :
|
||||
begin
|
||||
@ -2463,7 +2476,8 @@ implementation
|
||||
begin
|
||||
again:=true;
|
||||
postfixoperators(p1,again);
|
||||
end;
|
||||
end
|
||||
else
|
||||
consume(_RKLAMMER);
|
||||
end
|
||||
else
|
||||
@ -2475,6 +2489,7 @@ implementation
|
||||
end;
|
||||
got_addrn:=false;
|
||||
p1:=caddrnode.create(p1);
|
||||
p1.fileinfo:=filepos;
|
||||
if cs_typed_addresses in current_settings.localswitches then
|
||||
include(p1.flags,nf_typedaddr);
|
||||
{ Store the procvar that we are expecting, the
|
||||
@ -2590,6 +2605,7 @@ implementation
|
||||
consume(token);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ generate error node if no node is created }
|
||||
if not assigned(p1) then
|
||||
@ -2598,14 +2614,18 @@ implementation
|
||||
Comment(V_Warning,'factor: p1=nil');
|
||||
{$endif}
|
||||
p1:=cerrornode.create;
|
||||
updatefpos:=true;
|
||||
end;
|
||||
|
||||
{ get the resultdef for the node }
|
||||
if (not assigned(p1.resultdef)) then
|
||||
do_typecheckpass(p1);
|
||||
begin
|
||||
do_typecheckpass_changed(p1,nodechanged);
|
||||
updatefpos:=updatefpos or nodechanged;
|
||||
end;
|
||||
|
||||
if assigned(p1) and
|
||||
(p1<>oldp1) then
|
||||
updatefpos then
|
||||
p1.fileinfo:=filepos;
|
||||
factor:=p1;
|
||||
end;
|
||||
@ -2736,9 +2756,9 @@ implementation
|
||||
|
||||
var
|
||||
p1,p2 : tnode;
|
||||
oldafterassignment : boolean;
|
||||
oldp1 : tnode;
|
||||
filepos : tfileposinfo;
|
||||
oldafterassignment,
|
||||
updatefpos : boolean;
|
||||
|
||||
begin
|
||||
oldafterassignment:=afterassignment;
|
||||
@ -2749,7 +2769,7 @@ implementation
|
||||
filepos:=current_tokenpos;
|
||||
if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
|
||||
afterassignment:=true;
|
||||
oldp1:=p1;
|
||||
updatefpos:=true;
|
||||
case token of
|
||||
_POINTPOINT :
|
||||
begin
|
||||
@ -2792,12 +2812,14 @@ implementation
|
||||
p2:=sub_expr(opcompare,true);
|
||||
p1:=gen_c_style_operator(slashn,p1,p2);
|
||||
end;
|
||||
else
|
||||
updatefpos:=false;
|
||||
end;
|
||||
{ get the resultdef for this expression }
|
||||
if not assigned(p1.resultdef) then
|
||||
do_typecheckpass(p1);
|
||||
afterassignment:=oldafterassignment;
|
||||
if p1<>oldp1 then
|
||||
if updatefpos then
|
||||
p1.fileinfo:=filepos;
|
||||
expr:=p1;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user