[fpc-devel] One more issue with string function results (hopefully, the last)
Peter Vreman
peter at freepascal.org
Tue Jan 22 20:28:55 CET 2008
>> 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).
More information about the fpc-devel
mailing list