>> Hello, >> >> Ran into it while compiling Lazarus. It appears that, while many >> sophisticated checks are done in tcallnode.maybe_create_funcret_node, >> the obvious case when function result destination is one of the >> function's arguments, is not checked. To be honest, I noticed that >> earlier for the case of s := Copy(s, ...), but was thiniking that there >> is some compiler magic around Copy(). Delphi also appears to be smart >> enough to omit temps in case of s := copy(s,...). >> Anyway, since copy() assigns its result once before exiting, it works >> fine. Things go wrong when the function is tries to access its argument >> after modifying the result, like in the attached example. > > This issue is caused by your own patch to change the ansistring code to use > pass the result by > reference. > > Original code (using current 2.2.1) was: > > # [21] s := foo(s); // This one failes > movl -4(%ebp),%eax > call P$PROGRAM_FOO$ANSISTRING$$ANSISTRING > movl %eax,%ebx > leal -4(%ebp),%eax > call FPC_ANSISTR_DECR_REF > movl %ebx,-4(%ebp) > > The new code since r9718 is: > > # [21] s := foo(s); // This one failes > leal -4(%ebp),%edx > movl -4(%ebp),%eax > call P$PROGRAM_FOO$ANSISTRING$$ANSISTRING > > > Here you can see that the result is at the same location as the parameter. In > the original code > the value is only assigned to the original location after the call. > > The quick-solution is simple: revert r9718 until it works.
The example that is provided doesn't fail. Because when calling foo the value of -4(%ebp) is loaded in %eax and that value is used in the function foo. The setlength() will create a new string and store that at -4(%ebp) of the calling function. But doesn't change the original parameter value in %eax (and also stored also at (%esp) in foo). _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel