diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-27 14:52:00 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-27 14:52:00 -0700 |
| commit | e494ce760428cde79b63e9a9016c4af06484eef3 (patch) | |
| tree | 3205a2de5e327e61883c1d2dec37e027fe079842 /src | |
| parent | c1a5ff34f3f68a2a0bc32828ab483328cd436fea (diff) | |
| download | zig-e494ce760428cde79b63e9a9016c4af06484eef3.tar.gz zig-e494ce760428cde79b63e9a9016c4af06484eef3.zip | |
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 (limited to 'src')
| -rw-r--r-- | src/Module.zig | 20 | ||||
| -rw-r--r-- | src/Sema.zig | 5 |
2 files changed, 20 insertions, 5 deletions
diff --git a/src/Module.zig b/src/Module.zig index 2c51b0ab69..f0b3701e6e 100644 --- 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 index 87216348f2..83b81ef174 100644 --- 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, |
