mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
C backend: fix ptrtoint and wrap_errunion_err
This commit is contained in:
parent
9ed955e5ca
commit
c59ee3157f
@ -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;
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
18
test/behavior/if_llvm.zig
Normal file
18
test/behavior/if_llvm.zig
Normal file
@ -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();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user