summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pod/perldelta.pod8
-rw-r--r--pp_ctl.c2
-rw-r--r--t/op/gmagic.t15
3 files changed, 24 insertions, 1 deletions
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 944a7b874d..2b98f60e06 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -372,6 +372,14 @@ a tied operand when doing a symbolic dereference (looking up a variable by
name, which is not permitted under C<use strict 'refs'>). Only C<&{}> did
not have this problem. This has been fixed.
+=item *
+
+A minor regression introduced in 5.15.0 has been fixed. Dereferencing a
+magical mortal (e.g., the return value of C<delete> on a tied hash element)
+explicitly returned from a subroutine called recursively was not calling
+C<FETCH>. This would affect code like C<@{ foo() }> where the C<foo> sub
+contains C<return delete $hash{elem}> and is calling itself.
+
=back
=head1 Known Problems
diff --git a/pp_ctl.c b/pp_ctl.c
index 533ff5f33a..7f4371f701 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2499,13 +2499,13 @@ PP(pp_return)
*++newsp = SvREFCNT_inc(*SP);
FREETMPS;
sv_2mortal(*newsp);
+ if (gmagic) SvGETMAGIC(*newsp);
}
else {
sv = SvREFCNT_inc(*SP); /* FREETMPS could clobber it */
FREETMPS;
*++newsp = sv_mortalcopy(sv);
SvREFCNT_dec(sv);
- if (gmagic) SvGETMAGIC(sv);
}
}
else if (SvTEMP(*SP) && SvREFCNT(*SP) == 1) {
diff --git a/t/op/gmagic.t b/t/op/gmagic.t
index 2ec1f1126c..64e7a2aebb 100644
--- a/t/op/gmagic.t
+++ b/t/op/gmagic.t
@@ -81,6 +81,21 @@ ok($wgot == 0, 'a plain *foo causes no set-magic');
() = sub { return delete $_{elem} }->()->[3];
expected_tie_calls $tied_to, 1, 0,
'mortal magic var is explicitly returned in autoviv context';
+
+ $tied_to = tie $_{elem}, "Tie::Monitor";
+ my $rsub;
+ $rsub = sub { if ($_[0]) { delete $_{elem} } else { &$rsub(1)->[3] } };
+ &$rsub;
+ expected_tie_calls $tied_to, 1, 0,
+ 'mortal magic var is implicitly returned in autoviv context';
+
+ $tied_to = tie $_{elem}, "Tie::Monitor";
+ $rsub = sub {
+ if ($_[0]) { return delete $_{elem} } else { &$rsub(1)->[3] }
+ };
+ &$rsub;
+ expected_tie_calls $tied_to, 1, 0,
+ 'mortal magic var is explicitly returned in autoviv context';
}
done_testing();