diff options
author | David Mitchell <davem@iabyn.com> | 2015-11-23 08:15:40 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2015-11-23 08:46:48 +0000 |
commit | 04106f2e5c6e8162bd22fd9c7505096116e483cd (patch) | |
tree | 76e1a920c6a8a0f36eecef284cb46f715a798a38 /op.c | |
parent | a44fa0ed58afff072b11bd6c614f4b730b4bae7e (diff) | |
download | perl-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.c | 9 |
1 files changed, 9 insertions, 0 deletions
@@ -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); } |