Browse Source

* never create a regular temp for inline parameters that can be modified by
the caller (mantis #37465)a
o in theory, the regular checks for doing so should never trigger, but due
to compiler-generated nodes (such as calls to fpc_ansistr_unique), they
could. Internal address nodes can deal with taking the address of the
function result in this case.

git-svn-id: trunk@46660 -

Jonas Maebe 5 years ago
parent
commit
d1d3d7cd08
3 changed files with 22 additions and 0 deletions
  1. 1 0
      .gitattributes
  2. 5 0
      compiler/ncal.pas
  3. 16 0
      tests/webtbs/tw37465.pp

+ 1 - 0
.gitattributes

@@ -18426,6 +18426,7 @@ tests/webtbs/tw37423.pp svneol=native#text/plain
 tests/webtbs/tw37427.pp svneol=native#text/pascal
 tests/webtbs/tw37428.pp svneol=native#text/pascal
 tests/webtbs/tw37449.pp svneol=native#text/pascal
+tests/webtbs/tw37465.pp svneol=native#text/plain
 tests/webtbs/tw37468.pp svneol=native#text/pascal
 tests/webtbs/tw37477.pp svneol=native#text/pascal
 tests/webtbs/tw37493.pp svneol=native#text/pascal

+ 5 - 0
compiler/ncal.pas

@@ -4742,6 +4742,11 @@ implementation
 
     function tcallnode.paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean;
       begin
+        { if it's an assignable call-by-reference parameter, we cannot pass a
+          temp since then the modified valua will be lost }
+        if para.parasym.varspez in [vs_var,vs_out] then
+          exit(false);
+
         { We don't need temps for parameters that are already temps, except if
           the passed temp could be put in a regvar while the parameter inside
           the routine cannot be (e.g., because its address is taken in the

+ 16 - 0
tests/webtbs/tw37465.pp

@@ -0,0 +1,16 @@
+program example;
+
+{$mode objfpc}{$H+}
+
+procedure foo(out c: char); inline;
+begin
+  c := #32;
+end;
+
+var s: String;
+
+begin
+  s:=#42;
+  foo(s[1]);
+  Writeln(ord(s[1]));
+end.