diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-08-22 05:40:18 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-08-24 19:02:56 -0700 |
commit | e4916dd1b37bf1a38d4b4711efc268f2ddfca52f (patch) | |
tree | 33d3eb5ea90b8d67040fdfdcc1af975f11fb2acd /toke.c | |
parent | f393a21acd390a2084b262b82d021c5a00ddecd1 (diff) | |
download | perl-e4916dd1b37bf1a38d4b4711efc268f2ddfca52f.tar.gz |
[perl #80368] Fix implicit assignop in qq"a\U="
The bug report explains it all:
> $ perl -e 'print "a\U="'
> Can't modify constant item in concatenation (.) or string at -e line 1, near "print "a\U=""
> Execution of -e aborted due to compilation errors.
>
> The "a\U=" string constant ought to generate ops corresponding roughly to
> "a".uc("=") (which would then be constant-folded). However, the "=" is
> being interpreted by the tokeniser as part of the concatenation operator,
> producing ops corresponding to "a".=uc("") (which generates the error).
>
> This happens because the implicit concatenation operator is generated
> in toke.c via the Aop() macro, which allows an addition-type operator
> to be mutated into an assignment operator if it is immediately followed
> by an "=". It should instead be generated via one of the other macros,
> or possibly a new macro, that doesn't allow for mutation to an assignment
> operator.
This commit does the latter.
> There are multiple sites in toke.c making the same mistake.
The other two instances are harmless, but the next commit will change
them for a different reason (avoiding unnecessary PL_expect assign-
ments with a view to eventually removing PL_lex_expect).
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 4 |
1 files changed, 3 insertions, 1 deletions
@@ -196,6 +196,7 @@ static const char* const lex_state_names[] = { * PWop : power operator * PMop : pattern-matching operator * Aop : addition-level operator + * AopNOASSIGN : addition-level operator that is never part of .= * Mop : multiplication-level operator * Eop : equality-testing operator * Rop : relational operator <= != gt @@ -232,6 +233,7 @@ static const char* const lex_state_names[] = { #define PWop(f) return ao((pl_yylval.ival=f, PL_expect=XTERM, PL_bufptr=s, REPORT((int)POWOP))) #define PMop(f) return(pl_yylval.ival=f, PL_expect=XTERM, PL_bufptr=s, REPORT((int)MATCHOP)) #define Aop(f) return ao((pl_yylval.ival=f, PL_expect=XTERM, PL_bufptr=s, REPORT((int)ADDOP))) +#define AopNOASSIGN(f) return (pl_yylval.ival=f, PL_bufptr=s, REPORT((int)ADDOP)) #define Mop(f) return ao((pl_yylval.ival=f, PL_expect=XTERM, PL_bufptr=s, REPORT((int)MULOP))) #define Eop(f) return (pl_yylval.ival=f, PL_expect=XTERM, PL_bufptr=s, REPORT((int)EQOP)) #define Rop(f) return (pl_yylval.ival=f, PL_expect=XTERM, PL_bufptr=s, REPORT((int)RELOP)) @@ -4390,7 +4392,7 @@ Perl_yylex(pTHX) if (PL_lex_casemods == 1 && PL_lex_inpat) OPERATOR(','); else - Aop(OP_CONCAT); + AopNOASSIGN(OP_CONCAT); } else return yylex(); |