Browse Source

* ensure that load nodes only substitute temps in case both references point
to the start of their respective temps

git-svn-id: trunk@38859 -

Jonas Maebe 7 years ago
parent
commit
52e7678033
2 changed files with 28 additions and 2 deletions
  1. 2 2
      compiler/ncgld.pas
  2. 26 0
      compiler/tgobj.pas

+ 2 - 2
compiler/ncgld.pas

@@ -180,11 +180,11 @@ implementation
            { still used later on in initialisation/finalisation code }
            { still used later on in initialisation/finalisation code }
            is_managed_type(n.resultdef) or
            is_managed_type(n.resultdef) or
            { source and destination are temps (= not global variables) }
            { source and destination are temps (= not global variables) }
-           not tg.istemp(n.location.reference) or
-           not tg.istemp(newref) or
            { and both point to the start of a temp, and the source is a }
            { and both point to the start of a temp, and the source is a }
            { non-persistent temp (otherwise we need some kind of copy-  }
            { non-persistent temp (otherwise we need some kind of copy-  }
            { on-write support in case later on both are still used)     }
            { on-write support in case later on both are still used)     }
+           not tg.isstartoftemp(newref) or
+           not tg.isstartoftemp(n.location.reference) or
            (tg.gettypeoftemp(newref) <> tt_normal) or
            (tg.gettypeoftemp(newref) <> tt_normal) or
            not (tg.gettypeoftemp(n.location.reference) in [tt_normal,tt_persistent]) or
            not (tg.gettypeoftemp(n.location.reference) in [tt_normal,tt_persistent]) or
            { and both have the same size }
            { and both have the same size }

+ 26 - 0
compiler/tgobj.pas

@@ -103,6 +103,7 @@ unit tgobj;
           function sizeoftemp(list: TAsmList; const ref: treference): asizeint;
           function sizeoftemp(list: TAsmList; const ref: treference): asizeint;
           function changetemptype(list: TAsmList; const ref:treference;temptype:ttemptype):boolean;
           function changetemptype(list: TAsmList; const ref:treference;temptype:ttemptype):boolean;
           function gettypeoftemp(const ref:treference): ttemptype;
           function gettypeoftemp(const ref:treference): ttemptype;
+          function isstartoftemp(const ref: treference): boolean;
           {# Returns a reference corresponding to a temp }
           {# Returns a reference corresponding to a temp }
           procedure temp_to_ref(p: ptemprecord; out ref: treference); virtual;
           procedure temp_to_ref(p: ptemprecord; out ref: treference); virtual;
 
 
@@ -662,6 +663,31 @@ implementation
       end;
       end;
 
 
 
 
+    function ttgobj.isstartoftemp(const ref: treference): boolean;
+      var
+        hp: ptemprecord;
+        tmpref: treference;
+      begin
+        hp:=templist;
+        if ref.temppos.val=ctempposinvalid.val then
+          begin
+            result:=false;
+            exit;
+          end;
+        while assigned(hp) do
+         begin
+           if (hp^.pos=ref.temppos.val) then
+            begin
+              temp_to_ref(hp, tmpref);
+              result:=references_equal(ref, tmpref);
+              exit;
+            end;
+           hp:=hp^.next;
+         end;
+        internalerror(2018042601);
+      end;
+
+
     procedure ttgobj.temp_to_ref(p: ptemprecord; out ref: treference);
     procedure ttgobj.temp_to_ref(p: ptemprecord; out ref: treference);
       var
       var
         t: treftemppos;
         t: treftemppos;