authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-03 00:20:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-04 15:57:40-07:00
log8bfbfa589c424fc58d9c9a097b1df050738a337c
treec68e4b56f504f260dd1f28a56370d51e86c0fed2
parent73a76b45c5a2c8fc6ff884c4d3c84c29d37c3034

CBE: fix clone of freed locals not being deep clone


1 files changed, 37 insertions(+), 10 deletions(-)

src/codegen/c.zig+37-10
...@@ -411,7 +411,7 @@ pub const Function = struct {...@@ -411,7 +411,7 @@ pub const Function = struct {
411 pub fn deinit(f: *Function, gpa: mem.Allocator) void {411 pub fn deinit(f: *Function, gpa: mem.Allocator) void {
412 f.allocs.deinit(gpa);412 f.allocs.deinit(gpa);
413 f.locals.deinit(gpa);413 f.locals.deinit(gpa);
414 f.free_locals.deinit(gpa);414 deinitFreeLocalsMap(gpa, &f.free_locals);
415 f.blocks.deinit(gpa);415 f.blocks.deinit(gpa);
416 f.value_map.deinit();416 f.value_map.deinit();
417 f.object.code.deinit();417 f.object.code.deinit();
...@@ -4285,8 +4285,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4285,8 +4285,8 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4285 const gpa = f.object.dg.gpa;4285 const gpa = f.object.dg.gpa;
4286 var cloned_map = try f.value_map.clone();4286 var cloned_map = try f.value_map.clone();
4287 defer cloned_map.deinit();4287 defer cloned_map.deinit();
4288 var cloned_frees = try f.free_locals.clone(gpa);4288 var cloned_frees = try cloneFreeLocalsMap(gpa, &f.free_locals);
4289 defer cloned_frees.deinit(gpa);4289 defer deinitFreeLocalsMap(gpa, &cloned_frees);
42904290
4291 for (liveness_condbr.then_deaths) |operand| {4291 for (liveness_condbr.then_deaths) |operand| {
4292 try die(f, inst, Air.indexToRef(operand));4292 try die(f, inst, Air.indexToRef(operand));
...@@ -4299,7 +4299,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4299,7 +4299,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4299 try writer.writeAll(" else ");4299 try writer.writeAll(" else ");
4300 f.value_map.deinit();4300 f.value_map.deinit();
4301 f.value_map = cloned_map.move();4301 f.value_map = cloned_map.move();
4302 f.free_locals.deinit(gpa);4302 deinitFreeLocalsMap(gpa, &f.free_locals);
4303 f.free_locals = cloned_frees.move();4303 f.free_locals = cloned_frees.move();
4304 for (liveness_condbr.else_deaths) |operand| {4304 for (liveness_condbr.else_deaths) |operand| {
4305 try die(f, inst, Air.indexToRef(operand));4305 try die(f, inst, Air.indexToRef(operand));
...@@ -4362,18 +4362,19 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4362,18 +4362,19 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4362 const old_value_map = f.value_map;4362 const old_value_map = f.value_map;
4363 f.value_map = try old_value_map.clone();4363 f.value_map = try old_value_map.clone();
4364 const old_free_locals = f.free_locals;4364 const old_free_locals = f.free_locals;
4365 f.free_locals = try f.free_locals.clone(gpa);4365 f.free_locals = try cloneFreeLocalsMap(gpa, &f.free_locals);
4366
4367 for (liveness.deaths[case_i]) |operand| {
4368 try die(f, inst, Air.indexToRef(operand));
4369 }
43704366
4371 defer {4367 defer {
4372 f.value_map.deinit();4368 f.value_map.deinit();
4373 f.free_locals.deinit(gpa);4369 deinitFreeLocalsMap(gpa, &f.free_locals);
4374 f.value_map = old_value_map;4370 f.value_map = old_value_map;
4375 f.free_locals = old_free_locals;4371 f.free_locals = old_free_locals;
4376 }4372 }
4373
4374 for (liveness.deaths[case_i]) |operand| {
4375 try die(f, inst, Air.indexToRef(operand));
4376 }
4377
4377 try genBody(f, case_body);4378 try genBody(f, case_body);
4378 } else {4379 } else {
4379 for (liveness.deaths[case_i]) |operand| {4380 for (liveness.deaths[case_i]) |operand| {
...@@ -6933,3 +6934,29 @@ fn iterateBigTomb(f: *Function, inst: Air.Inst.Index) BigTomb {...@@ -6933,3 +6934,29 @@ fn iterateBigTomb(f: *Function, inst: Air.Inst.Index) BigTomb {
6933 .lbt = f.liveness.iterateBigTomb(inst),6934 .lbt = f.liveness.iterateBigTomb(inst),
6934 };6935 };
6935}6936}
6937
6938/// A naive clone of this map would create copies of the ArrayList which is
6939/// stored in the values. This function additionally clones the values.
6940fn cloneFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) !LocalsMap {
6941 var cloned = try map.clone(gpa);
6942 const values = cloned.values();
6943 var i: usize = 0;
6944 errdefer {
6945 cloned.deinit(gpa);
6946 while (i > 0) {
6947 i -= 1;
6948 values[i].deinit(gpa);
6949 }
6950 }
6951 while (i < values.len) : (i += 1) {
6952 values[i] = try values[i].clone(gpa);
6953 }
6954 return cloned;
6955}
6956
6957fn deinitFreeLocalsMap(gpa: mem.Allocator, map: *LocalsMap) void {
6958 for (map.values()) |*value| {
6959 value.deinit(gpa);
6960 }
6961 map.deinit(gpa);
6962}