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...@@ -1117,9 +1117,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1117 .float_to_int,1117 .float_to_int,
1118 .fptrunc,1118 .fptrunc,
1119 .fpext,1119 .fpext,
1120 .ptrtoint,
1121 => try airSimpleCast(f, inst),1120 => try airSimpleCast(f, inst),
11221121
1122 .ptrtoint => try airPtrToInt(f, inst),
1123
1123 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),1124 .atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),
1124 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),1125 .atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),
1125 .atomic_store_release => try airAtomicStore(f, inst, toMemoryOrder(.Release)),1126 .atomic_store_release => try airAtomicStore(f, inst, toMemoryOrder(.Release)),
...@@ -2264,15 +2265,18 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2264,15 +2265,18 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
2264 return local;2265 return local;
2265}2266}
2266fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {2267fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
2267 if (f.liveness.isUnused(inst))2268 if (f.liveness.isUnused(inst)) return CValue.none;
2268 return CValue.none;
22692269
2270 const writer = f.object.writer();2270 const writer = f.object.writer();
2271 const ty_op = f.air.instructions.items(.data)[inst].ty_op;2271 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
2272 const operand = try f.resolveInst(ty_op.operand);2272 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);2279 const local = try f.allocLocal(err_un_ty, .Const);
2275 const local = try f.allocLocal(inst_ty, .Const);
2276 try writer.writeAll(" = { .error = ");2280 try writer.writeAll(" = { .error = ");
2277 try f.writeCValue(writer, operand);2281 try f.writeCValue(writer, operand);
2278 try writer.writeAll(" };\n");2282 try writer.writeAll(" };\n");
...@@ -2343,8 +2347,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2343,8 +2347,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
2343/// Emits a local variable with the result type and initializes it2347/// Emits a local variable with the result type and initializes it
2344/// with the operand.2348/// with the operand.
2345fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {2349fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {
2346 if (f.liveness.isUnused(inst))2350 if (f.liveness.isUnused(inst)) return CValue.none;
2347 return CValue.none;
23482351
2349 const inst_ty = f.air.typeOfIndex(inst);2352 const inst_ty = f.air.typeOfIndex(inst);
2350 const local = try f.allocLocal(inst_ty, .Const);2353 const local = try f.allocLocal(inst_ty, .Const);
...@@ -2358,6 +2361,21 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -2358,6 +2361,21 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue {
2358 return local;2361 return local;
2359}2362}
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
2361fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue {2379fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue {
2362 if (f.liveness.isUnused(inst)) return CValue.none;2380 if (f.liveness.isUnused(inst)) return CValue.none;
23632381
test/behavior.zig+2-2
...@@ -2,7 +2,7 @@ const builtin = @import("builtin");...@@ -2,7 +2,7 @@ const builtin = @import("builtin");
22
3test {3test {
4 // Tests that pass for stage1, stage2, and the C backend.4 // Tests that pass for stage1, stage2, and the C backend.
5 {}5 _ = @import("behavior/if.zig");
66
7 if (builtin.object_format != .c) {7 if (builtin.object_format != .c) {
8 // Tests that pass for stage1 and stage2 but not the C backend.8 // Tests that pass for stage1 and stage2 but not the C backend.
...@@ -43,7 +43,7 @@ test {...@@ -43,7 +43,7 @@ test {
43 _ = @import("behavior/generics.zig");43 _ = @import("behavior/generics.zig");
44 _ = @import("behavior/hasdecl.zig");44 _ = @import("behavior/hasdecl.zig");
45 _ = @import("behavior/hasfield.zig");45 _ = @import("behavior/hasfield.zig");
46 _ = @import("behavior/if.zig");46 _ = @import("behavior/if_llvm.zig");
47 _ = @import("behavior/math.zig");47 _ = @import("behavior/math.zig");
48 _ = @import("behavior/maximum_minimum.zig");48 _ = @import("behavior/maximum_minimum.zig");
49 _ = @import("behavior/member_func.zig");49 _ = @import("behavior/member_func.zig");
test/behavior/if.zig-15
...@@ -73,18 +73,3 @@ test "const result loc, runtime if cond, else unreachable" {...@@ -73,18 +73,3 @@ test "const result loc, runtime if cond, else unreachable" {
73 const x = if (t) Num.Two else unreachable;73 const x = if (t) Num.Two else unreachable;
74 try expect(x == .Two);74 try expect(x == .Two);
75}75}
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}