From 6467ef6d3b5648d47c13b877d3d4fe6a5b5efb7d Mon Sep 17 00:00:00 2001 From: jacob gw Date: Mon, 1 Mar 2021 11:25:50 -0500 Subject: [PATCH] cbe: add error comparison support --- src/codegen.zig | 2 ++ src/type.zig | 2 +- src/zir_sema.zig | 3 ++- test/stage2/cbe.zig | 56 +++++++++++++++++++++++++++++---------------- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/codegen.zig b/src/codegen.zig index c3cd64cf73..cfe605b567 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -2237,6 +2237,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { // No side effects, so if it's unreferenced, do nothing. if (inst.base.isUnused()) return MCValue{ .dead = {} }; + if (inst.lhs.ty.zigTypeTag() == .ErrorSet or inst.rhs.ty.zigTypeTag() == .ErrorSet) + return self.fail(inst.base.src, "TODO implement cmp for errors", .{}); switch (arch) { .x86_64 => { try self.code.ensureCapacity(self.code.items.len + 8); diff --git a/src/type.zig b/src/type.zig index 50d55a0c54..c3a99bb184 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1663,6 +1663,7 @@ pub const Type = extern union { .Int, .Float, .ErrorSet, + .ErrorUnion, .Enum, .Frame, .AnyFrame, @@ -1687,7 +1688,6 @@ pub const Type = extern union { }, .Pointer, .Array => ty = ty.elemType(), - .ErrorUnion => @panic("TODO fn isValidVarType"), .Fn => @panic("TODO fn isValidVarType"), .Struct => @panic("TODO struct isValidVarType"), .Union => @panic("TODO union isValidVarType"), diff --git a/src/zir_sema.zig b/src/zir_sema.zig index 9cbdfd07dd..a1b79879b8 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -2326,7 +2326,8 @@ fn zirCmp( return mod.constBool(scope, inst.base.src, std.mem.eql(u8, lval.castTag(.@"error").?.data.name, rval.castTag(.@"error").?.data.name) == (op == .eq)); } } - return mod.fail(scope, inst.base.src, "TODO implement equality comparison between runtime errors", .{}); + const b = try mod.requireRuntimeBlock(scope, inst.base.src); + return mod.addBinOp(b, inst.base.src, Type.initTag(.bool), if (op == .eq) .cmp_eq else .cmp_neq, lhs, rhs); } else if (lhs.ty.isNumeric() and rhs.ty.isNumeric()) { // This operation allows any combination of integer and float types, regardless of the // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig index ba679f49a0..1487b15e12 100644 --- a/test/stage2/cbe.zig +++ b/test/stage2/cbe.zig @@ -244,30 +244,46 @@ pub fn addCases(ctx: *TestContext) !void { \\} , ""); } + //{ + // var case = ctx.exeFromCompiledC("optionals", .{}); + + // // Simple while loop + // case.addCompareOutput( + // \\export fn main() c_int { + // \\ var count: c_int = 0; + // \\ var opt_ptr: ?*c_int = &count; + // \\ while (opt_ptr) |_| : (count += 1) { + // \\ if (count == 4) opt_ptr = null; + // \\ } + // \\ return count - 5; + // \\} + // , ""); + + // // Same with non pointer optionals + // case.addCompareOutput( + // \\export fn main() c_int { + // \\ var count: c_int = 0; + // \\ var opt_ptr: ?c_int = count; + // \\ while (opt_ptr) |_| : (count += 1) { + // \\ if (count == 4) opt_ptr = null; + // \\ } + // \\ return count - 5; + // \\} + // , ""); + //} { - var case = ctx.exeFromCompiledC("optionals", .{}); - - // Simple while loop + var case = ctx.exeFromCompiledC("errors", .{}); case.addCompareOutput( \\export fn main() c_int { - \\ var count: c_int = 0; - \\ var opt_ptr: ?*c_int = &count; - \\ while (opt_ptr) |_| : (count += 1) { - \\ if (count == 4) opt_ptr = null; - \\ } - \\ return count - 5; + \\ var e1 = error.Foo; + \\ var e2 = error.Bar; + \\ assert(e1 != e2); + \\ assert(e1 == error.Foo); + \\ assert(e2 == error.Bar); + \\ return 0; \\} - , ""); - - // Same with non pointer optionals - case.addCompareOutput( - \\export fn main() c_int { - \\ var count: c_int = 0; - \\ var opt_ptr: ?c_int = count; - \\ while (opt_ptr) |_| : (count += 1) { - \\ if (count == 4) opt_ptr = null; - \\ } - \\ return count - 5; + \\fn assert(b: bool) void { + \\ if (!b) unreachable; \\} , ""); }