summaryrefslogtreecommitdiff
path: root/toke.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-26 18:03:04 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-06-26 18:05:02 -0700
commit9700e2d38d91e6678fcdf9d5c39ddd5ec7ad6867 (patch)
tree3d608816dd8dfd8152040a6a061ed6446d54b04c /toke.c
parent43fdf692884d7d7101eac00b3deb3bf5766fe378 (diff)
downloadperl-9700e2d38d91e6678fcdf9d5c39ddd5ec7ad6867.tar.gz
[perl #117535, #76910] Fix bogus ambiguity warnings
‘Ambiguous use of * resolved as operator *’: This message can occur in cases where there is no multiplication operator, so what it is saying is completely wrong. When the lexer parses a bareword, it looks at the previous character and warns if it happens to match /[*%&]/, so foo**bar and foo&&bar result in this warning, as does print $%foo. The purpose of the code is to catch *bar *bar or &black &sheep. To avoid false positives, when emitting one of the three operators * % & the lexer can record that fact, so when it sees a bareword pre- ceded by one of those three characters, instead of guessing that the infix operator was used, it will *know*. The test cases added also trigger ‘Bareword found where operator expected’. I don’t know whether that should change, but at least the current behaviour is tested, so we will know when it does change.
Diffstat (limited to 'toke.c')
-rw-r--r--toke.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/toke.c b/toke.c
index aedccc555d..8f6eb44177 100644
--- a/toke.c
+++ b/toke.c
@@ -4640,6 +4640,7 @@ Perl_yylex(pTHX)
char *d;
STRLEN len;
bool bof = FALSE;
+ const bool saw_infix_sigil = PL_parser->saw_infix_sigil;
U8 formbrack = 0;
U32 fake_eof = 0;
@@ -5042,6 +5043,7 @@ Perl_yylex(pTHX)
s = PL_bufptr;
PL_oldoldbufptr = PL_oldbufptr;
PL_oldbufptr = s;
+ PL_parser->saw_infix_sigil = 0;
retry:
#ifdef PERL_MAD
@@ -5697,6 +5699,7 @@ Perl_yylex(pTHX)
s--;
TOKEN(0);
}
+ PL_parser->saw_infix_sigil = 1;
Mop(OP_MULTIPLY);
case '%':
@@ -5705,6 +5708,7 @@ Perl_yylex(pTHX)
PL_lex_fakeeof >= LEX_FAKEEOF_ASSIGN)
TOKEN(0);
++s;
+ PL_parser->saw_infix_sigil = 1;
Mop(OP_MODULO);
}
PL_tokenbuf[0] = '%';
@@ -6198,6 +6202,7 @@ Perl_yylex(pTHX)
s--;
TOKEN(0);
}
+ PL_parser->saw_infix_sigil = 1;
BAop(OP_BIT_AND);
}
@@ -7433,7 +7438,8 @@ Perl_yylex(pTHX)
op_free(rv2cv_op);
safe_bareword:
- if ((lastchar == '*' || lastchar == '%' || lastchar == '&')) {
+ if ((lastchar == '*' || lastchar == '%' || lastchar == '&')
+ && saw_infix_sigil) {
Perl_ck_warner_d(aTHX_ packWARN(WARN_AMBIGUOUS),
"Operator or semicolon missing before %c%"SVf,
lastchar, SVfARG(newSVpvn_flags(PL_tokenbuf,