diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-06-26 18:03:04 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-06-26 18:05:02 -0700 |
commit | 9700e2d38d91e6678fcdf9d5c39ddd5ec7ad6867 (patch) | |
tree | 3d608816dd8dfd8152040a6a061ed6446d54b04c /toke.c | |
parent | 43fdf692884d7d7101eac00b3deb3bf5766fe378 (diff) | |
download | perl-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.c | 8 |
1 files changed, 7 insertions, 1 deletions
@@ -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, |