summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-12-18 13:34:44 -0800
committerFather Chrysostomos <sprout@cpan.org>2011-12-18 13:34:44 -0800
commitb73e53856fd974960547b6620ff23e22cf981f7b (patch)
tree6642beb5bba45fb5f4cea6861773dee8fd109f69
parent5dd80d85de04555d63d02b50785d3c62029a9375 (diff)
downloadperl-b73e53856fd974960547b6620ff23e22cf981f7b.tar.gz
Stop readline(*$glob_copy) from clearing PL_last_in_gv
This is related to commit 8dc99089, which fixed a similar bug in tell. In readline(*$glob_copy), the * makes a mortal copy of $glob_copy, turning off its fake flag. readline sets PL_last_in_gv to its argu- ment, but it gets freed at the end of the statement and PL_last_in_gv gets cleared.
-rw-r--r--op.c6
-rw-r--r--t/op/readline.t4
2 files changed, 8 insertions, 2 deletions
diff --git a/op.c b/op.c
index 146c3683e3..46b0522f94 100644
--- a/op.c
+++ b/op.c
@@ -8285,7 +8285,11 @@ Perl_ck_readline(pTHX_ OP *o)
{
PERL_ARGS_ASSERT_CK_READLINE;
- if (!(o->op_flags & OPf_KIDS)) {
+ if (o->op_flags & OPf_KIDS) {
+ OP *kid = cLISTOPo->op_first;
+ if (kid->op_type == OP_RV2GV) kid->op_private |= OPpALLOW_FAKE;
+ }
+ else {
OP * const newop
= newUNOP(OP_READLINE, 0, newGVOP(OP_GV, 0, PL_argvgv));
#ifdef PERL_MAD
diff --git a/t/op/readline.t b/t/op/readline.t
index fa0c4f7e4b..944cd7ab46 100644
--- a/t/op/readline.t
+++ b/t/op/readline.t
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}
-plan tests => 29;
+plan tests => 30;
# [perl #19566]: sv_gets writes directly to its argument via
# TARG. Test that we respect SvREADONLY.
@@ -266,6 +266,8 @@ $f{g} = 3; # PL_last_in_gv should be cleared now
is tell, -1, 'tell returns -1 after last gv is unglobbed';
$f{g} = *foom; # since PL_last_in_gv is null, this should have no effect
is tell, -1, 'unglobbery of last gv nullifies PL_last_in_gv';
+readline *{$f{g}};
+is tell, tell *foom, 'readline *$glob_copy sets PL_last_in_gv';
__DATA__
moo