diff options
-rw-r--r-- | scope.c | 5 | ||||
-rw-r--r-- | t/op/svleak.t | 8 |
2 files changed, 10 insertions, 3 deletions
@@ -627,9 +627,10 @@ Perl_save_aelem_flags(pTHX_ AV *av, I32 idx, SV **sptr, const U32 flags) SvGETMAGIC(*sptr); save_pushptri32ptr(SvREFCNT_inc_simple(av), idx, SvREFCNT_inc(*sptr), SAVEt_AELEM); - /* if it gets reified later, the restore will have the wrong refcnt */ + /* The array needs to hold a reference count on its new element, so it + must be AvREAL. */ if (!AvREAL(av) && AvREIFY(av)) - SvREFCNT_inc_void(*sptr); + av_reify(av); save_scalar_at(sptr, flags); /* XXX - FIXME - see #60360 */ if (flags & SAVEf_KEEPOLDELEM) return; diff --git a/t/op/svleak.t b/t/op/svleak.t index d38c92d11f..7b530925fa 100644 --- a/t/op/svleak.t +++ b/t/op/svleak.t @@ -15,7 +15,7 @@ BEGIN { use Config; -plan tests => 69; +plan tests => 71; # run some code N times. If the number of SVs at the end of loop N is # greater than (N-1)*delta at the end of loop 1, we've got a leak @@ -197,6 +197,12 @@ eleak(2, 0, 'no warnings; sub {1 1}', 'anon sub with syntax error'); eleak(2, 0, 'no warnings; use feature ":all"; my sub a{1 1}', 'my sub with syntax error'); +# Reification (or lack thereof) +leak(2, 0, sub { sub { local $_[0]; shift }->(1) }, + 'local $_[0] on surreal @_, followed by shift'); +leak(2, 0, sub { sub { local $_[0]; \@_ }->(1) }, + 'local $_[0] on surreal @_, followed by reification'); + # Syntax errors eleak(2, 0, '"${<<END}" ', 'unterminated here-doc in quotes in multiline eval'); |