aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-10-27 14:52:00 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-10-27 14:52:00 -0700
commite494ce760428cde79b63e9a9016c4af06484eef3 (patch)
tree3205a2de5e327e61883c1d2dec37e027fe079842 /src
parentc1a5ff34f3f68a2a0bc32828ab483328cd436fea (diff)
downloadzig-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.zig20
-rw-r--r--src/Sema.zig5
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,