diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-28 17:05:17 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-28 17:05:17 -0700 |
| commit | c59ee3157f5a7fb5c6110422ea8215601285ea28 (patch) | |
| tree | 6c241c1adb150f18ff109d5e14aba7d46bf90cb9 | |
| parent | 9ed955e5ca755ddfa7ee4cb3c34f6373cb1bf6a8 (diff) | |
| download | zig-c59ee3157f5a7fb5c6110422ea8215601285ea28.tar.gz zig-c59ee3157f5a7fb5c6110422ea8215601285ea28.zip | |
C backend: fix ptrtoint and wrap_errunion_err
| -rw-r--r-- | src/codegen/c.zig | 32 | ||||
| -rw-r--r-- | test/behavior.zig | 4 | ||||
| -rw-r--r-- | test/behavior/if.zig | 15 | ||||
| -rw-r--r-- | test/behavior/if_llvm.zig | 18 |
4 files changed, 45 insertions, 24 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 139809aac2..64d8cf362d 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1117,9 +1117,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .float_to_int, .fptrunc, .fpext, - .ptrtoint, => try airSimpleCast(f, inst), + .ptrtoint => try airPtrToInt(f, inst), + .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)), .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)), .atomic_store_release => try airAtomicStore(f, inst, toMemoryOrder(.Release)), @@ -2264,15 +2265,18 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { return local; } fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { - if (f.liveness.isUnused(inst)) - return CValue.none; + if (f.liveness.isUnused(inst)) return CValue.none; const writer = f.object.writer(); const ty_op = f.air.instructions.items(.data)[inst].ty_op; const operand = try f.resolveInst(ty_op.operand); + const err_un_ty = f.air.typeOfIndex(inst); + const payload_ty = err_un_ty.errorUnionPayload(); + if (!payload_ty.hasCodeGenBits()) { + return operand; + } - const inst_ty = f.air.typeOfIndex(inst); - const local = try f.allocLocal(inst_ty, .Const); + const local = try f.allocLocal(err_un_ty, .Const); try writer.writeAll(" = { .error = "); try f.writeCValue(writer, operand); try writer.writeAll(" };\n"); @@ -2343,8 +2347,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { /// Emits a local variable with the result type and initializes it /// with the operand. fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue { - if (f.liveness.isUnused(inst)) - return CValue.none; + if (f.liveness.isUnused(inst)) return CValue.none; const inst_ty = f.air.typeOfIndex(inst); const local = try f.allocLocal(inst_ty, .Const); @@ -2358,6 +2361,21 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue { return local; } +fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; + + const inst_ty = f.air.typeOfIndex(inst); + const local = try f.allocLocal(inst_ty, .Const); + const un_op = f.air.instructions.items(.data)[inst].un_op; + const writer = f.object.writer(); + const operand = try f.resolveInst(un_op); + + try writer.writeAll(" = "); + try f.writeCValue(writer, operand); + try writer.writeAll(";\n"); + return local; +} + fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue { if (f.liveness.isUnused(inst)) return CValue.none; diff --git a/test/behavior.zig b/test/behavior.zig index 136245baa1..30b76b00bf 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -2,7 +2,7 @@ const builtin = @import("builtin"); test { // Tests that pass for stage1, stage2, and the C backend. - {} + _ = @import("behavior/if.zig"); if (builtin.object_format != .c) { // Tests that pass for stage1 and stage2 but not the C backend. @@ -43,7 +43,7 @@ test { _ = @import("behavior/generics.zig"); _ = @import("behavior/hasdecl.zig"); _ = @import("behavior/hasfield.zig"); - _ = @import("behavior/if.zig"); + _ = @import("behavior/if_llvm.zig"); _ = @import("behavior/math.zig"); _ = @import("behavior/maximum_minimum.zig"); _ = @import("behavior/member_func.zig"); diff --git a/test/behavior/if.zig b/test/behavior/if.zig index e907f288de..a1f722d827 100644 --- a/test/behavior/if.zig +++ b/test/behavior/if.zig @@ -73,18 +73,3 @@ test "const result loc, runtime if cond, else unreachable" { const x = if (t) Num.Two else unreachable; try expect(x == .Two); } - -test "if copies its payload" { - const S = struct { - fn doTheTest() !void { - var tmp: ?i32 = 10; - if (tmp) |value| { - // Modify the original variable - tmp = null; - try expect(value == 10); - } else unreachable; - } - }; - try S.doTheTest(); - comptime try S.doTheTest(); -} diff --git a/test/behavior/if_llvm.zig b/test/behavior/if_llvm.zig new file mode 100644 index 0000000000..e6773d90c0 --- /dev/null +++ b/test/behavior/if_llvm.zig @@ -0,0 +1,18 @@ +const std = @import("std"); +const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; + +test "if copies its payload" { + const S = struct { + fn doTheTest() !void { + var tmp: ?i32 = 10; + if (tmp) |value| { + // Modify the original variable + tmp = null; + try expect(value == 10); + } else unreachable; + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} |
