summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scope.c5
-rw-r--r--t/op/svleak.t8
2 files changed, 10 insertions, 3 deletions
diff --git a/scope.c b/scope.c
index 8b82381ec8..75b2835ec5 100644
--- a/scope.c
+++ b/scope.c
@@ -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');