diff options
| author | xackus <14938807+xackus@users.noreply.github.com> | 2019-12-20 20:58:29 +0100 |
|---|---|---|
| committer | xackus <14938807+xackus@users.noreply.github.com> | 2020-01-10 22:35:41 +0100 |
| commit | f81529fab17fe1a7ded4f1aae959159563f09efb (patch) | |
| tree | c1766cd4b46039b3db4f20bb7905a4662f849e7a /lib/std | |
| parent | e06a6b9645827fa35cfa388bbea8813206d444ad (diff) | |
| download | zig-f81529fab17fe1a7ded4f1aae959159563f09efb.tar.gz zig-f81529fab17fe1a7ded4f1aae959159563f09efb.zip | |
stage2 parser: fix segfault on extern block
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/zig/parse.zig | 12 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 15 |
2 files changed, 26 insertions, 1 deletions
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index c9c9956159..049b8df10f 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -303,7 +303,17 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { const cc = parseFnCC(arena, it, tree); const fn_token = eatToken(it, .Keyword_fn) orelse { - if (cc == null) return null else return error.ParseError; + if (cc) |fnCC| { + if (fnCC == .Extern) { + putBackToken(it, fnCC.Extern); // 'extern' is also used in ContainerDecl + } else { + try tree.errors.push(AstError{ + .ExpectedToken = .{ .token = it.index, .expected_id = .Keyword_fn }, + }); + return error.ParseError; + } + } + return null; }; const name_token = eatToken(it, .Identifier); const lparen = try expectToken(it, tree, .LParen); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 97df2dff15..c57540ade9 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -2714,6 +2714,13 @@ test "zig fmt: top level doc comments" { ); } +test "zig fmt: extern without container keyword returns error" { + try testError( + \\const container = extern {}; + \\ + ); +} + const std = @import("std"); const mem = std.mem; const warn = std.debug.warn; @@ -2820,3 +2827,11 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void { fn testCanonical(source: []const u8) !void { return testTransform(source, source); } + +fn testError(source: []const u8) !void { + var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + const tree = try std.zig.parse(&fixed_allocator.allocator, source); + defer tree.deinit(); + + std.testing.expect(tree.errors.len != 0); +} |
