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.
This commit is contained in:
Luuk de Gram
2023-05-19 20:14:34 +02:00
parent ca870aa005
commit 832330094c

View File

@@ -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];