authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-28 17:05:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-28 17:05:17-07:00
logc59ee3157f5a7fb5c6110422ea8215601285ea28
tree6c241c1adb150f18ff109d5e14aba7d46bf90cb9
parent9ed955e5ca755ddfa7ee4cb3c34f6373cb1bf6a8

C backend: fix ptrtoint and wrap_errunion_err


4 files changed, 45 insertions(+), 24 deletions(-)

src/codegen/c.zig+25-7
......@@ -1117,9 +1117,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
11171117 .float_to_int,
11181118 .fptrunc,
11191119 .fpext,
1120 .ptrtoint,
11211120 => try airSimpleCast(f, inst),
11221121
1122 .ptrtoint => try airPtrToInt(f, inst),
1123
11231124 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),
11241125 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),
11251126 .atomic_store_release => try airAtomicStore(f, inst, toMemoryOrder(.Release)),
......@@ -2264,15 +2265,18 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
22642265 return local;
22652266}
22662267fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
2267 if (f.liveness.isUnused(inst))
2268 return CValue.none;
2268 if (f.liveness.isUnused(inst)) return CValue.none;
22692269
22702270 const writer = f.object.writer();
22712271 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
22722272 const operand = try f.resolveInst(ty_op.operand);
2273 const err_un_ty = f.air.typeOfIndex(inst);
2274 const payload_ty = err_un_ty.errorUnionPayload();
2275 if (!payload_ty.hasCodeGenBits()) {
2276 return operand;
2277 }
22732278
2274 const inst_ty = f.air.typeOfIndex(inst);
2275 const local = try f.allocLocal(inst_ty, .Const);
2279 const local = try f.allocLocal(err_un_ty, .Const);
22762280 try writer.writeAll(" = { .error = ");
22772281 try f.writeCValue(writer, operand);
22782282 try writer.writeAll(" };\n");
......@@ -2343,8 +2347,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
23432347/// Emits a local variable with the result type and initializes it
23442348/// with the operand.
23452349fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {
2346 if (f.liveness.isUnused(inst))
2347 return CValue.none;
2350 if (f.liveness.isUnused(inst)) return CValue.none;
23482351
23492352 const inst_ty = f.air.typeOfIndex(inst);
23502353 const local = try f.allocLocal(inst_ty, .Const);
......@@ -2358,6 +2361,21 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {
23582361 return local;
23592362}
23602363
2364fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue {
2365 if (f.liveness.isUnused(inst)) return CValue.none;
2366
2367 const inst_ty = f.air.typeOfIndex(inst);
2368 const local = try f.allocLocal(inst_ty, .Const);
2369 const un_op = f.air.instructions.items(.data)[inst].un_op;
2370 const writer = f.object.writer();
2371 const operand = try f.resolveInst(un_op);
2372
2373 try writer.writeAll(" = ");
2374 try f.writeCValue(writer, operand);
2375 try writer.writeAll(";\n");
2376 return local;
2377}
2378
23612379fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue {
23622380 if (f.liveness.isUnused(inst)) return CValue.none;
23632381
test/behavior.zig+2-2
......@@ -2,7 +2,7 @@ const builtin = @import("builtin");
22
33test {
44 // Tests that pass for stage1, stage2, and the C backend.
5 {}
5 _ = @import("behavior/if.zig");
66
77 if (builtin.object_format != .c) {
88 // Tests that pass for stage1 and stage2 but not the C backend.
......@@ -43,7 +43,7 @@ test {
4343 _ = @import("behavior/generics.zig");
4444 _ = @import("behavior/hasdecl.zig");
4545 _ = @import("behavior/hasfield.zig");
46 _ = @import("behavior/if.zig");
46 _ = @import("behavior/if_llvm.zig");
4747 _ = @import("behavior/math.zig");
4848 _ = @import("behavior/maximum_minimum.zig");
4949 _ = @import("behavior/member_func.zig");
test/behavior/if.zig-15
......@@ -73,18 +73,3 @@ test "const result loc, runtime if cond, else unreachable" {
7373 const x = if (t) Num.Two else unreachable;
7474 try expect(x == .Two);
7575}
76
77test "if copies its payload" {
78 const S = struct {
79 fn doTheTest() !void {
80 var tmp: ?i32 = 10;
81 if (tmp) |value| {
82 // Modify the original variable
83 tmp = null;
84 try expect(value == 10);
85 } else unreachable;
86 }
87 };
88 try S.doTheTest();
89 comptime try S.doTheTest();
90}
test/behavior/if_llvm.zig created+18
......@@ -0,0 +1,18 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
4
5test "if copies its payload" {
6 const S = struct {
7 fn doTheTest() !void {
8 var tmp: ?i32 = 10;
9 if (tmp) |value| {
10 // Modify the original variable
11 tmp = null;
12 try expect(value == 10);
13 } else unreachable;
14 }
15 };
16 try S.doTheTest();
17 comptime try S.doTheTest();
18}