瀏覽代碼

* Properly set location of float return value if it is passed as var parameter (it is always happens for safecall functions). It fixes bugs #8523 and #8977.
+ test.

git-svn-id: trunk@7728 -

yury 18 年之前
父節點
當前提交
3b7e458f02

+ 1 - 0
.gitattributes

@@ -8298,6 +8298,7 @@ tests/webtbs/tw8935.pp svneol=native#text/plain
 tests/webtbs/tw8950.pp svneol=native#text/plain
 tests/webtbs/tw8975.pp svneol=native#text/plain
 tests/webtbs/tw8975a.pp svneol=native#text/plain
+tests/webtbs/tw8977.pp svneol=native#text/plain
 tests/webtbs/tw9054.pp svneol=native#text/plain
 tests/webtbs/tw9076.pp svneol=native#text/plain
 tests/webtbs/tw9076a.pp svneol=native#text/plain

+ 10 - 8
compiler/arm/cpupara.pas

@@ -435,7 +435,13 @@ unit cpupara;
             location_reset(p.funcretloc[side],LOC_VOID,OS_NO);
             exit;
           end;
-
+        { Return is passed as var parameter }
+        if ret_in_param(p.returndef,p.proccalloption) then
+          begin
+            p.funcretloc[side].loc:=LOC_REFERENCE;
+            p.funcretloc[side].size:=retcgsize;
+            exit;
+          end;
         { Return in FPU register? }
         if p.returndef.typ=floatdef then
           begin
@@ -468,8 +474,8 @@ unit cpupara;
                 p.funcretloc[side].register:=NR_FPU_RESULT_REG;
               end;
           end
-          { Return in register? }
-        else if not ret_in_param(p.returndef,p.proccalloption) then
+          { Return in register }
+        else
           begin
             if retcgsize in [OS_64,OS_S64] then
               begin
@@ -483,11 +489,7 @@ unit cpupara;
                 p.funcretloc[side].loc:=LOC_REGISTER;
                 p.funcretloc[side].register:=NR_FUNCTION_RETURN_REG;
               end;
-          end
-        else
-          begin
-            p.funcretloc[side].loc:=LOC_REFERENCE;
-            p.funcretloc[side].size:=retcgsize;
+
           end;
      end;
 

+ 8 - 7
compiler/i386/cpupara.pas

@@ -328,6 +328,13 @@ unit cpupara;
             location_reset(p.funcretloc[side],LOC_VOID,OS_NO);
             exit;
           end;
+        { Return is passed as var parameter }
+        if ret_in_param(p.returndef,p.proccalloption) then
+          begin
+            p.funcretloc[side].loc:=LOC_REFERENCE;
+            p.funcretloc[side].size:=retcgsize;
+            exit;
+          end;
         { Return in FPU register? }
         if p.returndef.typ=floatdef then
           begin
@@ -336,8 +343,7 @@ unit cpupara;
             p.funcretloc[side].size:=retcgsize;
           end
         else
-         { Return in register? }
-         if not ret_in_param(p.returndef,p.proccalloption) then
+         { Return in register }
           begin
             if retcgsize in [OS_64,OS_S64] then
              begin
@@ -363,11 +369,6 @@ unit cpupara;
                else
                  p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
              end;
-          end
-        else
-          begin
-            p.funcretloc[side].loc:=LOC_REFERENCE;
-            p.funcretloc[side].size:=retcgsize;
           end;
       end;
 

+ 8 - 7
compiler/m68k/cpupara.pas

@@ -210,6 +210,13 @@ unit cpupara;
             location_reset(p.funcretloc[side],LOC_VOID,OS_NO);
             exit;
           end;
+        { Return is passed as var parameter }
+        if ret_in_param(p.returndef,p.proccalloption) then
+          begin
+            p.funcretloc[side].loc:=LOC_REFERENCE;
+            p.funcretloc[side].size:=retcgsize;
+            exit;
+          end;
         { Return in FPU register? }
         if not(cs_fp_emulation in current_settings.moduleswitches) and (p.returndef.typ=floatdef) then
           begin
@@ -218,8 +225,7 @@ unit cpupara;
             p.funcretloc[side].size:=retcgsize;
           end
         else
-         { Return in register? }
-         if not ret_in_param(p.returndef,p.proccalloption) then
+         { Return in register }
           begin
             if retcgsize in [OS_64,OS_S64] then
              begin
@@ -245,11 +251,6 @@ unit cpupara;
                else
                  p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
              end;
-          end
-        else
-          begin
-            p.funcretloc[side].loc:=LOC_REFERENCE;
-            p.funcretloc[side].size:=retcgsize;
           end;
       end;
 

+ 8 - 8
compiler/powerpc/cpupara.pas

@@ -246,7 +246,13 @@ unit cpupara;
             p.funcretloc[side].loc:=LOC_VOID;
             exit;
           end;
