zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 29f531bec9fd8cedc0e0da0981d1a71bb3348641 (tree)
parent c61fbe77c8689709aac4adfa78b27ed7ea53ee5f
Author: Daniele Cocca <daniele.cocca@gmail.com>
Date:   Sat, 13 Nov 2021 02:44:16 +0000

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.

Diffstat:
Msrc/codegen/c.zig | 39+++++++++++++++++++++++++++++++++++++++
Mtest/behavior.zig | 12++++++------
2 files changed, 45 insertions(+), 6 deletions(-)

diff --git 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 @@ -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");