diff options
author | Zefram <zefram@fysh.org> | 2018-01-16 06:22:17 +0000 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2018-01-16 06:22:17 +0000 |
commit | 6661956a23de82b41adc406200054293d6d7aded (patch) | |
tree | dfdbb337bf5531eb9b0d1c9e4b8fd8bd2c647e03 /pp_hot.c | |
parent | a97021b9d2cff6f0f8cbe5a5dd51187c5bad275e (diff) | |
download | perl-6661956a23de82b41adc406200054293d6d7aded.tar.gz |
vivify array elements when putting them on stack
When the elements of an array are put on the stack, by a padav, rv2av,
or padrange op, null pointers in the AvARRAY were being pushed as
&PL_sv_undef, which was OK in rvalue contexts but caused misbehaviour
in lvalue contexts. Change this to vivify these elements. There's no
attempt here to limit the vivification to lvalue contexts: the existing
op flags aren't enough to detect \(@a), and attempting to catch all
cases where a new flag needs to be set would be an error-prone process.
Fixes [perl #8910].
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 8 |
1 files changed, 5 insertions, 3 deletions
@@ -1163,15 +1163,17 @@ S_pushav(pTHX_ AV* const av) if (UNLIKELY(SvRMAGICAL(av))) { PADOFFSET i; for (i=0; i < (PADOFFSET)maxarg; i++) { - SV ** const svp = av_fetch(av, i, FALSE); + SV ** const svp = av_fetch(av, i, TRUE); SP[i+1] = svp ? *svp : &PL_sv_undef; } } else { PADOFFSET i; for (i=0; i < (PADOFFSET)maxarg; i++) { - SV * const sv = AvARRAY(av)[i]; - SP[i+1] = LIKELY(sv) ? sv : &PL_sv_undef; + SV *sv = AvARRAY(av)[i]; + if (!LIKELY(sv)) + AvARRAY(av)[i] = sv = newSV(0); + SP[i+1] = sv; } } SP += maxarg; |