summaryrefslogtreecommitdiff
path: root/toke.c
diff options
context:
space:
mode:
Diffstat (limited to 'toke.c')
-rw-r--r--toke.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/toke.c b/toke.c
index 98fd125dc0..4e7ae3b84d 100644
--- a/toke.c
+++ b/toke.c
@@ -6560,8 +6560,11 @@ Perl_yylex(pTHX)
{
OP *const_op = newSVOP(OP_CONST, 0, SvREFCNT_inc_NN(sv));
const_op->op_private = OPpCONST_BARE;
- rv2cv_op = newCVREF(0, const_op);
- cv = lex ? GvCV(gv) : rv2cv_op_cv(rv2cv_op, 0);
+ rv2cv_op =
+ newCVREF(OPpMAY_RETURN_CONSTANT<<8, const_op);
+ cv = lex
+ ? GvCV(gv)
+ : rv2cv_op_cv(rv2cv_op, RV2CVOPCV_RETURN_STUB);
}
/* See if it's the indirect object for a list operator. */
@@ -6675,6 +6678,7 @@ Perl_yylex(pTHX)
/* Not a method, so call it a subroutine (if defined) */
if (cv) {
+ OP *gvop;
if (lastchar == '-' && penultchar != '-') {
const STRLEN l = len ? len : strlen(PL_tokenbuf);
Perl_ck_warner_d(aTHX_ packWARN(WARN_AMBIGUOUS),
@@ -6699,6 +6703,20 @@ Perl_yylex(pTHX)
TOKEN(WORD);
}
+ /* Resolve to GV now if this is a placeholder. */
+ if ((gvop = cUNOPx(rv2cv_op)->op_first)
+ && gvop->op_type == OP_GV) {
+ GV *gv2 = cGVOPx_gv(gvop);
+ if (gv2 && !isGV(gv2)) {
+ gv = gv_fetchpv(PL_tokenbuf, 0, SVt_PVCV);
+ assert (SvTYPE(gv) == SVt_PVGV);
+ /* cv must have been some sort of placeholder,
+ so now needs replacing with a real code
+ reference. */
+ cv = GvCV(gv);
+ }
+ }
+
op_free(pl_yylval.opval);
pl_yylval.opval =
off ? (OP *)newCVREF(0, rv2cv_op) : rv2cv_op;