From: Vincent Pit Date: Wed, 26 Nov 2008 18:49:48 +0000 (+0100) Subject: Addendum to bug #38809: fix assertion failure, more tests X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1c8a42233ec49324eba45ced7d5587186f2e1587;p=p5sagit%2Fp5-mst-13.2.git Addendum to bug #38809: fix assertion failure, more tests Message-ID: <492D8C3C.1010003@profvince.com> p4raw-id: //depot/perl@34921 --- diff --git a/op.c b/op.c index 9c278df..990cf4b 100644 --- a/op.c +++ b/op.c @@ -7651,14 +7651,15 @@ Perl_ck_return(pTHX_ OP *o) } else { for (; kid; kid = kid->op_sibling) if ((kid->op_type == OP_NULL) - && (kid->op_flags & OPf_SPECIAL)) { + && ((kid->op_flags & (OPf_SPECIAL|OPf_KIDS)) == (OPf_SPECIAL|OPf_KIDS))) { /* This is a do block */ - OP *op = cUNOPx(kid)->op_first; - assert(op && (op->op_type == OP_LEAVE) && (op->op_flags & OPf_KIDS)); - op = cUNOPx(op)->op_first; - assert(op->op_type == OP_ENTER && !(op->op_flags & OPf_SPECIAL)); - /* Force the use of the caller's context */ - op->op_flags |= OPf_SPECIAL; + OP *op = kUNOP->op_first; + if (op->op_type == OP_LEAVE && op->op_flags & OPf_KIDS) { + op = cUNOPx(op)->op_first; + assert(op->op_type == OP_ENTER && !(op->op_flags & OPf_SPECIAL)); + /* Force the use of the caller's context */ + op->op_flags |= OPf_SPECIAL; + } } } diff --git a/t/op/do.t b/t/op/do.t index 90a106c..43ce3e8 100755 --- a/t/op/do.t +++ b/t/op/do.t @@ -29,7 +29,7 @@ sub ok { return $ok; } -print "1..32\n"; +print "1..38\n"; # Test do &sub and proper @_ handling. $_[0] = 0; @@ -105,21 +105,40 @@ $owww = do { 4 if not $zok }; ok( $owww eq '', 'last is if not' ); # [perl #38809] +@a = (7); +$x = sub { do { return do { @a } }; 2 }->(); +ok(defined $x && $x == 1, 'return do { } receives caller scalar context'); +@x = sub { do { return do { @a } }; 2 }->(); +ok("@x" eq "7", 'return do { } receives caller list context'); + @a = (7, 8); $x = sub { do { return do { 1; @a } }; 3 }->(); -ok(defined $x && $x == 2, 'return do { } receives caller scalar context'); +ok(defined $x && $x == 2, 'return do { ; } receives caller scalar context'); @x = sub { do { return do { 1; @a } }; 3 }->(); -ok("@x" eq "7 8", 'return do { } receives caller list context'); +ok("@x" eq "7 8", 'return do { ; } receives caller list context'); + +@b = (11 .. 15); +$x = sub { do { return do { 1; @a, @b } }; 3 }->(); +ok(defined $x && $x == 5, 'return do { ; , } receives caller scalar context'); +@x = sub { do { return do { 1; @a, @b } }; 3 }->(); +ok("@x" eq "7 8 11 12 13 14 15", 'return do { ; , } receives caller list context'); + +$x = sub { do { return do { 1; @a }, do { 2; @b } }; 3 }->(); +ok(defined $x && $x == 5, 'return do { ; }, do { ; } receives caller scalar context'); +@x = sub { do { return do { 1; @a }, do { 2; @b } }; 3 }->(); +ok("@x" eq "7 8 11 12 13 14 15", 'return do { ; }, do { ; } receives caller list context'); + @a = (7, 8, 9); $x = sub { do { do { 1; return @a } }; 4 }->(); ok(defined $x && $x == 3, 'do { return } receives caller scalar context'); @x = sub { do { do { 1; return @a } }; 4 }->(); ok("@x" eq "7 8 9", 'do { return } receives caller list context'); + @a = (7, 8, 9, 10); $x = sub { do { return do { 1; do { 2; @a } } }; 5 }->(); -ok(defined $x && $x == 4, 'return do { do { } } receives caller scalar context'); +ok(defined $x && $x == 4, 'return do { do { ; } } receives caller scalar context'); @x = sub { do { return do { 1; do { 2; @a } } }; 5 }->(); -ok("@x" eq "7 8 9 10", 'return do { do { } } receives caller list context'); +ok("@x" eq "7 8 9 10", 'return do { do { ; } } receives caller list context'); END { 1 while unlink("$$.16", "$$.17", "$$.18");