authorgravatar for t5j6p9@gmail.comTyler Philbrick <t5j6p9@gmail.com> 2019-04-23 00:47:55-07:00
committergravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-05-12 01:54:30-07:00
log16aee1f58a80295f7599a8290d764a5c7040c373
tree5aad83f912fff8f1b32ca4c03e313ebbdaa4b9be
parent4e28c2571d375e8e04df19074694f3fef252092c
signature Commit is signed but in an unrecognized format.

Fix memory leak in parser tests

The `arena` instance being used bythe parse tree was valid and pointed to valid memory, but existed as a local variable inside the stack frame of the `parse` function (the `const arena`), which was never stored anywhere before leaving the scope. This meant that code above the `parse` function saw a valid instance of an `ArenaAllocator` that pointed to the same backing memory, but didn't posess any of the local state built up after the call to `parseRoot`, basically the caller saw an empty arena. This meant that when `deinit` was called, it saw an Arena with 0 allocations in it's `buffer_list` and wasn't able to destroy any of the memory. This caused it to leak and caused FailingAllocator to balk. The fix is to make sure the parse tree is using the same instance of ArenaAllocator as is reported up the call stack, the one inside the `Tree{}` object. I'm not sure why that field is marked with a comment to remove it, as it's used by the `std.ast.Tree.deinit()` function, but this change seems to solve the problem.

1 files changed, 2 insertions(+), 2 deletions(-)

std/zig/parse2.zig+2-2
...@@ -31,10 +31,10 @@ pub fn parse(allocator: *Allocator, source: []const u8) !Tree {...@@ -31,10 +31,10 @@ pub fn parse(allocator: *Allocator, source: []const u8) !Tree {
31 .tokens = token_list,31 .tokens = token_list,
32 .errors = Tree.ErrorList.init(arena),32 .errors = Tree.ErrorList.init(arena),
33 // TODO: Remove (not used/needed anywhere)33 // TODO: Remove (not used/needed anywhere)
34 .arena_allocator = undefined,34 .arena_allocator = tree_arena,
35 };35 };
3636
37 tree.root_node = try parseRoot(arena, &it, &tree);37 tree.root_node = try parseRoot(&tree.arena_allocator.allocator, &it, &tree);
3838
39 return tree;39 return tree;
40}40}