summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2018-01-16 06:22:17 +0000
committerZefram <zefram@fysh.org>2018-01-16 06:22:17 +0000
commit6661956a23de82b41adc406200054293d6d7aded (patch)
treedfdbb337bf5531eb9b0d1c9e4b8fd8bd2c647e03 /pp_hot.c
parenta97021b9d2cff6f0f8cbe5a5dd51187c5bad275e (diff)
downloadperl-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.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 8a74f58cb8..d479ecf218 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -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;