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

Reply via email to