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.
This commit is contained in:
Andrew Kelley 2021-10-27 14:52:00 -07:00
parent c1a5ff34f3
commit e494ce7604
2 changed files with 20 additions and 5 deletions

View File

@ -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);
}

View File

@ -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,