MARK = ORIGMARK + 1;
if (GIMME == G_ARRAY) { /* copy return vals to stack */
+ const bool real = cBOOL(AvREAL(ary));
MEXTEND(MARK, length);
- Copy(AvARRAY(ary)+offset, MARK, length, SV*);
- if (AvREAL(ary)) {
+ if (real)
EXTEND_MORTAL(length);
- for (i = length, dst = MARK; i; i--) {
+ for (i = 0, dst = MARK; i < length; i++) {
+ if ((*dst = AvARRAY(ary)[i+offset])) {
+ if (real)
sv_2mortal(*dst); /* free them eventually */
- dst++;
}
+ else
+ *dst = &PL_sv_undef;
+ dst++;
}
MARK += length - 1;
}
MARK = ORIGMARK + 1;
if (GIMME == G_ARRAY) { /* copy return vals to stack */
if (length) {
- Copy(tmparyval, MARK, length, SV*);
- if (AvREAL(ary)) {
+ const bool real = cBOOL(AvREAL(ary));
+ if (real)
EXTEND_MORTAL(length);
- for (i = length, dst = MARK; i; i--) {
+ for (i = 0, dst = MARK; i < length; i++) {
+ if ((*dst = tmparyval[i])) {
+ if (real)
sv_2mortal(*dst); /* free them eventually */
- dst++;
}
+ else *dst = &PL_sv_undef;
+ dst++;
}
}
MARK += length - 1;
eval { splice( $new_arrayref, 0, 0, 1, 2, 3 ) };
like($@, qr/Not an ARRAY/, 'undefined first argument to splice');
+# Test arrays with nonexistent elements (crashes when it fails)
+@a = ();
+$#a++;
+is sprintf("%s", splice @a, 0, 1), "",
+ 'splice handles nonexistent elems when shrinking the array';
+@a = ();
+$#a++;
+is sprintf("%s", splice @a, 0, 1, undef), "",
+ 'splice handles nonexistent elems when array len stays the same';
+
done_testing;