Skip Menu |

This queue is for tickets about the Want CPAN distribution.

Report information
The Basics
Id: 72083
Status: resolved
Priority: 0/
Queue: Want

People
Owner: Nobody in particular
Requestors: ANDK [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.18
Fixed in: (no value)



Subject: Bleadperl v5.14.0-285-gfa1e92c breaks ROBIN/Want-0.18.tar.gz
https://rt.perl.org:443/rt3/Ticket/Display.html?id=102642 A cross reference to increase the chance of being found by interested parties... HTH,
Here is a patch to make Want work with perl 5.15. In 5.15, ‘return’ works in lvalue routines. So ‘return undef’ in lnoreturn ends up going through the lvalue code, which croaks on &PL_sv_undef (‘Can’t return undef...’). Turning off the lvalueness of the return with cx->blk_u16 &= ~OPpLVAL_INTRO; doesn’t work, because lvalue subs never copy their return values anymore (and pp_return uses CvLVALUE(cv) to determine whether to go through the lvalue code), so you get ‘Modification of a read-only value’. So we have to return a modifiable undef, but we don’t want a permanent variable, as the thing assigned to it would leak until the next lnoreturn. We can’t just say ‘return my $undef’, because of the new ‘Useless assignment to a temporary’ warning. So disarm_temp increases the refcount so that the code in pp_sassign that produces that warning will be fooled into thinking the scalar is still in use elsewhere. There are also test fix-ups to avoid (valid) warnings about assigning to temporaries, and to stop testing for Perl bugs. :-) BTW, double_return is one of the neatest tricks I’ve seen.
Subject: open_yqOZIIcO.txt
diff -rup Want-0.18-i_Beo4-orig/Want.pm Want-0.18-i_Beo4/Want.pm --- Want-0.18-i_Beo4-orig/Want.pm 2008-02-04 01:35:55.000000000 -0800 +++ Want-0.18-i_Beo4/Want.pm 2011-11-02 22:03:21.000000000 -0700 @@ -177,7 +177,7 @@ sub lnoreturn () { croak "Can't lnoreturn except in ASSIGN context"; } double_return(); - return undef; + return disarm_temp(my $undef); } # Some naughty people were relying on these internal methods. @@ -291,6 +291,7 @@ I<always> be in RVALUE context. If you need to return values from an lvalue subroutine in RVALUE context, you should use the C<rreturn> function rather than an ordinary C<return>. Otherwise you'll probably get a compile-time error in perl 5.6.1 and later. +As of perl 5.16, ordinary C<return> works fine. =item B<LVALUE> @@ -379,7 +380,7 @@ This makes it very easy to write lvalue backstr(my $robin) = "nibor"; print "\$robin is now $robin\n"; # $robin is now robin -Notice that you need to put a (meaningless) return +Notice that, prior to perl 5.16, you need to put a (meaningless) return statement at the end of the function, otherwise you will get the error I<Can't modify non-lvalue subroutine call in lvalue subroutine return>. @@ -496,8 +497,8 @@ A full list of the permitted keyword is Use this function instead of C<return> from inside an lvalue subroutine when you know that you're in RVALUE context. If you try to use a normal C<return>, -you'll get a compile-time error in Perl 5.6.1 and above unless you return an -lvalue. +you'll get a compile-time error in Perl 5.6.1 to 5.14.x unless you return +an lvalue. In perl 5.16, C<return> will suffice. =item lnoreturn @@ -505,7 +506,8 @@ Use this function instead of C<return> f you're in ASSIGN context and you've used C<want('ASSIGN')> to carry out the appropriate action. -If you use C<rreturn> or C<lnoreturn>, then you have to put a bare C<return;> +If you use C<rreturn> or C<lnoreturn>, then, unless you want to +depend on perl 5.16 or higher, you have to put a bare C<return;> at the very end of your lvalue subroutine, in order to stop the Perl compiler from complaining. Think of it as akin to the C<1;> that you have to put at the end of a module. diff -rup Want-0.18-i_Beo4-orig/Want.xs Want-0.18-i_Beo4/Want.xs --- Want-0.18-i_Beo4-orig/Want.xs 2008-02-03 14:29:35.000000000 -0800 +++ Want-0.18-i_Beo4/Want.xs 2011-11-02 22:11:38.000000000 -0700 @@ -676,3 +676,11 @@ double_return() #endif return; + +SV * +disarm_temp(sv) +SV *sv; + CODE: + RETVAL = sv_2mortal(SvREFCNT_inc(SvREFCNT_inc(sv))); + OUTPUT: + RETVAL diff -rup Want-0.18-i_Beo4-orig/t/all.t Want-0.18-i_Beo4/t/all.t --- Want-0.18-i_Beo4-orig/t/all.t 2011-11-02 20:10:38.000000000 -0700 +++ Want-0.18-i_Beo4/t/all.t 2011-11-02 20:33:14.000000000 -0700 @@ -13,7 +13,10 @@ sub lv :lvalue { my $xxx; } -&lv = 23; +{ + local $^W; + &lv = 23; +} sub rv :lvalue { print (Want::want_lvalue(0) ? "not ok 3\n" : "ok 3\n"); @@ -141,7 +144,7 @@ print ($y == 23 ? "ok 35\n" : "not ok 35 @x = \(g(37, 'LVALUE', 'LIST')); ($x) = \(scalar g(38, 'RVALUE')); $$x = 29; -print ($y != 29 ? "ok 39\n" : "not ok 39\n"); +print (($] ge 5.015 ? $y == 29 : $y != 29) ? "ok 39\n" : "not ok 39\n"); ng(41, 'REF') = g(40, 'HASH')->{foo}; $y = sub {}; # Just to silence warning diff -rup Want-0.18-i_Beo4-orig/t/assign.t Want-0.18-i_Beo4/t/assign.t --- Want-0.18-i_Beo4-orig/t/assign.t 2001-08-29 02:28:30.000000000 -0700 +++ Want-0.18-i_Beo4/t/assign.t 2011-11-02 20:33:57.000000000 -0700 @@ -25,8 +25,11 @@ sub idl :lvalue {@_[0..$#_]} t (2, qw/RVALUE !ASSIGN/); tl(3, qw/RVALUE !ASSIGN/); noop(tl(4, qw/LVALUE !ASSIGN/)); -tl(5, qw/LVALUE ASSIGN/) = (); -tl(6, 'ASSIGN') = (); +{ + local $^W; + tl(5, qw/LVALUE ASSIGN/) = (); + tl(6, 'ASSIGN') = (); +} sub backstr :lvalue { if (want('LVALUE')) {
RT-Send-CC: robin [...] cpan.org
Robin, I see you have released Want 0.19 and 0.20 to work around bleadperl changes. Did you realise I had a patch in this ticket (<https://rt.cpan.org/Ticket/Display.html? id=72083>)? I see that your code (in 0.20) will cause lnoreturn to leak the value assigned, at least until the next lnoreturn. On Thu Nov 03 01:24:27 2011, SPROUT wrote: Show quoted text
> Here is a patch to make Want work with perl 5.15. > > In 5.15, ‘return’ works in lvalue routines. So ‘return undef’ in > lnoreturn ends up going > through the lvalue code, which croaks on &PL_sv_undef (‘Can’t return > undef...’). > > Turning off the lvalueness of the return with > > cx->blk_u16 &= ~OPpLVAL_INTRO; > > doesn’t work, because lvalue subs never copy their return values > anymore (and pp_return > uses CvLVALUE(cv) to determine whether to go through the lvalue code), > so you get > ‘Modification of a read-only value’. > > So we have to return a modifiable undef, but we don’t want a permanent > variable, as the thing > assigned to it would leak until the next lnoreturn. > > We can’t just say ‘return my $undef’, because of the new ‘Useless > assignment to a temporary’ > warning. > > So disarm_temp increases the refcount so that the code in pp_sassign > that produces that > warning will be fooled into thinking the scalar is still in use > elsewhere. > > There are also test fix-ups to avoid (valid) warnings about assigning > to temporaries, and to > stop testing for Perl bugs. :-) > > BTW, double_return is one of the neatest tricks I’ve seen.
Subject: Re: [rt.cpan.org #72083] Bleadperl v5.14.0-285-gfa1e92c breaks ROBIN/Want-0.18.tar.gz
Date: Wed, 29 Feb 2012 10:28:54 +0000
To: bug-Want [...] rt.cpan.org
From: Robin Houston <robin.houston [...] gmail.com>
Thank you, Father. No, I didn’t know about this patch or had forgotten about it. Thanks for drawing my attention to it. I’ll see if I can understand what the problem is with my attempt, and then probably replace it with yours. :-) Cheers, Robin On 29 February 2012 04:36, Father Chrysostomos via RT <bug-Want@rt.cpan.org>wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=72083 > > > Robin, I see you have released Want 0.19 and 0.20 to work around bleadperl > changes. Did > you realise I had a patch in this ticket (< > https://rt.cpan.org/Ticket/Display.html? > id=72083>)? I see that your code (in 0.20) will cause lnoreturn to leak > the value assigned, at > least until the next lnoreturn. > > On Thu Nov 03 01:24:27 2011, SPROUT wrote:
> > Here is a patch to make Want work with perl 5.15. > > > > In 5.15, ‘return’ works in lvalue routines. So ‘return undef’ in > > lnoreturn ends up going > > through the lvalue code, which croaks on &PL_sv_undef (‘Can’t return > > undef...’). > > > > Turning off the lvalueness of the return with > > > > cx->blk_u16 &= ~OPpLVAL_INTRO; > > > > doesn’t work, because lvalue subs never copy their return values > > anymore (and pp_return > > uses CvLVALUE(cv) to determine whether to go through the lvalue code), > > so you get > > ‘Modification of a read-only value’. > > > > So we have to return a modifiable undef, but we don’t want a permanent > > variable, as the thing > > assigned to it would leak until the next lnoreturn. > > > > We can’t just say ‘return my $undef’, because of the new ‘Useless > > assignment to a temporary’ > > warning. > > > > So disarm_temp increases the refcount so that the code in pp_sassign > > that produces that > > warning will be fooled into thinking the scalar is still in use > > elsewhere. > > > > There are also test fix-ups to avoid (valid) warnings about assigning > > to temporaries, and to > > stop testing for Perl bugs. :-) > > > > BTW, double_return is one of the neatest tricks I’ve seen.
> > > >
Subject: Re: [rt.cpan.org #72083] Bleadperl v5.14.0-285-gfa1e92c breaks ROBIN/Want-0.18.tar.gz
Date: Wed, 29 Feb 2012 16:56:56 +0000
To: bug-Want [...] rt.cpan.org
From: Robin Houston <robin.houston [...] gmail.com>
Thanks for this. I’ve incorporated your suggestion at https://github.com/robinhouston/Want, I hope. Does it look okay to you? Thanks, Robin
RT-Send-CC: robin.houston [...] gmail.com, robin [...] cpan.org
On Wed Feb 29 11:57:05 2012, robin.houston@gmail.com wrote: Show quoted text
> Thanks for this. I’ve incorporated your suggestion at > https://github.com/robinhouston/Want, I hope. Does it look okay to you?
Yes, that looks good.
RT-Send-CC: robin [...] cpan.org
On Wed Feb 29 12:28:51 2012, SPROUT wrote: Show quoted text
> On Wed Feb 29 11:57:05 2012, robin.houston@gmail.com wrote:
> > Thanks for this. I’ve incorporated your suggestion at > > https://github.com/robinhouston/Want, I hope. Does it look okay to you?
> > Yes, that looks good.
But you might want to mention in the docs that explicit return can be used in 5.16.