This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #129073] Assert failure: ${p{};sub p}()
authorFather Chrysostomos <sprout@cpan.org>
Sun, 4 Sep 2016 21:22:37 +0000 (14:22 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 4 Sep 2016 21:29:09 +0000 (14:29 -0700)
commitbdc377e5e0c60dfb539423e956843489501ca2bd
tree83b6f39eee74b52500f4b6953010570938a29733
parentba0a4150f6f1604df236035adf6df18bd43de88e
[perl #129073] Assert failure: ${p{};sub p}()

When parsing the special ${var{subscript}} syntax, the lexer notes
that the } matching the ${ will be a fake bracket, and should
be ignored.

In the case of ${p{};sub p}() the first syntax error causes tokens to
be popped, such that the } following the sub declaration ends up being
the one treated as a fake bracket and ignored.

The part of the lexer that deals with sub declarations treats a ( fol-
lowing the sub name as a prototype (which is a single term) if signa-
tures are disabled, but ignores it and allows the rest of the lexer to
treat it as a parenthesis if signatures are enabled.

Hence, the part of the parser (perly.y) that parses signatures knows
that a parenthesis token can only come after a sub if signatures are
enabled, and asserts as much.

In the case of an error and tokens being discarded, a parenthesis may
come after a sub name as far as the parser is concerned, even though
there was a } in between that got discarded.  The sub part of the
lexer, of course did not see the parenthesis because of the interven-
ing brace, and did not treat it as a prototype.  So we get an asser-
tion failure.

The simplest fix is to loosen up the assertion and allow for anomalies
after errors.  It does not hurt to go ahead and parse a signature at
this point, even though the feature is disabled, because there has
been a syntax error already, so the parsed code will never run, and
the parsed sub will not be installed.
perly.act
perly.h
perly.tab
perly.y
t/comp/parser.t