In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/9f021be64d99e25c9277e6c3e36d224ca74edaed?hp=66edcf79f81d47833f2be442966a5e90a223365f>
- Log ----------------------------------------------------------------- commit 9f021be64d99e25c9277e6c3e36d224ca74edaed Author: Father Chrysostomos <[email protected]> Date: Sun Mar 1 13:27:39 2015 -0800 op.c apidoc typo M op.c commit 71488339f94f1083d9e4d8f9014f5c979ba1a6d6 Author: Father Chrysostomos <[email protected]> Date: Sun Mar 1 13:26:52 2015 -0800 [perl #123821] Fix assert fail with \(&$0)=0 If the operand of a reference constructor that is assigned to is not valid, then S_lvref (in op.c) queues an error and does not bother to convert the op into an lvref op. This causes problems, since we have already set lvref-specific flags on the op in the expectation that its type will change. We get assertion failures later when freeing the op, because of the invalid flags. Instead of bailing out when we have an error like this, just continue processing it, as we do in many other places. M op.c M t/op/lvref.t commit 6b2b48acae2d74dcbde18f956f6951b5b9aa468b Author: Father Chrysostomos <[email protected]> Date: Sun Mar 1 13:16:36 2015 -0800 [perl #123817] Assert fail with attr in anon hash These two one-liners were failing an assertion: $y = { my $x : m } $y = [ (my $x : m) ] The lexical with an attribute was turning into an op of type âlistâ with the OPpLVAL_INTRO flag set. Many op constructors convert an operand that is of type âlistâ into the correct type, instead of creating a new op to wrap around it. Other ops were not expecting the flag to be set, causing an assertion failure. The easiest solution is to turn off the flag in op_convert_list, which is where the op type changes. (I tried modifying other op types to accept the flag, but that caused problems for B::Deparse, which inquires of B::Op_private which ops can legitimately take that flag.) M op.c M t/op/attrs.t commit a282984d19c73aae6ef9231e723101b3c3b5d2d0 Author: Father Chrysostomos <[email protected]> Date: Sun Mar 1 11:43:11 2015 -0800 op.c: Remove redundant op_lvalue call Refgen ops already call op_lvalue on their operands. Calling it beforehand causes it to be called twice, which is harmless, but wasteful. M op.c ----------------------------------------------------------------------- Summary of changes: op.c | 8 +++++--- t/op/attrs.t | 13 +++++++++++++ t/op/lvref.t | 3 +++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/op.c b/op.c index 45cde2b..e6b6069 100644 --- a/op.c +++ b/op.c @@ -2731,7 +2731,6 @@ S_lvref(pTHX_ OP *o, I32 type) ? "do block" : OP_DESC(o), PL_op_desc[type])); - return; } CHANGE_TYPE(o, OP_LVREF); o->op_private &= @@ -3412,7 +3411,7 @@ S_apply_attrs_my(pTHX_ HV *stash, OP *target, OP *attrs, OP **imopsp) newSVOP(OP_CONST, 0, stashsv), op_prepend_elem(OP_LIST, newUNOP(OP_REFGEN, 0, - op_lvalue(arg, OP_REFGEN)), + arg), dup_attrlist(attrs))); /* Fake up a method call to import */ @@ -4577,7 +4576,10 @@ Perl_op_convert_list(pTHX_ I32 type, I32 flags, OP *o) if (!o || o->op_type != OP_LIST) o = force_list(o, 0); else + { o->op_flags &= ~OPf_WANT; + o->op_private &= ~OPpLVAL_INTRO; + } if (!(PL_opargs[type] & OA_MARK)) op_null(cLISTOPo->op_first); @@ -4664,7 +4666,7 @@ supply up to two ops to be direct children of the list op; they are consumed by this function and become part of the constructed op tree. For most list operators, the check function expects all the kid ops to be -present already, so calling C<newLISTOP(OP_JOIN, ...)> (e.g.,) is not +present already, so calling C<newLISTOP(OP_JOIN, ...)> (e.g.) is not appropriate. What you want to do in that case is create an op of type OP_LIST, append more children to it, and then call L</op_convert_list>. See L</op_convert_list> for more information. diff --git a/t/op/attrs.t b/t/op/attrs.t index b93ed74..16e1fce 100644 --- a/t/op/attrs.t +++ b/t/op/attrs.t @@ -415,4 +415,17 @@ is $ProtoTest::Proto, '$', 'prototypes are visible in attr handlers'; 'applying const attr via attributes.pm'; } +# [perl #123817] Attributes in list-type operators +# These tests used to fail an assertion because the list op generated by +# the lexical attribute declaration was converted to another op type with +# the OPpLVAL_INTRO flag still set. These op types were not expecting that +# flag to be set, though it was harmless for non-debugging builds. +package _123817 { + sub MODIFY_SCALAR_ATTRIBUTES {()} + eval '{my $x : m}'; + eval '[(my $x : m)]'; + eval 'formline my $x : m'; + eval 'return my $x : m'; +} + done_testing(); diff --git a/t/op/lvref.t b/t/op/lvref.t index 2bdc26d..3e65198 100644 --- a/t/op/lvref.t +++ b/t/op/lvref.t @@ -587,3 +587,6 @@ SKIP: { \(@a) = \($x,$y); goto do_test3; } + +# Used to fail an assertion [perl #123821] +eval '\(&$0)=0'; -- Perl5 Master Repository
