On 22 Jan 2008, at 20:28, Peter Vreman wrote:
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).
It is nevertheless unsafe. The called routine has a const ansistring
parameter. The refcount for such parameters is not increased. So when
the result (= parameter) is overwritten, things will go wrong if
a) the refcount was 1
b) the memory location of the old string is reused
Jonas
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel