summaryrefslogtreecommitdiff
path: root/parser.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2018-02-26 18:52:23 +0000
committerDavid Mitchell <davem@iabyn.com>2018-03-02 13:36:43 +0000
commita8c5635617479436b1775ba4ab34e4bc791eda54 (patch)
tree870dda66a262326c7e359e6c8fd7d45383b39867 /parser.h
parent86ae8d9a6f56e9e71efc1f3e556f6770dc07566e (diff)
downloadperl-a8c5635617479436b1775ba4ab34e4bc791eda54.tar.gz
detect sub attributes following a signature
RT #132760 A recent commit (v5.27.7-212-g894f226) moved subroutine attributes back before the subroutine's signature: e.g. sub foo :prototype($$) ($a, $b) { ... } # 5.18 and 5.28 + sub foo ($a, $b) :prototype($$) { ... } # 5.20 .. 5.26 This change means that any code still using an attribute following the signature is going to trigger a syntax error. However, the error, followed by error recovery and further warnings and errors, is very unfriendly and gives no indication of the root cause. This commit introduces a new error, "Subroutine attributes must come before the signature". For example, List::Lazy, the subject of the ticket, failed to compile tests, with output like: Array found where operator expected at blib/lib/List/Lazy.pm line 43, near "$$@)" (Missing operator before @)?) "my" variable $step masks earlier declaration in same statement at blib/lib/List/Lazy.pm line 44. syntax error at blib/lib/List/Lazy.pm line 36, near ") :" Global symbol "$generator" requires explicit package name (did you forget to declare "my $generator"?) at blib/lib/List/Lazy.pm line 38. Global symbol "$state" requires explicit package name (did you forget to declare "my $state"?) at blib/lib/List/Lazy.pm line 39. Global symbol "$min" requires explicit package name (did you forget to declare "my $min"?) at blib/lib/List/Lazy.pm line 43. Global symbol "$max" requires explicit package name (did you forget to declare "my $max"?) at blib/lib/List/Lazy.pm line 43. Global symbol "$step" requires explicit package name (did you forget to declare "my $step"?) at blib/lib/List/Lazy.pm line 43. Invalid separator character '{' in attribute list at blib/lib/List/Lazy.pm line 44, near "$step : sub " Global symbol "$step" requires explicit package name (did you forget to declare "my $step"?) at blib/lib/List/Lazy.pm line 44. But following this commit, it now just outputs: Subroutine attributes must come before the signature at blib/lib/List/Lazy.pm line 36. Compilation failed in require at t/append.t line 5. BEGIN failed--compilation aborted at t/append.t line 5. It works by: 1) adding a boolean flag (sig_seen) to the parser state to indicate that a signature has been parsed; 2) at the end of parsing a signature, PL_expect is set to XATTRBLOCK rather than XBLOCK. Then if something looking like one or more attributes is encountered by the lexer immediately afterwards, it scans it as if it were an attribute, but then if sig_seen is true, it croaks.
Diffstat (limited to 'parser.h')
-rw-r--r--parser.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/parser.h b/parser.h
index 216e9deca8..19c5c63ad3 100644
--- a/parser.h
+++ b/parser.h
@@ -112,6 +112,7 @@ typedef struct yy_parser {
line_t herelines; /* number of lines in here-doc */
line_t preambling; /* line # when processing $ENV{PERL5DB} */
+ bool sig_seen; /* the currently parsing sub has a signature */
/* these are valid while parsing a subroutine signature */
IV sig_elems; /* number of signature elements seen so far */
IV sig_optelems; /* number of optional signature elems seen */