* 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 -
This commit is contained in:
Jonas Maebe 2016-09-07 19:37:35 +00:00
parent 997a958f72
commit 5ffd06392d
3 changed files with 40 additions and 1 deletions

1
.gitattributes vendored
View File

@ -15213,6 +15213,7 @@ tests/webtbs/tw30443.pp svneol=native#text/plain
tests/webtbs/tw3045.pp svneol=native#text/plain
tests/webtbs/tw3048.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/tw3064.pp svneol=native#text/plain
tests/webtbs/tw3073.pp svneol=native#text/plain

View File

@ -2892,6 +2892,17 @@ implementation
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;
var
realassignmenttarget: tnode;
@ -2946,7 +2957,7 @@ implementation
not(ti_addr_taken in ttemprefnode(realassignmenttarget).tempflags) and
not(ti_may_be_in_reg in ttemprefnode(realassignmenttarget).tempflags) then
begin
result:=true;
result:=not foreachnodestatic(left,@check_funcret_temp_used_as_para,ttemprefnode(realassignmenttarget).tempinfo);
exit;
end;

27
tests/webtbs/tw30572.pp Normal file
View File

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