From 885ef6f56b61fd750ef3b1fa614d11480baac635 Mon Sep 17 00:00:00 2001 From: Gerard Goossen Date: Sun, 27 Dec 2009 17:24:28 +0100 Subject: [PATCH] Ignore a lvalue attribute after the subroutine has been defined, and warn about it. Fixes part of [perl #68758]. --- op.c | 4 +++- pod/perldiag.pod | 8 ++++++++ t/op/attrs.t | 8 ++++---- t/op/sub_lval.t | 14 +++++++++++++- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/op.c b/op.c index 88a31d3..db17d14 100644 --- a/op.c +++ b/op.c @@ -5714,7 +5714,9 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) )&& !attrs) { if (CvFLAGS(PL_compcv)) { /* might have had built-in attrs applied */ - CvFLAGS(cv) |= (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS); + if (CvLVALUE(PL_compcv) && ! CvLVALUE(cv)) + Perl_warner(aTHX_ packWARN(WARN_MISC), "lvalue attribute ignored after the subroutine has been defined"); + CvFLAGS(cv) |= (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS & ~CVf_LVALUE); } /* just a "sub foo;" when &foo is already defined */ SAVEFREESV(PL_compcv); diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 6656148..2b8d2c0 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -2307,6 +2307,14 @@ You may wish to switch to using L explicitly. by that? lstat() makes sense only on filenames. (Perl did a fstat() instead on the filehandle.) +=item lvalue attribute ignored after the subroutine has been defined + +(W) Making a subroutine an lvalue subroutine after it has been defined +by declaring the subroutine with a lvalue attribute is not +possible. To make the the subroutine a lvalue subroutine add the +lvalue attribute to the definition, or put the the declaration before +the definition. + =item Lvalue subs returning %s not implemented yet (F) Due to limitations in the current implementation, array and hash diff --git a/t/op/attrs.t b/t/op/attrs.t index 8f059b0..8239572 100644 --- a/t/op/attrs.t +++ b/t/op/attrs.t @@ -115,15 +115,15 @@ eval 'package A; sub PS : lvalue'; is "@attrs", "lvalue"; # Test ability to modify existing sub's (or XSUB's) attributes. -eval 'package A; sub X { $_[0] } sub X : lvalue'; +eval 'package A; sub X { $_[0] } sub X : method'; @attrs = eval 'attributes::get \&A::X'; -is "@attrs", "lvalue"; +is "@attrs", "method"; # Above not with just 'pure' built-in attributes. sub Z::MODIFY_CODE_ATTRIBUTES { (); } -eval 'package Z; sub L { $_[0] } sub L : Z lvalue'; +eval 'package Z; sub L { $_[0] } sub L : Z method'; @attrs = eval 'attributes::get \&Z::L'; -is "@attrs", "lvalue Z"; +is "@attrs", "method Z"; # Begin testing attributes that tie diff --git a/t/op/sub_lval.t b/t/op/sub_lval.t index a159bac..d2e70fe 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=>69; +plan tests=>70; sub a : lvalue { my $a = 34; ${\(bless \$a)} } # Return a temporary sub b : lvalue { ${\shift} } @@ -550,3 +550,15 @@ TODO: { $foo->bar; is ($result, 'bar', "RT #41550"); } + +fresh_perl_is(<<'----', <<'====', "lvalue can not be set after definition. [perl #68758]"); +use warnings; +our $x; +sub foo { $x } +sub foo : lvalue; +foo = 3; +---- +lvalue attribute ignored after the subroutine has been defined at - line 4. +Can't modify non-lvalue subroutine call in scalar assignment at - line 5, near "3;" +Execution of - aborted due to compilation errors. +==== -- 1.8.3.1