Browse Source

* store array results returned in registers on x86_64-win64 in a memory location if needed, resolves #14388

git-svn-id: trunk@14736 -
florian 15 years ago
parent
commit
988b94e578
3 changed files with 32 additions and 1 deletions
  1. 1 0
      .gitattributes
  2. 9 1
      compiler/ncgmem.pas
  3. 22 0
      tests/webtbs/tw14388.pp

+ 1 - 0
.gitattributes

@@ -10172,6 +10172,7 @@ tests/webtbs/tw1430.pp svneol=native#text/plain
 tests/webtbs/tw14307.pp svneol=native#text/plain
 tests/webtbs/tw1433.pp svneol=native#text/plain
 tests/webtbs/tw14363.pp svneol=native#text/plain
+tests/webtbs/tw14388.pp svneol=native#text/pascal
 tests/webtbs/tw14403.pp svneol=native#text/plain
 tests/webtbs/tw14418.pp svneol=native#text/plain
 tests/webtbs/tw1445.pp svneol=native#text/plain

+ 9 - 1
compiler/ncgmem.pas

@@ -196,7 +196,15 @@ implementation
          location_reset(location,LOC_REGISTER,OS_ADDR);
          location.register:=cg.getaddressregister(current_asmdata.CurrAsmList);
          if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-           internalerror(2006111510);
+           { on x86_64-win64, array of chars can be returned in registers, however,
+             when passing these arrays to other functions, the compiler wants to take
+             the address of the array so when the addrnode has been created internally,
+             we have to force the data into memory, see also tw14388.pp
+           }
+           if nf_internal in flags then
+             location_force_mem(current_asmdata.CurrAsmList,left.location)
+           else
+             internalerror(2006111510);
          cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,location.register);
       end;
 

+ 22 - 0
tests/webtbs/tw14388.pp

@@ -0,0 +1,22 @@
+program Project1;
+
+{$mode objfpc}{$H+}
+
+type
+  TID4 = array[0..3] of char;
+
+function GetID: TID4;
+begin
+  result:=#1#3#5#9;
+end;
+
+
+var
+  ChunkID: TID4;
+begin
+  ChunkID:=#1#3#5#9;
+  if GetID=ChunkID then
+    writeln('ok')
+  else
+    halt(1);
+end.