localize = 1;
/* FALL THROUGH */
case OP_AASSIGN:
- if (type == OP_LEAVESUBLV)
+ /* Do not apply the lvsub flag for rv2[ah]v in scalar context. */
+ if (type == OP_LEAVESUBLV && (
+ (o->op_type != OP_RV2AV && o->op_type != OP_RV2HV)
+ || (o->op_flags & OPf_WANT) != OPf_WANT_SCALAR
+ ))
o->op_private |= OPpMAYBE_LVSUB;
/* FALL THROUGH */
case OP_NEXTSTATE:
return o; /* Treat \(@foo) like ordinary list. */
if (scalar_mod_type(o, type))
goto nomod;
- if (type == OP_LEAVESUBLV)
+ if ((o->op_flags & OPf_WANT) != OPf_WANT_SCALAR
+ && type == OP_LEAVESUBLV)
o->op_private |= OPpMAYBE_LVSUB;
/* FALL THROUGH */
case OP_PADSV:
@INC = '../lib';
require './test.pl';
}
-plan tests=>203;
+plan tests=>205;
sub a : lvalue { my $a = 34; ${\(bless \$a)} } # Return a temporary
sub b : lvalue { ${\shift} }
like($_, qr/Can\'t return a temporary from lvalue subroutine/,
'returning a PADTMP explicitly (list context)');
+# These next two tests are not necessarily normative. But this way we will
+# know if this discrepancy changes.
+
+$_ = undef;
+eval <<'EOE' or $_ = $@;
+ sub scalarray : lvalue { @a || $b }
+ @a = 1;
+ (scalarray) = (2,3);
+ 1;
+EOE
+
+like($_, qr/Can\'t return a temporary from lvalue subroutine/,
+ 'returning a scalar-context array via ||');
+
+$_ = undef;
+eval <<'EOE' or $_ = $@;
+ use warnings "FATAL" => "all";
+ sub myscalarray : lvalue { my @a = 1; @a || $b }
+ (myscalarray) = (2,3);
+ 1;
+EOE
+
+like($_, qr/Useless assignment to a temporary/,
+ 'returning a scalar-context lexical array via ||');
+
$_ = undef;
sub lv2t : lvalue { shift }
(lv2t($_)) = (2,3);