-
+        { Return is passed as var parameter }
+        if ret_in_param(p.returndef,p.proccalloption) then
+          begin
+            p.funcretloc[side].loc:=LOC_REFERENCE;
+            p.funcretloc[side].size:=retcgsize;
+            exit;
+          end;
         { Return in FPU register? }
         if p.returndef.typ=floatdef then
           begin
@@ -255,8 +261,7 @@ unit cpupara;
             p.funcretloc[side].size:=retcgsize;
           end
         else
-         { Return in register? }
-         if not ret_in_param(p.returndef,p.proccalloption) then
+         { Return in register }
           begin
 {$ifndef cpu64bit}
             if retcgsize in [OS_64,OS_S64] then
@@ -283,11 +288,6 @@ unit cpupara;
                else
                  p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
              end;
-          end
-        else
-          begin
-            p.funcretloc[side].loc:=LOC_REFERENCE;
-            p.funcretloc[side].size:=retcgsize;
           end;
       end;
 

+ 9 - 6
compiler/powerpc64/cpupara.pas

@@ -225,15 +225,21 @@ begin
     p.funcretloc[side].loc := LOC_VOID;
     exit;
   end;
-
+  { Return is passed as var parameter }
+  if ret_in_param(p.returndef, p.proccalloption) then
+    begin
+      p.funcretloc[side].loc := LOC_REFERENCE;
+      p.funcretloc[side].size := retcgsize;
+      exit;
+    end;
   { Return in FPU register? }
   if p.returndef.typ = floatdef then begin
     p.funcretloc[side].loc := LOC_FPUREGISTER;
     p.funcretloc[side].register := NR_FPU_RESULT_REG;
     p.funcretloc[side].size := retcgsize;
   end else
-    { Return in register? } 
-    if not ret_in_param(p.returndef, p.proccalloption) then begin
+    { Return in register }
+    begin
       p.funcretloc[side].loc := LOC_REGISTER;
       p.funcretloc[side].size := retcgsize;
       if side = callerside then
@@ -242,9 +248,6 @@ begin
       else
         p.funcretloc[side].register := newreg(R_INTREGISTER,
           RS_FUNCTION_RETURN_REG, cgsize2subreg(retcgsize));
-    end else begin
-      p.funcretloc[side].loc := LOC_REFERENCE;
-      p.funcretloc[side].size := retcgsize;
     end;
 end;
 

+ 8 - 8
compiler/sparc/cpupara.pas

@@ -156,7 +156,13 @@ implementation
             p.funcretloc[side].loc:=LOC_VOID;
             exit;
           end;
-
+        { Return is passed as var parameter }
+        if ret_in_param(p.returndef,p.proccalloption) then
+          begin
+            p.funcretloc[side].loc:=LOC_REFERENCE;
+            p.funcretloc[side].size:=retcgsize;
+            exit;
+          end;
         { Return in FPU register? }
         if p.returndef.typ=floatdef then
           begin
@@ -167,8 +173,7 @@ implementation
             p.funcretloc[side].size:=retcgsize;
           end
         else
-         { Return in register? }
-         if not ret_in_param(p.returndef,p.proccalloption) then
+         { Return in register }
           begin
 {$ifndef cpu64bit}
             if retcgsize in [OS_64,OS_S64] then
@@ -195,11 +200,6 @@ implementation
                else
                  p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
              end;
-          end
-        else
-          begin
-            p.funcretloc[side].loc:=LOC_REFERENCE;
-            p.funcretloc[side].size:=retcgsize;
           end;
       end;
 

+ 8 - 7
compiler/x86_64/cpupara.pas

@@ -335,6 +335,13 @@ unit cpupara;
             location_reset(p.funcretloc[side],LOC_VOID,OS_NO);
             exit;
           end;
+        { Return is passed as var parameter }
+        if ret_in_param(p.returndef,p.proccalloption) then
+          begin
+            p.funcretloc[side].loc:=LOC_REFERENCE;
+            p.funcretloc[side].size:=retcgsize;
+            exit;
+          end;
         { Return in FPU register? }
         if p.returndef.typ=floatdef then
           begin
@@ -358,8 +365,7 @@ unit cpupara;
             end;
           end
         else
-         { Return in register? }
-         if not ret_in_param(p.returndef,p.proccalloption) then
+         { Return in register }
           begin
             p.funcretloc[side].loc:=LOC_REGISTER;
             p.funcretloc[side].size:=retcgsize;
@@ -367,11 +373,6 @@ unit cpupara;
               p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
             else
               p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
-          end
-        else
-          begin
-            p.funcretloc[side].loc:=LOC_REFERENCE;
-            p.funcretloc[side].size:=retcgsize;
           end;
       end;
 

+ 8 - 0
tests/webtbs/tw8977.pp

@@ -0,0 +1,8 @@
+function DoTest: double; safecall;
+begin
+  DoTest:=1.0;
+end;
+
+begin
+  writeln(DoTest);
+end.