Re: [perl #30568] splice generates undef? [PATCH]
LAUN Wolfgang [Mon, 12 Jul 2004 08:26:01 +0000 (10:26 +0200)]
Message-ID: <DF27CDCBD2581D4B88431901094E4B4D02B0C7D2@attmsx1.aut.alcatel.at>

p4raw-id: //depot/perl@23092

pp.c
t/op/splice.t

diff --git a/pp.c b/pp.c
index 9425bca..659366f 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -4125,6 +4125,13 @@ PP(pp_splice)
     if (newlen && !AvREAL(ary) && AvREIFY(ary))
        av_reify(ary);
 
+    /* make new elements SVs now: avoid problems if they're from the array */
+    for (dst = MARK, i = newlen; i; i--) {
+        SV *h = *dst;
+       *dst = NEWSV(46, 0);
+       sv_setsv(*dst++, h);
+    }
+
     if (diff < 0) {                            /* shrinking the area */
        if (newlen) {
            New(451, tmparyval, newlen, SV*);   /* so remember insertion */
@@ -4181,11 +4188,7 @@ PP(pp_splice)
            dst[--i] = &PL_sv_undef;
        
        if (newlen) {
-           for (src = tmparyval, dst = AvARRAY(ary) + offset;
-             newlen; newlen--) {
-               *dst = NEWSV(46, 0);
-               sv_setsv(*dst++, *src++);
-           }
+           Copy( tmparyval, AvARRAY(ary) + offset, newlen, SV* );
            Safefree(tmparyval);
        }
     }
@@ -4224,10 +4227,10 @@ PP(pp_splice)
            }
        }
 
-       for (src = MARK, dst = AvARRAY(ary) + offset; newlen; newlen--) {
-           *dst = NEWSV(46, 0);
-           sv_setsv(*dst++, *src++);
+       if (newlen) {
+           Copy( MARK, AvARRAY(ary) + offset, newlen, SV* );
        }
+
        MARK = ORIGMARK + 1;
        if (GIMME == G_ARRAY) {                 /* copy return vals to stack */
            if (length) {
index 6d9b71f..1ffcb49 100755 (executable)
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..12\n";
+print "1..18\n";
 
 @a = (1..10);
 
@@ -52,3 +52,33 @@ $foo = shift @a;
 print "not " unless $foo eq 'red';
 print "ok 12\n";
 
+# Bug [perl #30568] - insertions of deleted elements
+@a = (1, 2, 3);
+splice( @a, 0, 3, $a[1], $a[0] );
+print "not " unless j(@a) eq j(2,1);
+print "ok 13\n";
+
+@a = (1, 2, 3);
+splice( @a, 0, 3 ,$a[0], $a[1] );
+print "not " unless j(@a) eq j(1,2);
+print "ok 14\n";
+
+@a = (1, 2, 3);
+splice( @a, 0, 3 ,$a[2], $a[1], $a[0] );
+print "not " unless j(@a) eq j(3,2,1);
+print "ok 15\n";
+
+@a = (1, 2, 3);
+splice( @a, 0, 3, $a[0], $a[1], $a[2], $a[0], $a[1], $a[2] );
+print "not " unless j(@a) eq j(1,2,3,1,2,3);
+print "ok 16\n";
+
+@a = (1, 2, 3);
+splice( @a, 1, 2, $a[2], $a[1] );
+print "not " unless j(@a) eq j(1,3,2);
+print "ok 17\n";
+
+@a = (1, 2, 3);
+splice( @a, 1, 2, $a[1], $a[1] );
+print "not " unless j(@a) eq j(1,2,2);
+print "ok 18\n";