Retain builtin attributes from pre-declaration. Fixes [perl #68758].
Gerard Goossen [Sun, 27 Dec 2009 17:02:37 +0000 (18:02 +0100)]
op.c
t/op/attrs.t
t/op/sub_lval.t

diff --git a/op.c b/op.c
index db17d14..a7205cb 100644 (file)
--- a/op.c
+++ b/op.c
@@ -5785,8 +5785,9 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
                   && block->op_type != OP_NULL
 #endif
        ) {
+           cv_flags_t existing_builtin_attrs = CvFLAGS(cv) & CVf_BUILTIN_ATTRS;
            cv_undef(cv);
-           CvFLAGS(cv) = CvFLAGS(PL_compcv);
+           CvFLAGS(cv) = CvFLAGS(PL_compcv) | existing_builtin_attrs;
            if (!CvWEAKOUTSIDE(cv))
                SvREFCNT_dec(CvOUTSIDE(cv));
            CvOUTSIDE(cv) = CvOUTSIDE(PL_compcv);
index 8239572..7c98529 100644 (file)
@@ -14,7 +14,7 @@ BEGIN {
 
 use warnings;
 
-plan 91;
+plan 92;
 
 $SIG{__WARN__} = sub { die @_ };
 
@@ -114,6 +114,11 @@ eval 'package A; sub PS : lvalue';
 @attrs = eval 'attributes::get \&A::PS';
 is "@attrs", "lvalue";
 
+# Test attributes on predeclared subroutines, after definition
+eval 'package A; sub PS : lvalue; sub PS { }';
+@attrs = eval 'attributes::get \&A::PS';
+is "@attrs", "lvalue";
+
 # Test ability to modify existing sub's (or XSUB's) attributes.
 eval 'package A; sub X { $_[0] } sub X : method';
 @attrs = eval 'attributes::get \&A::X';
index d2e70fe..c20ffac 100644 (file)
@@ -3,7 +3,7 @@ BEGIN {
     @INC = '../lib';
     require './test.pl';
 }
-plan tests=>70;
+plan tests=>71;
 
 sub a : lvalue { my $a = 34; ${\(bless \$a)} }  # Return a temporary
 sub b : lvalue { ${\shift} }
@@ -562,3 +562,11 @@ 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.
 ====
+
+{
+    my $x;
+    sub lval_decl : lvalue;
+    sub lval_decl { $x }
+    lval_decl = 5;
+    is($x, 5, "subroutine declared with lvalue before definition retains lvalue. [perl #68758]");
+}