This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #105924] require 1 << 2
authorFather Chrysostomos <sprout@cpan.org>
Thu, 20 Sep 2012 13:24:25 +0000 (06:24 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 20 Sep 2012 15:37:58 +0000 (08:37 -0700)
Setting PL_expect after force_next has no effect, as force_next
(called by force_version and force_word) picks up the current value of
PL_expect and arranges for it to be reset thereto after the forced
token is force-fed to the parser.

The KEY_require case should be setting PL_expect to XTERM (as it
already does) when there is no forced token (version or bareword),
because we expect a term after ‘require’, but to XOPERATOR when
there is a forced token, because we expect an operator after that
forced token.

Since the PL_expect assignment has no effect after force_next, we can
set it to XOPERATOR before calling potentially calling force_next, and
then to XTERM afterwards.

Loop exits had the same bug, so this fixes them all.

t/base/lex.t
toke.c

index dc4abe5..bca43b4 100644 (file)
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..75\n";
+print "1..81\n";
 
 $x = 'x';
 
@@ -372,3 +372,11 @@ eval 'warn ({$_ => 1} + 1) if 0';
 print "not " if $@;
 print "ok 75 - listop({$_ => 1} + 1)\n";
 print "# $@" if $@;
+
+$test = 76;
+for(qw< require goto last next redo dump >) {
+    eval "sub { $_ foo << 2 }";
+    print "not " if $@;
+    print "ok ", $test++, " - [perl #105924] $_ WORD << ...\n";
+    print "# $@" if $@;
+}
diff --git a/toke.c b/toke.c
index b2d8119..e0e0acd 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -7508,6 +7508,7 @@ Perl_yylex(pTHX)
            UNI(OP_DBMCLOSE);
 
        case KEY_dump:
+           PL_expect = XOPERATOR;
            s = force_word(s,WORD,TRUE,FALSE,FALSE);
            LOOPX(OP_DUMP);
 
@@ -7640,6 +7641,7 @@ Perl_yylex(pTHX)
            LOP(OP_GREPSTART, XREF);
 
        case KEY_goto:
+           PL_expect = XOPERATOR;
            s = force_word(s,WORD,TRUE,FALSE,FALSE);
            LOOPX(OP_GOTO);
 
@@ -7762,6 +7764,7 @@ Perl_yylex(pTHX)
            LOP(OP_KILL,XTERM);
 
        case KEY_last:
+           PL_expect = XOPERATOR;
            s = force_word(s,WORD,TRUE,FALSE,FALSE);
            LOOPX(OP_LAST);
        
@@ -7866,6 +7869,7 @@ Perl_yylex(pTHX)
            OPERATOR(MY);
 
        case KEY_next:
+           PL_expect = XOPERATOR;
            s = force_word(s,WORD,TRUE,FALSE,FALSE);
            LOOPX(OP_NEXT);
 
@@ -8051,6 +8055,7 @@ Perl_yylex(pTHX)
 
        case KEY_require:
            s = SKIPSPACE1(s);
+           PL_expect = XOPERATOR;
            if (isDIGIT(*s)) {
                s = force_version(s, FALSE);
            }
@@ -8082,6 +8087,7 @@ Perl_yylex(pTHX)
            UNI(OP_RESET);
 
        case KEY_redo:
+           PL_expect = XOPERATOR;
            s = force_word(s,WORD,TRUE,FALSE,FALSE);
            LOOPX(OP_REDO);