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 c00b0247bb052cb6541ef781bb98a9c0ce191fc8..e95a5a77ec861fdd70de5c149074f47b8547b8d8 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 9ef98bd7720dc727808b9b4c1bcb9361f0ceabb0..4f78a9d35a6857014567c75034a679746d313017 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"); -- 2.54.0