diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-06-22 18:46:00 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-07-25 23:48:00 -0700 |
commit | 5608dcc62313f26a4bf696abe8e5fe687335a7e1 (patch) | |
tree | 1bfc56fdb4eedf0783ebe0f59a699c4b8a6ba4eb /op.c | |
parent | 2ca971d50b815fd6da6adac5c6691ac438237e05 (diff) | |
download | perl-5608dcc62313f26a4bf696abe8e5fe687335a7e1.tar.gz |
[perl #3105] Make 1..3 modification safe
This construct is optimised at compile time to an anonymous array with
an implicit @{} around it if both arguments are constant. Modifying
elements of that array produces wrong results the next time the same
code is executed.
If we mark each element of the array as PADTMP, then it will be
treated like an operator’s return value (which it is) and get copied
as appropriate.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 8 |
1 files changed, 7 insertions, 1 deletions
@@ -3353,6 +3353,8 @@ S_gen_constant_list(pTHX_ OP *o) dVAR; OP *curop; const I32 oldtmps_floor = PL_tmps_floor; + SV **svp; + AV *av; list(o); if (PL_parser && PL_parser->error_count) @@ -3375,7 +3377,11 @@ S_gen_constant_list(pTHX_ OP *o) o->op_flags |= OPf_PARENS; /* and flatten \(1..2,3) */ o->op_opt = 0; /* needs to be revisited in rpeep() */ curop = ((UNOP*)o)->op_first; - ((UNOP*)o)->op_first = newSVOP(OP_CONST, 0, SvREFCNT_inc_NN(*PL_stack_sp--)); + av = (AV *)SvREFCNT_inc_NN(*PL_stack_sp--); + ((UNOP*)o)->op_first = newSVOP(OP_CONST, 0, (SV *)av); + if (AvFILLp(av) != -1) + for (svp = AvARRAY(av) + AvFILLp(av); svp >= AvARRAY(av); --svp) + SvPADTMP_on(*svp); #ifdef PERL_MAD op_getmad(curop,o,'O'); #else |