Browse Source

* don't optimize "x:=f(x)" whereby the function result of f() is passed
by reference in case x is a temp (mantis #30572)

git-svn-id: trunk@34445 -

Jonas Maebe 9 years ago
parent
commit
5ffd06392d
3 changed files with 40 additions and 1 deletions
  1. 1 0
      .gitattributes
  2. 12 1
      compiler/ncal.pas
  3. 27 0
      tests/webtbs/tw30572.pp

+ 1 - 0
.gitattributes

@@ -15213,6 +15213,7 @@ tests/webtbs/tw30443.pp svneol=native#text/plain
 tests/webtbs/tw3045.pp svneol=native#text/plain
 tests/webtbs/tw3045.pp svneol=native#text/plain
 tests/webtbs/tw3048.pp svneol=native#text/plain
 tests/webtbs/tw3048.pp svneol=native#text/plain
 tests/webtbs/tw30522.pp svneol=native#text/plain
 tests/webtbs/tw30522.pp svneol=native#text/plain
+tests/webtbs/tw30572.pp svneol=native#text/plain
 tests/webtbs/tw3063.pp svneol=native#text/plain
 tests/webtbs/tw3063.pp svneol=native#text/plain
 tests/webtbs/tw3064.pp svneol=native#text/plain
 tests/webtbs/tw3064.pp svneol=native#text/plain
 tests/webtbs/tw3073.pp svneol=native#text/plain
 tests/webtbs/tw3073.pp svneol=native#text/plain

+ 12 - 1
compiler/ncal.pas

@@ -2892,6 +2892,17 @@ implementation
       end;
       end;
 
 
 
 
+    function check_funcret_temp_used_as_para(var n: tnode; arg: pointer): foreachnoderesult;
+      var
+        tempinfo : ptempinfo absolute arg;
+      begin
+        result := fen_false;
+        if (n.nodetype=temprefn) and
+           (ttemprefnode(n).tempinfo = tempinfo) then
+          result := fen_norecurse_true;
+      end;
+
+
     function tcallnode.funcret_can_be_reused:boolean;
     function tcallnode.funcret_can_be_reused:boolean;
       var
       var
         realassignmenttarget: tnode;
         realassignmenttarget: tnode;
@@ -2946,7 +2957,7 @@ implementation
            not(ti_addr_taken in ttemprefnode(realassignmenttarget).tempflags) and
            not(ti_addr_taken in ttemprefnode(realassignmenttarget).tempflags) and
            not(ti_may_be_in_reg in ttemprefnode(realassignmenttarget).tempflags) then
            not(ti_may_be_in_reg in ttemprefnode(realassignmenttarget).tempflags) then
           begin
           begin
-            result:=true;
+            result:=not foreachnodestatic(left,@check_funcret_temp_used_as_para,ttemprefnode(realassignmenttarget).tempinfo);
             exit;
             exit;
           end;
           end;
 
 

+ 27 - 0
tests/webtbs/tw30572.pp

@@ -0,0 +1,27 @@
+{$mode objfpc}
+{$h+}
+{$inline on}
+
+var
+  s: String;
+
+  function TestWinCPToUTF8(const s: string): string;
+  begin
+    if pointer(s)=pointer(result) then
+      halt(1);
+    Result := s; // Result is now invalid
+    SetCodePage(RawByteString(Result), CP_ACP, False);
+  end;
+
+  function Test: string; inline;
+  var
+    s: String;
+  begin
+    s := 'test';
+    result:=s+'a';
+    Result := TestWinCPToUTF8(Result);
+  end;
+
+begin
+  s := Test;
+end.