authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-27 14:52:00-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-27 14:52:00-07:00
loge494ce760428cde79b63e9a9016c4af06484eef3
tree3205a2de5e327e61883c1d2dec37e027fe079842
parentc1a5ff34f3f68a2a0bc32828ab483328cd436fea

stage2: fix small memory leak of test_functions when using `zig test`

The way `zig test` works is that it uses a stand-in var test_functions: []const TestFn = undefined; during semantic analysis, but then just before codegen, it swaps out the value with a constant like this: const test_functions: []const TestFn = .{foo, bar, baz, etc}; Before this commit, the `Module.Variable` associated with the stand-in value was leaked; now it is properly cleaned up before being replaced.

2 files changed, 20 insertions(+), 5 deletions(-)

src/Module.zig+15-5
......@@ -4767,15 +4767,25 @@ pub fn populateTestFunctions(mod: *Module) !void {
47674767 try mod.linkerUpdateDecl(array_decl);
47684768
47694769 {
4770 var arena_instance = decl.value_arena.?.promote(gpa);
4771 defer decl.value_arena.?.* = arena_instance.state;
4772 const arena = &arena_instance.allocator;
4770 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
4771 errdefer new_decl_arena.deinit();
4772 const arena = &new_decl_arena.allocator;
47734773
4774 decl.ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena));
4775 decl.val = try Value.Tag.slice.create(arena, .{
4774 // This copy accesses the old Decl Type/Value so it must be done before `clearValues`.
4775 const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena));
4776 const new_val = try Value.Tag.slice.create(arena, .{
47764777 .ptr = try Value.Tag.decl_ref.create(arena, array_decl),
47774778 .len = try Value.Tag.int_u64.create(arena, mod.test_functions.count()),
47784779 });
4780
4781 // Since we are replacing the Decl's value we must perform cleanup on the
4782 // previous value.
4783 decl.clearValues(gpa);
4784 decl.ty = new_ty;
4785 decl.val = new_val;
4786 decl.has_tv = true;
4787
4788 try decl.finalizeNewArena(&new_decl_arena);
47794789 }
47804790 try mod.linkerUpdateDecl(decl);
47814791}
src/Sema.zig+5
......@@ -10762,6 +10762,11 @@ fn zirVarExtended(
1076210762 }
1076310763
1076410764 const new_var = try sema.gpa.create(Module.Var);
10765
10766 log.debug("created variable {*} owner_decl: {*} ({s})", .{
10767 new_var, sema.owner_decl, sema.owner_decl.name,
10768 });
10769
1076510770 new_var.* = .{
1076610771 .owner_decl = sema.owner_decl,
1076710772 .init = init_val,