summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--av.c59
-rw-r--r--dist/Storable/Storable.xs56
-rw-r--r--dist/Storable/t/malice.t8
-rw-r--r--ext/B/t/showlex.t2
-rw-r--r--ext/Devel-Peek/Peek.xs1
-rw-r--r--ext/IPC-Open3/lib/IPC/Open3.pm4
-rw-r--r--pad.c30
-rw-r--r--pp.c4
-rw-r--r--pp_hot.c12
-rw-r--r--regexec.c2
10 files changed, 120 insertions, 58 deletions
diff --git a/av.c b/av.c
index b15f6ff7b6..aae70bf8ac 100644
--- a/av.c
+++ b/av.c
@@ -40,16 +40,15 @@ Perl_av_reify(pTHX_ AV *av)
#endif
key = AvMAX(av) + 1;
while (key > AvFILLp(av) + 1)
- AvARRAY(av)[--key] = &PL_sv_undef;
+ AvARRAY(av)[--key] = NULL;
while (key) {
SV * const sv = AvARRAY(av)[--key];
- assert(sv);
if (sv != &PL_sv_undef)
- SvREFCNT_inc_simple_void_NN(sv);
+ SvREFCNT_inc_simple_void(sv);
}
key = AvARRAY(av) - AvALLOC(av);
while (key)
- AvALLOC(av)[--key] = &PL_sv_undef;
+ AvALLOC(av)[--key] = NULL;
AvREIFY_off(av);
AvREAL_on(av);
}
@@ -105,7 +104,7 @@ Perl_av_extend_guts(pTHX_ AV *av, I32 key, SSize_t *maxp, SV ***allocp,
*arrayp = *allocp;
if (AvREAL(av)) {
while (tmp)
- ary[--tmp] = &PL_sv_undef;
+ ary[--tmp] = NULL;
}
if (key > *maxp - 10) {
newmax = key + *maxp;
@@ -126,7 +125,7 @@ Perl_av_extend_guts(pTHX_ AV *av, I32 key, SSize_t *maxp, SV ***allocp,
based on calling Perl_safesysmalloc_size() immediately after
allocation, I'm not convinced that it is a great idea here.
In an array we have to loop round setting everything to
- &PL_sv_undef, which means writing to memory, potentially lots
+ NULL, which means writing to memory, potentially lots
of it, whereas for the SV buffer case we don't touch the
"bonus" memory. So there there is no cost in telling the
world about it, whereas here we have to do work before we can
@@ -161,11 +160,11 @@ Perl_av_extend_guts(pTHX_ AV *av, I32 key, SSize_t *maxp, SV ***allocp,
Newx(*allocp, newmax+1, SV*);
ary = *allocp + 1;
tmp = newmax;
- *allocp[0] = &PL_sv_undef; /* For the stacks */
+ *allocp[0] = NULL; /* For the stacks */
}
if (av && AvREAL(av)) {
while (tmp)
- ary[--tmp] = &PL_sv_undef;
+ ary[--tmp] = NULL;
}
*arrayp = *allocp;
@@ -250,7 +249,7 @@ Perl_av_fetch(pTHX_ AV *av, I32 key, I32 lval)
return NULL;
}
- if (key > AvFILLp(av) || AvARRAY(av)[key] == &PL_sv_undef) {
+ if (key > AvFILLp(av) || !AvARRAY(av)[key]) {
emptyness:
return lval ? av_store(av,key,newSV(0)) : NULL;
}
@@ -258,7 +257,7 @@ Perl_av_fetch(pTHX_ AV *av, I32 key, I32 lval)
if (AvREIFY(av)
&& (!AvARRAY(av)[key] /* eg. @_ could have freed elts */
|| SvIS_FREED(AvARRAY(av)[key]))) {
- AvARRAY(av)[key] = &PL_sv_undef; /* 1/2 reify */
+ AvARRAY(av)[key] = NULL; /* 1/2 reify */
goto emptyness;
}
return &AvARRAY(av)[key];
@@ -299,9 +298,6 @@ Perl_av_store(pTHX_ AV *av, I32 key, SV *val)
(unicode_alternate may be NULL).
*/
- if (!val)
- val = &PL_sv_undef;
-
if (SvRMAGICAL(av)) {
const MAGIC * const tied_magic = mg_find((const SV *)av, PERL_MAGIC_tied);
if (tied_magic) {
@@ -309,7 +305,7 @@ Perl_av_store(pTHX_ AV *av, I32 key, SV *val)
if (!S_adjust_index(aTHX_ av, tied_magic, &key))
return 0;
}
- if (val != &PL_sv_undef) {
+ if (val) {
mg_copy(MUTABLE_SV(av), val, 0, key);
}
return NULL;
@@ -336,7 +332,7 @@ Perl_av_store(pTHX_ AV *av, I32 key, SV *val)
if (av == PL_curstack && key > PL_stack_sp - PL_stack_base)
PL_stack_sp = PL_stack_base + key; /* XPUSH in disguise */
do {
- ary[++AvFILLp(av)] = &PL_sv_undef;
+ ary[++AvFILLp(av)] = NULL;
} while (AvFILLp(av) < key);
}
AvFILLp(av) = key;
@@ -349,7 +345,7 @@ Perl_av_store(pTHX_ AV *av, I32 key, SV *val)
bool set = TRUE;
for (; mg; mg = mg->mg_moremagic) {
if (!isUPPER(mg->mg_type)) continue;
- if (val != &PL_sv_undef) {
+ if (val) {
sv_magic(val, MUTABLE_SV(av), toLOWER(mg->mg_type), 0, key);
}
if (PL_delaymagic && mg->mg_type == PERL_MAGIC_isa) {
@@ -465,7 +461,7 @@ Perl_av_clear(pTHX_ AV *av)
SV * const sv = ary[--index];
/* undef the slot before freeing the value, because a
* destructor might try to modify this array */
- ary[index] = &PL_sv_undef;
+ ary[index] = NULL;
SvREFCNT_dec(sv);
}
}
@@ -601,10 +597,10 @@ Perl_av_pop(pTHX_ AV *av)
if (AvFILL(av) < 0)
return &PL_sv_undef;
retval = AvARRAY(av)[AvFILLp(av)];
- AvARRAY(av)[AvFILLp(av)--] = &PL_sv_undef;
+ AvARRAY(av)[AvFILLp(av)--] = NULL;
if (SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
- return retval;
+ return retval ? retval : &PL_sv_undef;
}
/*
@@ -685,7 +681,7 @@ Perl_av_unshift(pTHX_ AV *av, I32 num)
ary = AvARRAY(av);
Move(ary, ary + num, i + 1, SV*);
do {
- ary[--num] = &PL_sv_undef;
+ ary[--num] = NULL;
} while (num);
/* Make extra elements into a buffer */
AvMAX(av) -= slide;
@@ -728,13 +724,13 @@ Perl_av_shift(pTHX_ AV *av)
return &PL_sv_undef;
retval = *AvARRAY(av);
if (AvREAL(av))
- *AvARRAY(av) = &PL_sv_undef;
+ *AvARRAY(av) = NULL;
AvARRAY(av) = AvARRAY(av) + 1;
AvMAX(av)--;
AvFILLp(av)--;
if (SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
- return retval;
+ return retval ? retval : &PL_sv_undef;
}
/*
@@ -772,7 +768,7 @@ Perl's C<$#array = $fill;>.
The number of elements in the an array will be C<fill + 1> after
av_fill() returns. If the array was previously shorter, then the
-additional elements appended are set to C<PL_sv_undef>. If the array
+additional elements appended are set to NULL. If the array
was longer, then the excess elements are freed. C<av_fill(av, -1)> is
the same as C<av_clear(av)>.
@@ -803,12 +799,12 @@ Perl_av_fill(pTHX_ AV *av, I32 fill)
if (AvREAL(av)) {
while (key > fill) {
SvREFCNT_dec(ary[key]);
- ary[key--] = &PL_sv_undef;
+ ary[key--] = NULL;
}
}
else {
while (key < fill)
- ary[++key] = &PL_sv_undef;
+ ary[++key] = NULL;
}
AvFILLp(av) = fill;
@@ -816,7 +812,7 @@ Perl_av_fill(pTHX_ AV *av, I32 fill)
mg_set(MUTABLE_SV(av));
}
else
- (void)av_store(av,fill,&PL_sv_undef);
+ (void)av_store(av,fill,NULL);
}
/*
@@ -877,13 +873,13 @@ Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
av_reify(av);
sv = AvARRAY(av)[key];
if (key == AvFILLp(av)) {
- AvARRAY(av)[key] = &PL_sv_undef;
+ AvARRAY(av)[key] = NULL;
do {
AvFILLp(av)--;
- } while (--key >= 0 && AvARRAY(av)[key] == &PL_sv_undef);
+ } while (--key >= 0 && !AvARRAY(av)[key]);
}
else
- AvARRAY(av)[key] = &PL_sv_undef;
+ AvARRAY(av)[key] = NULL;
if (SvSMAGICAL(av))
mg_set(MUTABLE_SV(av));
}
@@ -902,7 +898,7 @@ Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
Returns true if the element indexed by C<key> has been initialized.
This relies on the fact that uninitialized array elements are set to
-C<&PL_sv_undef>.
+NULL.
Perl equivalent: C<exists($myarray[$key])>.
@@ -955,8 +951,7 @@ Perl_av_exists(pTHX_ AV *av, I32 key)
return FALSE;
}
- if (key <= AvFILLp(av) && AvARRAY(av)[key] != &PL_sv_undef
- && AvARRAY(av)[key])
+ if (key <= AvFILLp(av) && AvARRAY(av)[key])
{
return TRUE;
}
diff --git a/dist/Storable/Storable.xs b/dist/Storable/Storable.xs
index 439009a789..c89517007e 100644
--- a/dist/Storable/Storable.xs
+++ b/dist/Storable/Storable.xs
@@ -156,7 +156,8 @@
#define SX_WEAKOVERLOAD C(28) /* Overloaded weak reference */
#define SX_VSTRING C(29) /* vstring forthcoming (small) */
#define SX_LVSTRING C(30) /* vstring forthcoming (large) */
-#define SX_ERROR C(31) /* Error */
+#define SX_SVUNDEF_ELEM C(31) /* array element set to &PL_sv_undef */
+#define SX_ERROR C(32) /* Error */
/*
* Those are only used to retrieve "old" pre-0.6 binary images.
@@ -843,7 +844,7 @@ static const char byteorderstr_56[] = {BYTEORDER_BYTES_56, 0};
#endif
#define STORABLE_BIN_MAJOR 2 /* Binary major "version" */
-#define STORABLE_BIN_MINOR 9 /* Binary minor "version" */
+#define STORABLE_BIN_MINOR 10 /* Binary minor "version" */
#if (PATCHLEVEL <= 5)
#define STORABLE_BIN_WRITE_MINOR 4
@@ -852,6 +853,9 @@ static const char byteorderstr_56[] = {BYTEORDER_BYTES_56, 0};
* Perl 5.6.0-5.8.0 can do weak references, but not vstring magic.
*/
#define STORABLE_BIN_WRITE_MINOR 8
+#elif PATCHLEVEL >= 19
+/* Perl 5.19 takes away the special meaning of PL_sv_undef in arrays. */
+#define STORABLE_BIN_WRITE_MINOR 10
#else
#define STORABLE_BIN_WRITE_MINOR 9
#endif /* (PATCHLEVEL <= 5) */
@@ -935,7 +939,9 @@ static const char byteorderstr_56[] = {BYTEORDER_BYTES_56, 0};
#define STORE_SCALAR(pv, len) STORE_PV_LEN(pv, len, SX_SCALAR, SX_LSCALAR)
/*
- * Store &PL_sv_undef in arrays without recursing through store().
+ * Store &PL_sv_undef in arrays without recursing through store(). We
+ * actually use this to represent nonexistent elements, for historical
+ * reasons.
*/
#define STORE_SV_UNDEF() \
STMT_START { \
@@ -1186,6 +1192,7 @@ static const sv_retrieve_t sv_old_retrieve[] = {
(sv_retrieve_t)retrieve_other, /* SX_WEAKOVERLOAD not supported */
(sv_retrieve_t)retrieve_other, /* SX_VSTRING not supported */
(sv_retrieve_t)retrieve_other, /* SX_LVSTRING not supported */
+ (sv_retrieve_t)retrieve_other, /* SX_SVUNDEF_ELEM not supported */
(sv_retrieve_t)retrieve_other, /* SX_ERROR */
};
@@ -1206,6 +1213,7 @@ static SV *retrieve_weakref(pTHX_ stcxt_t *cxt, const char *cname);
static SV *retrieve_weakoverloaded(pTHX_ stcxt_t *cxt, const char *cname);
static SV *retrieve_vstring(pTHX_ stcxt_t *cxt, const char *cname);
static SV *retrieve_lvstring(pTHX_ stcxt_t *cxt, const char *cname);
+static SV *retrieve_svundef_elem(pTHX_ stcxt_t *cxt, const char *cname);
static const sv_retrieve_t sv_retrieve[] = {
0, /* SX_OBJECT -- entry unused dynamically */
@@ -1239,6 +1247,7 @@ static const sv_retrieve_t sv_retrieve[] = {
(sv_retrieve_t)retrieve_weakoverloaded, /* SX_WEAKOVERLOAD */
(sv_retrieve_t)retrieve_vstring, /* SX_VSTRING */
(sv_retrieve_t)retrieve_lvstring, /* SX_LVSTRING */
+ (sv_retrieve_t)retrieve_svundef_elem, /* SX_SVUNDEF_ELEM */
(sv_retrieve_t)retrieve_other, /* SX_ERROR */
};
@@ -2253,10 +2262,23 @@ static int store_array(pTHX_ stcxt_t *cxt, AV *av)
for (i = 0; i < len; i++) {
sav = av_fetch(av, i, 0);
if (!sav) {
- TRACEME(("(#%d) undef item", i));
+ TRACEME(("(#%d) nonexistent item", i));
STORE_SV_UNDEF();
continue;
}
+#if PATCHLEVEL >= 19
+ /* In 5.19.3 and up, &PL_sv_undef can actually be stored in
+ * an array; it no longer represents nonexistent elements.
+ * Historically, we have used SX_SV_UNDEF in arrays for
+ * nonexistent elements, so we use SX_SVUNDEF_ELEM for
+ * &PL_sv_undef itself. */
+ if (*sav == &PL_sv_undef) {
+ TRACEME(("(#%d) undef item", i));
+ cxt->tagnum++;
+ PUTMARK(SX_SVUNDEF_ELEM);
+ continue;
+ }
+#endif
TRACEME(("(#%d) item", i));
if ((ret = store(aTHX_ cxt, *sav))) /* Extra () for -Wall, grr... */
return ret;
@@ -5238,6 +5260,24 @@ static SV *retrieve_sv_no(pTHX_ stcxt_t *cxt, const char *cname)
}
/*
+ * retrieve_svundef_elem
+ *
+ * Return &PL_sv_placeholder, representing &PL_sv_undef in an array. This
+ * is a bit of a hack, but we already use SX_SV_UNDEF to mean a nonexistent
+ * element, for historical reasons.
+ */
+static SV *retrieve_svundef_elem(pTHX_ stcxt_t *cxt, const char *cname)
+{
+ TRACEME(("retrieve_svundef_elem"));
+
+ /* SEEN reads the contents of its SV argument, which we are not
+ supposed to do with &PL_sv_placeholder. */
+ SEEN(&PL_sv_undef, cname, 1);
+
+ return &PL_sv_placeholder;
+}
+
+/*
* retrieve_array
*
* Retrieve a whole array.
@@ -5253,6 +5293,7 @@ static SV *retrieve_array(pTHX_ stcxt_t *cxt, const char *cname)
AV *av;
SV *sv;
HV *stash;
+ bool seen_null = FALSE;
TRACEME(("retrieve_array (#%d)", cxt->tagnum));
@@ -5279,9 +5320,16 @@ static SV *retrieve_array(pTHX_ stcxt_t *cxt, const char *cname)
sv = retrieve(aTHX_ cxt, 0); /* Retrieve item */
if (!sv)
return (SV *) 0;
+ if (sv == &PL_sv_undef) {
+ seen_null = TRUE;
+ continue;
+ }
+ if (sv == &PL_sv_placeholder)
+ sv = &PL_sv_undef;
if (av_store(av, i, sv) == 0)
return (SV *) 0;
}
+ if (seen_null) av_fill(av, len-1);
TRACEME(("ok (retrieve_array at 0x%"UVxf")", PTR2UV(av)));
diff --git a/dist/Storable/t/malice.t b/dist/Storable/t/malice.t
index ffc9fcf54f..867a0d7505 100644
--- a/dist/Storable/t/malice.t
+++ b/dist/Storable/t/malice.t
@@ -34,8 +34,8 @@ $file_magic_str = 'pst0';
$other_magic = 7 + length $byteorder;
$network_magic = 2;
$major = 2;
-$minor = 9;
-$minor_write = $] > 5.008 ? 9 : $] > 5.005_50 ? 8 : 4;
+$minor = 10;
+$minor_write = $] >= 5.019 ? 10 : $] > 5.008 ? 9 : $] > 5.005_50 ? 8 : 4;
use Test::More;
@@ -208,7 +208,7 @@ sub test_things {
$where = $file_magic + $network_magic;
}
- # Just the header and a tag 255. As 30 is currently the highest tag, this
+ # Just the header and a tag 255. As 31 is currently the highest tag, this
# is "unexpected"
$copy = substr ($contents, 0, $where) . chr 255;
@@ -228,7 +228,7 @@ sub test_things {
# local $Storable::DEBUGME = 1;
# This is the delayed croak
test_corrupt ($copy, $sub,
- "/^Storable binary image v$header->{major}.$minor6 contains data of type 255. This Storable is v$header->{major}.$minor and can only handle data types up to 30/",
+ "/^Storable binary image v$header->{major}.$minor6 contains data of type 255. This Storable is v$header->{major}.$minor and can only handle data types up to 31/",
"bogus tag, minor plus 4");
# And check again that this croak is not delayed:
{
diff --git a/ext/B/t/showlex.t b/ext/B/t/showlex.t
index 6a531821f9..2871622a5d 100644
--- a/ext/B/t/showlex.t
+++ b/ext/B/t/showlex.t
@@ -31,7 +31,7 @@ if ($is_thread) {
ok "# use5005threads: test skipped\n";
} else {
$a = `$^X $path "-MO=Showlex" -e "my \@one" 2>&1`;
- like ($a, qr/sv_undef.*PVNV.*\@one.*sv_undef.*AV/s,
+ like ($a, qr/sv_undef.*PVNV.*\@one.*Nullsv.*AV/s,
"canonical usage works");
}
diff --git a/ext/Devel-Peek/Peek.xs b/ext/Devel-Peek/Peek.xs
index 1ea7f8fed9..73094b8efc 100644
--- a/ext/Devel-Peek/Peek.xs
+++ b/ext/Devel-Peek/Peek.xs
@@ -81,6 +81,7 @@ DeadCode(pTHX)
}
}
for (j = 1; j < AvFILL((AV*)svp[1]); j++) { /* Vars. */
+ if (!pad[j]) continue;
if (SvROK(pad[j])) {
levelref++;
do_sv_dump(0, Perl_debug_log, pad[j], 0, 4, 0, 0);
diff --git a/ext/IPC-Open3/lib/IPC/Open3.pm b/ext/IPC-Open3/lib/IPC/Open3.pm
index af1d1e0690..90bd9fb087 100644
--- a/ext/IPC-Open3/lib/IPC/Open3.pm
+++ b/ext/IPC-Open3/lib/IPC/Open3.pm
@@ -185,6 +185,10 @@ sub _open3 {
# it's too ugly to use @_ throughout to make perl do it for us
# tchrist 5-Mar-00
+ # Historically, open3(undef...) has silently worked, so keep
+ # it working.
+ splice @_, 0, 1, undef if \$_[0] == \undef;
+ splice @_, 1, 1, undef if \$_[1] == \undef;
unless (eval {
$_[0] = gensym unless defined $_[0] && length $_[0];
$_[1] = gensym unless defined $_[1] && length $_[1];
diff --git a/pad.c b/pad.c
index d8d9322c60..92765f0f79 100644
--- a/pad.c
+++ b/pad.c
@@ -285,6 +285,7 @@ Perl_pad_new(pTHX_ int flags)
av_store(pad, 0, NULL);
padname = newAV();
AvPAD_NAMELIST_on(padname);
+ av_store(padname, 0, &PL_sv_undef);
}
/* Most subroutines never recurse, hence only need 2 entries in the padlist
@@ -1651,11 +1652,13 @@ Perl_pad_swipe(pTHX_ PADOFFSET po, bool refadjust)
PL_curpad[po] = newSV(0);
SvPADTMP_on(PL_curpad[po]);
#else
- PL_curpad[po] = &PL_sv_undef;
+ PL_curpad[po] = NULL;
#endif
if (PadnamelistMAX(PL_comppad_name) != -1
&& (PADOFFSET)PadnamelistMAX(PL_comppad_name) >= po) {
- assert(!PadnameLEN(PadnamelistARRAY(PL_comppad_name)[po]));
+ if (PadnamelistARRAY(PL_comppad_name)[po]) {
+ assert(!PadnameLEN(PadnamelistARRAY(PL_comppad_name)[po]));
+ }
PadnamelistARRAY(PL_comppad_name)[po] = &PL_sv_undef;
}
if ((I32)po < PL_padix)
@@ -1767,21 +1770,23 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
av_store(PL_comppad_name, AvFILLp(PL_comppad), NULL);
if (type == padtidy_SUBCLONE) {
- SV * const * const namep = AvARRAY(PL_comppad_name);
+ SV ** const namep = AvARRAY(PL_comppad_name);
PADOFFSET ix;
for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
SV *namesv;
+ if (!namep[ix]) namep[ix] = &PL_sv_undef;
/*
* The only things that a clonable function needs in its
* pad are anonymous subs, constants and GVs.
* The rest are created anew during cloning.
*/
- if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
+ if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix])
+ || IS_PADGV(PL_curpad[ix]))
continue;
- if (!((namesv = namep[ix]) != NULL &&
- PadnamePV(namesv) &&
+ namesv = namep[ix];
+ if (!(PadnamePV(namesv) &&
(!PadnameLEN(namesv) || *SvPVX_const(namesv) == '&')))
{
SvREFCNT_dec(PL_curpad[ix]);
@@ -1797,10 +1802,12 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
}
if (type == padtidy_SUB || type == padtidy_FORMAT) {
- SV * const * const namep = AvARRAY(PL_comppad_name);
+ SV ** const namep = AvARRAY(PL_comppad_name);
PADOFFSET ix;
for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
- if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]) || IS_PADCONST(PL_curpad[ix]))
+ if (!namep[ix]) namep[ix] = &PL_sv_undef;
+ if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix])
+ || IS_PADGV(PL_curpad[ix]) || IS_PADCONST(PL_curpad[ix]))
continue;
if (!SvPADMY(PL_curpad[ix])) {
SvPADTMP_on(PL_curpad[ix]);
@@ -2417,7 +2424,8 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
for ( ;ix > 0; ix--) {
if (!oldpad[ix]) {
pad1a[ix] = NULL;
- } else if (names_fill >= ix && PadnameLEN(names[ix])) {
+ } else if (names_fill >= ix && names[ix] &&
+ PadnameLEN(names[ix])) {
const char sigil = SvPVX_const(names[ix])[0];
if ((SvFLAGS(names[ix]) & SVf_FAKE)
|| (SvFLAGS(names[ix]) & SVpad_STATE)
@@ -2446,7 +2454,9 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
}
}
}
- else if (IS_PADGV(oldpad[ix]) || PadnamePV(names[ix])) {
+ else if (IS_PADGV(oldpad[ix])
+ || ( names_fill >= ix && names[ix]
+ && PadnamePV(names[ix]) )) {
pad1a[ix] = sv_dup_inc(oldpad[ix], param);
}
else {
diff --git a/pp.c b/pp.c
index fd40453657..17e0f3bb51 100644
--- a/pp.c
+++ b/pp.c
@@ -4330,7 +4330,7 @@ PP(pp_aslice)
svp = av_fetch(av, elem, lval);
if (lval) {
- if (!svp || *svp == &PL_sv_undef)
+ if (!svp || !*svp)
DIE(aTHX_ PL_no_aelem, elem);
if (localizing) {
if (preeminent)
@@ -5016,7 +5016,7 @@ PP(pp_splice)
}
i = -diff;
while (i)
- dst[--i] = &PL_sv_undef;
+ dst[--i] = NULL;
if (newlen) {
Copy( tmparyval, AvARRAY(ary) + offset, newlen, SV* );
diff --git a/pp_hot.c b/pp_hot.c
index b08643fcc1..58a30831d8 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -339,7 +339,11 @@ S_pushav(pTHX_ AV* const av)
}
}
else {
- Copy(AvARRAY(av), SP+1, maxarg, SV*);
+ U32 i;
+ for (i=0; i < (U32)maxarg; i++) {
+ SV * const sv = AvARRAY(av)[i];
+ SP[i+1] = sv ? sv : &PL_sv_undef;
+ }
}
SP += maxarg;
PUTBACK;
@@ -1055,8 +1059,8 @@ PP(pp_aassign)
i = 0;
while (relem <= lastrelem) { /* gobble up all the rest */
SV **didstore;
- assert(*relem);
- SvGETMAGIC(*relem); /* before newSV, in case it dies */
+ if (*relem)
+ SvGETMAGIC(*relem); /* before newSV, in case it dies */
sv = newSV(0);
sv_setsv_nomg(sv, *relem);
*(relem++) = sv;
@@ -2830,7 +2834,7 @@ PP(pp_aelem)
MEM_WRAP_CHECK_1(elem,SV*,oom_array_extend);
}
#endif
- if (!svp || *svp == &PL_sv_undef) {
+ if (!svp || !*svp) {
SV* lv;
if (!defer)
DIE(aTHX_ PL_no_aelem, elem);
diff --git a/regexec.c b/regexec.c
index 5f142a0332..d207d0d951 100644
--- a/regexec.c
+++ b/regexec.c
@@ -7318,7 +7318,7 @@ S_core_regclass_swash(pTHX_ const regexp *prog, const regnode* node, bool doinit
/* Element [1] is reserved for the set-up swash. If already there,
* return it; if not, create it and store it there */
- if (SvROK(ary[1])) {
+ if (ary[1] && SvROK(ary[1])) {
sw = ary[1];
}
else if (si && doinit) {