Browse Source

fcl-passrc: process TBinaryExpr left lists without stack

git-svn-id: trunk@49030 -
(cherry picked from commit 3c18b7e3b6bca2bb59e9514d251b6b9ccbbe4e18)
Mattias Gaertner 4 years ago
parent
commit
708de2786f

+ 1 - 1
packages/fcl-passrc/src/pasresolveeval.pas

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

+ 26 - 3
packages/fcl-passrc/src/pastree.pp

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

+ 25 - 2
packages/fcl-passrc/src/pasuseanalyzer.pas

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