Hi, the attached proposed patch against blead hopefully fixes a problem when a lvalue-sub has an element of a tied hash or array as its last statement. It should be a solution for buglet #30582 "Conflicts between the :shared attribute and lvalue subroutines" which boiled down to
$ perl -MTie::Hash -we'tie %x,"Tie::StdHash"; sub foo:lvalue {$x{foo}} foo=1' Can't return a temporary from lvalue subroutine at -e line 1. The patch also contains a couple of new tests in t/op/sub_lval.t for these constructs. Tassilo -- use bigint; $n=71423350343770280161397026330337371139054411854220053437565440; $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
--- [EMAIL PROTECTED]/pp_hot.c 2005-07-20 09:33:46.000000000 +0200 +++ [EMAIL PROTECTED]/pp_hot.c 2005-07-20 10:32:23.000000000 +0200 @@ -2441,7 +2441,10 @@ PP(pp_leavesublv) MARK = newsp + 1; EXTEND_MORTAL(1); if (MARK == SP) { - if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { + /* Temporaries are bad unless they happen to be elements + * of a tied hash or array */ + if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY) && + !(SvRMAGICAL(TOPs) && mg_find(TOPs, PERL_MAGIC_tiedelem))) { LEAVE; cxstack_ix--; POPSUB(cx,sv); --- [EMAIL PROTECTED]/t/op/sub_lval.t 2005-07-20 09:33:49.000000000 +0200 +++ [EMAIL PROTECTED]/t/op/sub_lval.t 2005-07-20 10:30:41.000000000 +0200 @@ -1,4 +1,4 @@ -print "1..68\n"; +print "1..72\n"; BEGIN { chdir 't' if -d 't'; @@ -530,8 +530,51 @@ sub lval2 : lvalue { $ary[1]; } print "not " unless join(':', @ary) eq "1:2:6"; print "ok 64\n"; +# check that an element of a tied hash/array can be assigned to via lvalueness + +package Tie_Hash; + +our ($key, $val); +sub TIEHASH { bless \my $v => __PACKAGE__ } +sub STORE { ($key, $val) = @_[1,2] } + +package main; +sub lval_tie_hash : lvalue { + tie my %t => 'Tie_Hash'; + $t{key}; +} + +eval { lval_tie_hash() = "value"; }; + +print "# element of tied hash: [EMAIL PROTECTED] " if $@; +print "ok 65\n"; + +print "not " if "$Tie_Hash::key-$Tie_Hash::val" ne "key-value"; +print "ok 66\n"; + + +package Tie_Array; + +our @val; +sub TIEARRAY { bless \my $v => __PACKAGE__ } +sub STORE { $val[ $_[1] ] = $_[2] } + +package main; +sub lval_tie_array : lvalue { + tie my @t => 'Tie_Array'; + $t[0]; +} + +eval { lval_tie_array() = "value"; }; + +print "# element of tied array: [EMAIL PROTECTED] " if $@; +print "ok 67\n"; + +print "not " if $Tie_Array::val[0] ne "value"; +print "ok 68\n"; + require './test.pl'; -curr_test(65); +curr_test(69); TODO: { local $TODO = 'test explicit return of lval expr';