diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-07-10 15:09:51 -0400 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-07-26 10:16:55 +0200 |
commit | 0fe688f528b0e1b5bef6fb30d5e45316430e8a41 (patch) | |
tree | a38f5eb47badce81268c3c57df36562d8ac90c91 /pp_hot.c | |
parent | 1eb3f3ad74c5c8cb35d027485b9938eb0a64db40 (diff) | |
download | perl-0fe688f528b0e1b5bef6fb30d5e45316430e8a41.tar.gz |
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.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 8 |
1 files changed, 8 insertions, 0 deletions
@@ -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; } |