This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [PATCH scope.c] Re: local($tied->{foo}) leaks
[perl5.git] / scope.c
diff --git a/scope.c b/scope.c
index 85a0680..a1fdfd1 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -587,23 +587,39 @@ Perl_save_destructor_x(pTHX_ DESTRUCTORFUNC_t f, void* p)
 void
 Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr)
 {
+    SV *sv;
     SSCHECK(4);
     SSPUSHPTR(SvREFCNT_inc(av));
     SSPUSHINT(idx);
     SSPUSHPTR(SvREFCNT_inc(*sptr));
     SSPUSHINT(SAVEt_AELEM);
     save_scalar_at(sptr);
+    sv = *sptr;
+    /* If we're localizing a tied array element, this new sv
+     * won't actually be stored in the array - so it won't get
+     * reaped when the localize ends. Ensure it gets reaped by
+     * mortifying it instead. DAPM */
+    if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
+       sv_2mortal(sv);
 }
 
 void
 Perl_save_helem(pTHX_ HV *hv, SV *key, SV **sptr)
 {
+    SV *sv;
     SSCHECK(4);
     SSPUSHPTR(SvREFCNT_inc(hv));
     SSPUSHPTR(SvREFCNT_inc(key));
     SSPUSHPTR(SvREFCNT_inc(*sptr));
     SSPUSHINT(SAVEt_HELEM);
     save_scalar_at(sptr);
+    sv = *sptr;
+    /* If we're localizing a tied hash element, this new sv
+     * won't actually be stored in the hash - so it won't get
+     * reaped when the localize ends. Ensure it gets reaped by
+     * mortifying it instead. DAPM */
+    if (SvTIED_mg(sv, PERL_MAGIC_tiedelem))
+       sv_2mortal(sv);
 }
 
 void