From 832330094c00391ecd6f0ea4abf2d05261b5a10c Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Fri, 19 May 2023 20:14:34 +0200 Subject: [PATCH] wasm: aggregate_init - ensure zeroed result local When initializing a packed struct, we must ensure the result local is zero'd. Previously we would do this by ensuring a new local is allocated. Although a local is always zero by default, it meant that if such an initialization was being done inside a loop, it would re- use that very same local that could potentially still hold a different value. Because this value is `or`'d with the value, it would result in a miscompilation. By manually setting this result to 0, we guarantee the correct behavior. --- src/arch/wasm/CodeGen.zig | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 5e36bb3f89..11b7f65946 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -4893,8 +4893,15 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const struct_obj = result_ty.castTag(.@"struct").?.data; const fields = struct_obj.fields.values(); const backing_type = struct_obj.backing_int_ty; - // we ensure a new local is created so it's zero-initialized - const result = try func.ensureAllocLocal(backing_type); + + // ensure the result is zero'd + const result = try func.allocLocal(backing_type); + if (struct_obj.backing_int_ty.bitSize(func.target) <= 32) + try func.addImm32(0) + else + try func.addImm64(0); + try func.addLabel(.local_set, result.local.value); + var current_bit: u16 = 0; for (elements, 0..) |elem, elem_index| { const field = fields[elem_index];