zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit e494ce760428cde79b63e9a9016c4af06484eef3 (tree)
parent c1a5ff34f3f68a2a0bc32828ab483328cd436fea
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Wed, 27 Oct 2021 14:52:00 -0700

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.

Diffstat:
Msrc/Module.zig | 20+++++++++++++++-----
Msrc/Sema.zig | 5+++++
2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/Module.zig b/src/Module.zig @@ -4767,15 +4767,25 @@ pub fn populateTestFunctions(mod: *Module) !void { try mod.linkerUpdateDecl(array_decl); { - var arena_instance = decl.value_arena.?.promote(gpa); - defer decl.value_arena.?.* = arena_instance.state; - const arena = &arena_instance.allocator; + var new_decl_arena = std.heap.ArenaAllocator.init(gpa); + errdefer new_decl_arena.deinit(); + const arena = &new_decl_arena.allocator; - decl.ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena)); - decl.val = try Value.Tag.slice.create(arena, .{ + // This copy accesses the old Decl Type/Value so it must be done before `clearValues`. + const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena)); + const new_val = try Value.Tag.slice.create(arena, .{ .ptr = try Value.Tag.decl_ref.create(arena, array_decl), .len = try Value.Tag.int_u64.create(arena, mod.test_functions.count()), }); + + // Since we are replacing the Decl's value we must perform cleanup on the + // previous value. + decl.clearValues(gpa); + decl.ty = new_ty; + decl.val = new_val; + decl.has_tv = true; + + try decl.finalizeNewArena(&new_decl_arena); } try mod.linkerUpdateDecl(decl); } diff --git a/src/Sema.zig b/src/Sema.zig @@ -10762,6 +10762,11 @@ fn zirVarExtended( } const new_var = try sema.gpa.create(Module.Var); + + log.debug("created variable {*} owner_decl: {*} ({s})", .{ + new_var, sema.owner_decl, sema.owner_decl.name, + }); + new_var.* = .{ .owner_decl = sema.owner_decl, .init = init_val,