summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-11-23 08:15:40 +0000
committerDavid Mitchell <davem@iabyn.com>2015-11-23 08:46:48 +0000
commit04106f2e5c6e8162bd22fd9c7505096116e483cd (patch)
tree76e1a920c6a8a0f36eecef284cb46f715a798a38 /op.c
parenta44fa0ed58afff072b11bd6c614f4b730b4bae7e (diff)
downloadperl-04106f2e5c6e8162bd22fd9c7505096116e483cd.tar.gz
assertion failure on foo(my $x : bar)
RT #126257 'my var : attr' injects a void-context sub call just after the pad op. However, Perl_ck_entersub_args_list() tries to impose lvalue context on each of its args, which causes an assertion failure. This commit makes Perl_ck_entersub_args_list() skip calling op_lvalue() on any args which are OP_ENTERSUB/OPf_WANT_VOID. Strictly speaking it should check that the sub call is actually an attribute method call (e.g. first child is a const("attibutes") etc), but this was far too much like hard work.
Diffstat (limited to 'op.c')
-rw-r--r--op.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/op.c b/op.c
index 37d8656431..d7d1988189 100644
--- a/op.c
+++ b/op.c
@@ -11156,11 +11156,20 @@ OP *
Perl_ck_entersub_args_list(pTHX_ OP *entersubop)
{
OP *aop;
+
PERL_ARGS_ASSERT_CK_ENTERSUB_ARGS_LIST;
+
aop = cUNOPx(entersubop)->op_first;
if (!OpHAS_SIBLING(aop))
aop = cUNOPx(aop)->op_first;
for (aop = OpSIBLING(aop); OpHAS_SIBLING(aop); aop = OpSIBLING(aop)) {
+ /* skip the extra attributes->import() call implicitly added in
+ * something like foo(my $x : bar)
+ */
+ if ( aop->op_type == OP_ENTERSUB
+ && (aop->op_flags & OPf_WANT) == OPf_WANT_VOID
+ )
+ continue;
list(aop);
op_lvalue(aop, OP_ENTERSUB);
}