authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-15 23:38:40+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-15 23:50:47+03:00
logb2f16d4484d2506d6a1e8a7d9f516f780d7fbd22
treed268fccb56981f6f060d46f73680af77e57e1af9
parenta00fd6e25469a9929defea95425a1c312a68cf0e
signature Commit is signed but in an unrecognized format.

fix infinite loop with mismatced bracket


4 files changed, 24 insertions(+), 11 deletions(-)

doc/langref.html.in+5-5
...@@ -10090,7 +10090,7 @@ FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Link...@@ -10090,7 +10090,7 @@ FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? Link
1009010090
10091VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON10091VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
1009210092
10093ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?10093ContainerField &lt;- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
1009410094
10095# *** Block Level ***10095# *** Block Level ***
10096Statement10096Statement
...@@ -10204,7 +10204,7 @@ PrimaryTypeExpr...@@ -10204,7 +10204,7 @@ PrimaryTypeExpr
10204 / KEYWORD_error DOT IDENTIFIER10204 / KEYWORD_error DOT IDENTIFIER
10205 / KEYWORD_false10205 / KEYWORD_false
10206 / KEYWORD_null10206 / KEYWORD_null
10207 / KEYWORD_promise10207 / KEYWORD_anyframe
10208 / KEYWORD_true10208 / KEYWORD_true
10209 / KEYWORD_undefined10209 / KEYWORD_undefined
10210 / KEYWORD_unreachable10210 / KEYWORD_unreachable
...@@ -10348,7 +10348,7 @@ PrefixOp...@@ -10348,7 +10348,7 @@ PrefixOp
1034810348
10349PrefixTypeOp10349PrefixTypeOp
10350 &lt;- QUESTIONMARK10350 &lt;- QUESTIONMARK
10351 / KEYWORD_promise MINUSRARROW10351 / KEYWORD_anyframe MINUSRARROW
10352 / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*10352 / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
10353 / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*10353 / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
1035410354
...@@ -10495,6 +10495,7 @@ end_of_word &lt;- ![a-zA-Z0-9_] skip...@@ -10495,6 +10495,7 @@ end_of_word &lt;- ![a-zA-Z0-9_] skip
10495KEYWORD_align &lt;- 'align' end_of_word10495KEYWORD_align &lt;- 'align' end_of_word
10496KEYWORD_allowzero &lt;- 'allowzero' end_of_word10496KEYWORD_allowzero &lt;- 'allowzero' end_of_word
10497KEYWORD_and &lt;- 'and' end_of_word10497KEYWORD_and &lt;- 'and' end_of_word
10498KEYWORD_anyframe &lt;- 'anyframe' end_of_word
10498KEYWORD_asm &lt;- 'asm' end_of_word10499KEYWORD_asm &lt;- 'asm' end_of_word
10499KEYWORD_async &lt;- 'async' end_of_word10500KEYWORD_async &lt;- 'async' end_of_word
10500KEYWORD_await &lt;- 'await' end_of_word10501KEYWORD_await &lt;- 'await' end_of_word
...@@ -10521,7 +10522,6 @@ KEYWORD_null &lt;- 'null' end_of_word...@@ -10521,7 +10522,6 @@ KEYWORD_null &lt;- 'null' end_of_word
10521KEYWORD_or &lt;- 'or' end_of_word10522KEYWORD_or &lt;- 'or' end_of_word
10522KEYWORD_orelse &lt;- 'orelse' end_of_word10523KEYWORD_orelse &lt;- 'orelse' end_of_word
10523KEYWORD_packed &lt;- 'packed' end_of_word10524KEYWORD_packed &lt;- 'packed' end_of_word
10524KEYWORD_promise &lt;- 'promise' end_of_word
10525KEYWORD_pub &lt;- 'pub' end_of_word10525KEYWORD_pub &lt;- 'pub' end_of_word
10526KEYWORD_resume &lt;- 'resume' end_of_word10526KEYWORD_resume &lt;- 'resume' end_of_word
10527KEYWORD_return &lt;- 'return' end_of_word10527KEYWORD_return &lt;- 'return' end_of_word
...@@ -10548,7 +10548,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm...@@ -10548,7 +10548,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm
10548 / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false10548 / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false
10549 / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline10549 / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline
10550 / KEYWORD_noalias / KEYWORD_null / KEYWORD_or10550 / KEYWORD_noalias / KEYWORD_null / KEYWORD_or
10551 / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub10551 / KEYWORD_orelse / KEYWORD_packed / KEYWORD_anyframe / KEYWORD_pub
10552 / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection10552 / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
10553 / KEYWORD_struct / KEYWORD_suspend10553 / KEYWORD_struct / KEYWORD_suspend
10554 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try10554 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
lib/std/zig/parse.zig+6-3
...@@ -69,8 +69,8 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error...@@ -69,8 +69,8 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
69/// <- TestDecl ContainerMembers69/// <- TestDecl ContainerMembers
70/// / TopLevelComptime ContainerMembers70/// / TopLevelComptime ContainerMembers
71/// / KEYWORD_pub? TopLevelDecl ContainerMembers71/// / KEYWORD_pub? TopLevelDecl ContainerMembers
72/// / KEYWORD_pub? ContainerField COMMA ContainerMembers72/// / ContainerField COMMA ContainerMembers
73/// / KEYWORD_pub? ContainerField73/// / ContainerField
74/// /74/// /
75fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree, top_level: bool) !Node.Root.DeclList {75fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree, top_level: bool) !Node.Root.DeclList {
76 var list = Node.Root.DeclList.init(arena);76 var list = Node.Root.DeclList.init(arena);
...@@ -284,7 +284,10 @@ fn findNextContainerMember(it: *TokenIterator) void {...@@ -284,7 +284,10 @@ fn findNextContainerMember(it: *TokenIterator) void {
284 }284 }
285 },285 },
286 .LParen, .LBracket, .LBrace => level += 1,286 .LParen, .LBracket, .LBrace => level += 1,
287 .RParen, .RBracket, .RBrace => {287 .RParen, .RBracket => {
288 if (level != 0) level -= 1;
289 },
290 .RBrace => {
288 if (level == 0) {291 if (level == 0) {
289 // end of container, exit292 // end of container, exit
290 putBackToken(it, tok.index);293 putBackToken(it, tok.index);
lib/std/zig/parser_test.zig+10
...@@ -162,6 +162,16 @@ test "recovery: extra '}' at top level" {...@@ -162,6 +162,16 @@ test "recovery: extra '}' at top level" {
162 });162 });
163}163}
164164
165test "recovery: mismatched bracket at top level" {
166 try testError(
167 \\const S = struct {
168 \\ arr: 128]?G
169 \\};
170 , &[_]Error{
171 .ExpectedToken,
172 });
173}
174
165test "zig fmt: top-level fields" {175test "zig fmt: top-level fields" {
166 try testCanonical(176 try testCanonical(
167 \\a: did_you_know,177 \\a: did_you_know,
src/parser.cpp+3-3
...@@ -538,8 +538,8 @@ enum ContainerFieldState {...@@ -538,8 +538,8 @@ enum ContainerFieldState {
538// <- TestDecl ContainerMembers538// <- TestDecl ContainerMembers
539// / TopLevelComptime ContainerMembers539// / TopLevelComptime ContainerMembers
540// / KEYWORD_pub? TopLevelDecl ContainerMembers540// / KEYWORD_pub? TopLevelDecl ContainerMembers
541// / KEYWORD_comptime? ContainerField COMMA ContainerMembers541// / ContainerField COMMA ContainerMembers
542// / KEYWORD_comptime? ContainerField542// / ContainerField
543// /543// /
544static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {544static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
545 AstNodeContainerDecl res = {};545 AstNodeContainerDecl res = {};
...@@ -862,7 +862,7 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {...@@ -862,7 +862,7 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
862 return res;862 return res;
863}863}
864864
865// ContainerField <- IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?865// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
866static AstNode *ast_parse_container_field(ParseContext *pc) {866static AstNode *ast_parse_container_field(ParseContext *pc) {
867 Token *identifier = eat_token_if(pc, TokenIdSymbol);867 Token *identifier = eat_token_if(pc, TokenIdSymbol);
868 if (identifier == nullptr)868 if (identifier == nullptr)