From 29f531bec9fd8cedc0e0da0981d1a71bb3348641 Mon Sep 17 00:00:00 2001 From: Daniele Cocca Date: Sat, 13 Nov 2021 02:44:16 +0000 Subject: [PATCH] CBE: memset(..., 0xaa, ...) undefined values This commit makes airStore() handle undefined values directly instead of delegating to renderValue(): the call to renderValue() happens too late, when "dest = " has already been written to the stream, at which point there's no sane way to initialize e.g. struct values by assignment. Instead, we make airStore() use memset(dest, 0xaa, sizeof(dest)), which should transparently handle all types. Also moves the newly-passing tests to the top of test/behavior.zig. --- src/codegen/c.zig | 39 +++++++++++++++++++++++++++++++++++++++ test/behavior.zig | 12 ++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index c00b0247bb..e95a5a77ec 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1470,12 +1470,51 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { return local; } +fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue { + const is_debug_build = f.object.dg.module.optimizeMode() == .Debug; + if (!is_debug_build) + return CValue.none; + + const writer = f.object.writer(); + switch (dest_ptr) { + .local_ref => |i| { + const dest: CValue = .{ .local = i }; + try writer.writeAll("memset(&"); + try f.writeCValue(writer, dest); + try writer.writeAll(", 0xaa, sizeof("); + try f.writeCValue(writer, dest); + try writer.writeAll("));\n"); + }, + .decl_ref => |decl| { + const dest: CValue = .{ .decl = decl }; + try writer.writeAll("memset(&"); + try f.writeCValue(writer, dest); + try writer.writeAll(", 0xaa, sizeof("); + try f.writeCValue(writer, dest); + try writer.writeAll("));\n"); + }, + else => { + try writer.writeAll("memset("); + try f.writeCValue(writer, dest_ptr); + try writer.writeAll(", 0xaa, sizeof(*"); + try f.writeCValue(writer, dest_ptr); + try writer.writeAll("));\n"); + }, + } + return CValue.none; +} + fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { // *a = b; const bin_op = f.air.instructions.items(.data)[inst].bin_op; const dest_ptr = try f.resolveInst(bin_op.lhs); const src_val = try f.resolveInst(bin_op.rhs); + const src_val_is_undefined = + if (f.air.value(bin_op.rhs)) |v| v.isUndef() else false; + if (src_val_is_undefined) + return try airStoreUndefined(f, dest_ptr); + const writer = f.object.writer(); switch (dest_ptr) { .local_ref => |i| { diff --git a/test/behavior.zig b/test/behavior.zig index 9ef98bd772..4f78a9d35a 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -5,12 +5,15 @@ test { _ = @import("behavior/basic.zig"); _ = @import("behavior/bitcast.zig"); _ = @import("behavior/bool.zig"); + _ = @import("behavior/bugs/624.zig"); _ = @import("behavior/bugs/655.zig"); _ = @import("behavior/bugs/679.zig"); _ = @import("behavior/bugs/704.zig"); _ = @import("behavior/bugs/1486.zig"); _ = @import("behavior/bugs/2346.zig"); + _ = @import("behavior/bugs/2692.zig"); _ = @import("behavior/bugs/2889.zig"); + _ = @import("behavior/bugs/3586.zig"); _ = @import("behavior/bugs/4560.zig"); _ = @import("behavior/bugs/4769_a.zig"); _ = @import("behavior/bugs/4769_b.zig"); @@ -30,6 +33,9 @@ test { _ = @import("behavior/underscore.zig"); _ = @import("behavior/usingnamespace.zig"); _ = @import("behavior/while.zig"); + _ = @import("behavior/this.zig"); + _ = @import("behavior/member_func.zig"); + _ = @import("behavior/translate_c_macros.zig"); if (builtin.object_format != .c) { // Tests that pass for stage1 and stage2 but not the C backend. @@ -38,14 +44,11 @@ test { _ = @import("behavior/atomics.zig"); _ = @import("behavior/basic_llvm.zig"); _ = @import("behavior/bugs/394.zig"); - _ = @import("behavior/bugs/624.zig"); _ = @import("behavior/bugs/1277.zig"); _ = @import("behavior/bugs/1500.zig"); _ = @import("behavior/bugs/1741.zig"); _ = @import("behavior/bugs/2006.zig"); - _ = @import("behavior/bugs/2692.zig"); _ = @import("behavior/bugs/3112.zig"); - _ = @import("behavior/bugs/3586.zig"); _ = @import("behavior/cast.zig"); _ = @import("behavior/error.zig"); _ = @import("behavior/eval.zig"); @@ -55,7 +58,6 @@ test { _ = @import("behavior/generics.zig"); _ = @import("behavior/math.zig"); _ = @import("behavior/maximum_minimum.zig"); - _ = @import("behavior/member_func.zig"); _ = @import("behavior/null_llvm.zig"); _ = @import("behavior/optional.zig"); _ = @import("behavior/pointers.zig"); @@ -65,8 +67,6 @@ test { _ = @import("behavior/slice.zig"); _ = @import("behavior/struct_llvm.zig"); _ = @import("behavior/switch.zig"); - _ = @import("behavior/this.zig"); - _ = @import("behavior/translate_c_macros.zig"); _ = @import("behavior/union.zig"); _ = @import("behavior/widening.zig");