This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Resurrect immortals before checking for SvTEMP()
authorDavid Mitchell <davem@iabyn.com>
Wed, 6 Dec 2023 20:46:09 +0000 (20:46 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Jan 2024 12:33:02 +0000 (12:33 +0000)
commit6ca3ba049e69f7b8d67362ce4fac7b812a47ee1f
tree217c9f8d59f71aabe06694ae41a6f26b84012628
parent48cac15890ee29400bff9bb1e0c940997f1505b1
Resurrect immortals before checking for SvTEMP()

sv_clear() and sv_free2() both do, in this order, (simplified):

    #ifdef DEBUGGING
        if (SvTEMP(sv))
            Perl_ck_warner_d(..., Attempt to free temp prematurely",...);
    #endif

    if (SvIMMORTAL(sv))
        SvREFCNT(sv) = SvREFCNT_IMMORTAL

Now, it so happens that under DEBUGGING PERL_RC_STACK builds,

a) immortals such s PL_sv_undef have their refcount set to only 10 to
deliberately trigger the edge case of them being freed more often;

b) PERL_RC_STACK builds increasingly don't bother to increment the
reference counts of immortals when pushing them on the stack - this
saves a bit of time, and just means that once every two billion times on
normal builds the ref count drops to zero and sv_clear() sets it back to
SvREFCNT_IMMORTAL.

The combination of these has suddenly made it much more likely that
an immortal on the stack which has also been mortalised, will be passed
to sv_clear() and thus spuriously output the warning message.

So this commit swaps the order of the checks.

In the SvIMMORTAL() branch, it now also turns off SvTEMP.
sv.c