diff --git a/src/ir.cpp b/src/ir.cpp index 90e8f1ed8f..1cfdb4544d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16848,11 +16848,30 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) { ZigType *type_entry = value->value.type; - if (type_entry->id == ZigTypeIdOptional) { + if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { if (instr_is_comptime(value)) { - ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad); - if (!maybe_val) + ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); + if (c_ptr_val == nullptr) return ira->codegen->invalid_instruction; + if (c_ptr_val->special == ConstValSpecialUndef) + return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); + bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || + (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && + c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); + return ir_const_bool(ira, source_inst, !is_null); + } + + IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, + source_inst->scope, source_inst->source_node, value); + result->value.type = ira->codegen->builtin_types.entry_bool; + return result; + } else if (type_entry->id == ZigTypeIdOptional) { + if (instr_is_comptime(value)) { + ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefOk); + if (maybe_val == nullptr) + return ira->codegen->invalid_instruction; + if (maybe_val->special == ConstValSpecialUndef) + return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); } diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig index 1a7616e757..50b36fe583 100644 --- a/test/stage1/behavior/pointers.zig +++ b/test/stage1/behavior/pointers.zig @@ -157,12 +157,20 @@ test "assign null directly to C pointer and test null equality" { expect(null == x); expect(!(x != null)); expect(!(null != x)); + if (x) |same_x| { + @panic("fail"); + } + var otherx: i32 = undefined; + expect((x orelse &otherx) == &otherx); const y: [*c]i32 = null; comptime expect(y == null); comptime expect(null == y); comptime expect(!(y != null)); comptime expect(!(null != y)); + if (y) |same_y| @panic("fail"); + const othery: i32 = undefined; + comptime expect((y orelse &othery) == &othery); var n: i32 = 1234; var x1: [*c]i32 = &n; @@ -171,6 +179,12 @@ test "assign null directly to C pointer and test null equality" { expect(x1 != null); expect(null != x1); expect(x1.?.* == 1234); + if (x1) |same_x1| { + expect(same_x1.* == 1234); + } else { + @panic("fail"); + } + expect((x1 orelse &otherx) == x1); const nc: i32 = 1234; const y1: [*c]const i32 = &nc; @@ -179,4 +193,10 @@ test "assign null directly to C pointer and test null equality" { comptime expect(y1 != null); comptime expect(null != y1); comptime expect(y1.?.* == 1234); + if (y1) |same_y1| { + expect(same_y1.* == 1234); + } else { + @compileError("fail"); + } + comptime expect((y1 orelse &othery) == y1); }