Fix parsing of readline(FH) [perl #68458]
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>
Sun, 23 Aug 2009 13:28:22 +0000 (15:28 +0200)
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>
Sun, 23 Aug 2009 13:28:22 +0000 (15:28 +0200)
This was broken by commit 984f9f66477bc722578262ae8520584e44e881af,
which was committed to solve bug [perl #53806].

Basically, to make everyone happy, we need only to enforce strictures
on barewords that follow the specially parsed keywords "print" and
"exec" (and similar) -- except when they have been already parsed.

t/lib/strict/subs
toke.c

index 03cda4f..25c6543 100644 (file)
@@ -409,16 +409,23 @@ EXPECT
 Bareword "FOO" not allowed while "strict subs" in use at - line 4.
 Execution of - aborted due to compilation errors.
 ########
-# TODO: commit 984f9f66477bc722578262ae8520584e44e881af broke this parsing
 use strict 'subs';
 my @players;
-sub _rankCompare { }
-@players = sort(_rankCompare @players);
+eval { @players = sort(_rankCompare @players) };
+sub _rankCompare2 { }
+@players = sort(_rankCompare2 @players);
 EXPECT
 
 ########
-# TODO: commit 984f9f66477bc722578262ae8520584e44e881af broke this parsing
 use strict;
-readline(STDIN);
+readline(FOO);
 EXPECT
 
+########
+use strict 'subs';
+sub sayfoo { print "foo:@_\n" }
+system sayfoo "bar";
+system sayfoo . "bar";
+EXPECT
+foo:bar
+foo:
diff --git a/toke.c b/toke.c
index b264279..734c516 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -5699,10 +5699,22 @@ Perl_yylex(pTHX)
 
                /* Call it a bare word */
 
-               bareword:
                if (PL_hints & HINT_STRICT_SUBS)
                    pl_yylval.opval->op_private |= OPpCONST_STRICT;
                else {
+               bareword:
+                   /* after "print" and similar functions (corresponding to
+                    * "F? L" in opcode.pl), whatever wasn't already parsed as
+                    * a filehandle should be subject to "strict subs".
+                    * Likewise for the optional indirect-object argument to system
+                    * or exec, which can't be a bareword */
+                   if ((PL_last_lop_op == OP_PRINT
+                           || PL_last_lop_op == OP_PRTF
+                           || PL_last_lop_op == OP_SAY
+                           || PL_last_lop_op == OP_SYSTEM
+                           || PL_last_lop_op == OP_EXEC)
+                           && (PL_hints & HINT_STRICT_SUBS))
+                       pl_yylval.opval->op_private |= OPpCONST_STRICT;
                    if (lastchar != '-') {
                        if (ckWARN(WARN_RESERVED)) {
                            d = PL_tokenbuf;