aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorxackus <14938807+xackus@users.noreply.github.com>2019-12-20 20:58:29 +0100
committerxackus <14938807+xackus@users.noreply.github.com>2020-01-10 22:35:41 +0100
commitf81529fab17fe1a7ded4f1aae959159563f09efb (patch)
treec1766cd4b46039b3db4f20bb7905a4662f849e7a /lib/std
parente06a6b9645827fa35cfa388bbea8813206d444ad (diff)
downloadzig-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.zig12
-rw-r--r--lib/std/zig/parser_test.zig15
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);
+}