diff options
-rw-r--r-- | op.c | 19 | ||||
-rw-r--r-- | pp_hot.c | 14 | ||||
-rw-r--r-- | t/op/sub_lval.t | 8 |
3 files changed, 25 insertions, 16 deletions
@@ -6368,14 +6368,8 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) exit. */ PL_breakable_sub_gen++; - if (CvLVALUE(cv)) { - CvROOT(cv) = newUNOP(OP_LEAVESUBLV, 0, - op_lvalue(scalarseq(block), OP_LEAVESUBLV)); - block->op_attached = 1; - } - else { - /* This makes sub {}; work as expected. */ - if (block->op_type == OP_STUB) { + /* This makes sub {}; work as expected. */ + if (block->op_type == OP_STUB) { OP* const newblock = newSTATEOP(0, NULL, 0); #ifdef PERL_MAD op_getmad(block,newblock,'B'); @@ -6383,11 +6377,12 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) op_free(block); #endif block = newblock; - } - else - block->op_attached = 1; - CvROOT(cv) = newUNOP(OP_LEAVESUB, 0, scalarseq(block)); } + else block->op_attached = 1; + CvROOT(cv) = CvLVALUE(cv) + ? newUNOP(OP_LEAVESUBLV, 0, + op_lvalue(scalarseq(block), OP_LEAVESUBLV)) + : newUNOP(OP_LEAVESUB, 0, scalarseq(block)); CvROOT(cv)->op_private |= OPpREFCOUNTED; OpREFCNT_set(CvROOT(cv), 1); CvSTART(cv) = LINKLIST(CvROOT(cv)); @@ -2745,14 +2745,22 @@ PP(pp_leavesublv) SvREFCNT_inc_void(*mark); } } - else { /* Should not happen? */ + else { + /* sub:lvalue{} will take us here. + Presumably the case of a non-empty array never happens. + */ LEAVE; cxstack_ix--; POPSUB(cx,sv); PL_curpm = newpm; LEAVESUB(sv); - DIE(aTHX_ "%s returned from lvalue subroutine in scalar context", - (MARK > SP ? "Empty array" : "Array")); + DIE(aTHX_ "%s", + (MARK > SP + ? "Can't return undef from lvalue subroutine" + : "Array returned from lvalue subroutine in scalar " + "context" + ) + ); } SP = MARK; } diff --git a/t/op/sub_lval.t b/t/op/sub_lval.t index 787d904c4f..c1691cb336 100644 --- a/t/op/sub_lval.t +++ b/t/op/sub_lval.t @@ -3,7 +3,7 @@ BEGIN { @INC = '../lib'; require './test.pl'; } -plan tests=>107; +plan tests=>108; sub a : lvalue { my $a = 34; ${\(bless \$a)} } # Return a temporary sub b : lvalue { ${\shift} } @@ -230,6 +230,12 @@ EOE ok(!defined $_) or diag $_; +($a,$b)=(); +(lv0($a,$b)) = (3,4); +is +($a//'undef') . ($b//'undef'), 'undefundef', + 'list assignment to empty lvalue sub'; + + sub lv1u :lvalue { undef } $_ = undef; |