In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/0fe688f528b0e1b5bef6fb30d5e45316430e8a41?hp=1eb3f3ad74c5c8cb35d027485b9938eb0a64db40>
- Log ----------------------------------------------------------------- commit 0fe688f528b0e1b5bef6fb30d5e45316430e8a41 Author: Father Chrysostomos <[email protected]> Date: Sat Jul 10 15:09:51 2010 -0400 Fix for RT#1804: Anonymous glob breaks when assigned through The problem here is that globs are scalars and the = operator can only distinguish between scalar and glob assignments by the flags on the glob. It only sees the return value of *{}, not the *{} itself. We can fix this by having the pp_sassign look for a rv2gv (*{}) on its LHS, to decide what type of assignment to do. ----------------------------------------------------------------------- Summary of changes: pp_hot.c | 8 ++++++++ t/op/gv.t | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletions(-) diff --git a/pp_hot.c b/pp_hot.c index d5a4572..bd0f909 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -112,6 +112,7 @@ PP(pp_and) PP(pp_sassign) { dVAR; dSP; dPOPTOPssrl; + U32 wasfake = 0; if (PL_op->op_private & OPpASSIGN_BACKWARDS) { SV * const temp = left; @@ -197,7 +198,14 @@ PP(pp_sassign) } } + /* Allow glob assignments like *$x = ..., which, when the glob has a + SVf_FAKE flag, cannot be distinguished from $x = ... without looking + at the op tree. */ + if( SvTYPE(right) == SVt_PVGV && cBINOP->op_last->op_type == OP_RV2GV + && (wasfake = SvFLAGS(right) & SVf_FAKE) ) + SvFLAGS(right) &= ~SVf_FAKE; SvSetMagicSV(right, left); + if(wasfake) SvFLAGS(right) |= SVf_FAKE; SETs(right); RETURN; } diff --git a/t/op/gv.t b/t/op/gv.t index f3511e3..13da980 100644 --- a/t/op/gv.t +++ b/t/op/gv.t @@ -12,7 +12,7 @@ BEGIN { use warnings; require './test.pl'; -plan( tests => 191 ); +plan( tests => 192 ); # type coersion on assignment $foo = 'foo'; @@ -623,6 +623,17 @@ is ($@, '', "Can localize FAKE glob that's present in stash"); is (scalar $::{fake}, "*main::sym", "Localized FAKE glob's value was correctly restored"); +# [perl #1804] *$x assignment when $x is a copy of another glob +{ + no warnings 'once'; + my $x = *_random::glob_that_is_not_used_elsewhere; + *$x = sub{}; + is( + "$x", '*_random::glob_that_is_not_used_elsewhere', + '[perl #1804] *$x assignment when $x is FAKE', + ); +} + __END__ Perl Rules -- Perl5 Master Repository
