RT 8857: premature free in local of tied element
authorDavid Mitchell <davem@iabyn.com>
Sun, 11 Apr 2010 14:52:43 +0000 (15:52 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sun, 11 Apr 2010 15:15:31 +0000 (16:15 +0100)
commit459defa14829d1e98582a2fcd871ef3425e1fe38
tree8a5ea764cabff130a96e8baf4576ca186c975e45
parentd97c33b505dd45c052a8bf42014917701b4502a5
RT 8857: premature free in local of tied element

[The original bug report concerned local($_) remained tied, but while
looking at it, Nicholas found some related code that popped up premature
free errors. This commit fixes the freeing issue rather than the issue of
the original bug report ]

Background:

    local $a[0]

does, approximately:

    svp = av_fetch(av);
    SAVE(av,*svp);
    sv = newSV();
    *svp = sv;

This used to leak when av was tied, as the new sv only got embedded in
*svp, which for tied arrays is a temporary placeholder rather than
somewhere within AvARRAY. This leak was fixed in 2002 by adding the
following:

    if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
sv_2mortal(sv);

which worked, except for the following:

    sub f { local $_[0] }
    f($_) for ($tied[0]);

Here, @_ is a real array not a tied one, yet its first element is a
PERL_MAGIC_tiedelem which trigged the test above. So the sv got
mortalised *and* stored in the array, so got freed twice. The fix is
to test the *array/hash* for tied-ness rather than the element.
scope.c
t/op/svleak.t
t/op/tie.t