fcl-passrc: process TBinaryExpr left lists without stack

git-svn-id: trunk@49030 -
This commit is contained in:
Mattias Gaertner 2021-03-22 17:29:50 +00:00
parent de0e5919c9
commit 3c18b7e3b6
3 changed files with 52 additions and 6 deletions

View File

@ -1546,7 +1546,7 @@ begin
if SubBin.OpCode<>eopAdd then break;
Left:=SubBin.left;
end;
LeftValue:=Eval(Expr.left,Flags);
LeftValue:=Eval(Left,Flags);
while LeftValue<>nil do
begin
SubBin:=TBinaryExpr(Left.Parent);

View File

@ -5873,7 +5873,6 @@ begin
end;
end;
constructor TBinaryExpr.Create(AParent : TPasElement; xleft,xright:TPasExpr; AOpCode:TExprOpCode);
begin
inherited Create(AParent,pekBinary, AOpCode);
@ -5893,9 +5892,33 @@ begin
end;
destructor TBinaryExpr.Destroy;
var
El: TPasExpr;
SubBin: TBinaryExpr;
begin
ReleaseAndNil(TPasElement(left){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.left'{$ENDIF});
ReleaseAndNil(TPasElement(right){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.right'{$ENDIF});
// handle left of binary chains without stack
El:=Left;
while El is TBinaryExpr do
begin
SubBin:=TBinaryExpr(El);
El:=SubBin.left;
if (El=nil) or (El.Parent<>SubBin) then
begin
El:=SubBin;
break;
end;
end;
repeat
if El=left then
SubBin:=Self
else
SubBin:=TBinaryExpr(El.Parent);
ReleaseAndNil(TPasElement(SubBin.left){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.left'{$ENDIF});
ReleaseAndNil(TPasElement(SubBin.right){$IFDEF CheckPasTreeRefCount},'TBinaryExpr.left'{$ENDIF});
El:=SubBin;
until El=Self;
inherited Destroy;
end;

View File

@ -1711,6 +1711,8 @@ var
Decl: TPasElement;
ModScope: TPasModuleScope;
Access: TResolvedRefAccess;
Bin: TBinaryExpr;
Left: TPasExpr;
begin
if El=nil then exit;
// Note: expression itself is not marked, but it can reference identifiers
@ -1792,8 +1794,29 @@ begin
// ok
else if C=TBinaryExpr then
begin
UseExpr(TBinaryExpr(El).left);
UseExpr(TBinaryExpr(El).right);
Bin:=TBinaryExpr(El);
if Bin.OpCode=eopAdd then
begin
// handle multi add expressions without stack
Left:=Bin;
while Left.ClassType=TBinaryExpr do
begin
Bin:=TBinaryExpr(Left);
if Bin.OpCode<>eopAdd then break;
Left:=Bin.left;
end;
UseExpr(Left);
repeat
Bin:=TBinaryExpr(Left.Parent);
UseExpr(Bin.right);
Left:=Bin;
until Left=El;
end
else
begin
UseExpr(Bin.left);
UseExpr(Bin.right);
end;
end
else if C=TUnaryExpr then
UseExpr(TUnaryExpr(El).Operand)