| author | |
| committer | |
| log | a4aee8b24d321aa4c7a791d20500e5847a08b587 |
| tree | b628bc75fc9e41eecff4e5242e0b2367f4d3aa33 |
| parent | 0099583bd3eccbecbb827edbde46a40cf821fecf |
| signature |
See #19672 files changed, 42 insertions(+), 3 deletions(-)
src/ir.cpp+22-3| ... | ... | @@ -16848,11 +16848,30 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| 16848 | 16848 | static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) { |
| 16849 | 16849 | ZigType *type_entry = value->value.type; |
| 16850 | 16850 | |
| 16851 | if (type_entry->id == ZigTypeIdOptional) { | |
| 16851 | if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { | |
| 16852 | 16852 | if (instr_is_comptime(value)) { |
| 16853 | ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad); | |
| 16854 | if (!maybe_val) | |
| 16853 | ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); | |
| 16854 | if (c_ptr_val == nullptr) | |
| 16855 | return ira->codegen->invalid_instruction; | |
| 16856 | if (c_ptr_val->special == ConstValSpecialUndef) | |
| 16857 | return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); | |
| 16858 | bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || | |
| 16859 | (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && | |
| 16860 | c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); | |
| 16861 | return ir_const_bool(ira, source_inst, !is_null); | |
| 16862 | } | |
| 16863 | ||
| 16864 | IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, | |
| 16865 | source_inst->scope, source_inst->source_node, value); | |
| 16866 | result->value.type = ira->codegen->builtin_types.entry_bool; | |
| 16867 | return result; | |
| 16868 | } else if (type_entry->id == ZigTypeIdOptional) { | |
| 16869 | if (instr_is_comptime(value)) { | |
| 16870 | ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefOk); | |
| 16871 | if (maybe_val == nullptr) | |
| 16855 | 16872 | return ira->codegen->invalid_instruction; |
| 16873 | if (maybe_val->special == ConstValSpecialUndef) | |
| 16874 | return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); | |
| 16856 | 16875 | |
| 16857 | 16876 | return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); |
| 16858 | 16877 | } |
test/stage1/behavior/pointers.zig+20| ... | ... | @@ -157,12 +157,20 @@ test "assign null directly to C pointer and test null equality" { |
| 157 | 157 | expect(null == x); |
| 158 | 158 | expect(!(x != null)); |
| 159 | 159 | expect(!(null != x)); |
| 160 | if (x) |same_x| { | |
| 161 | @panic("fail"); | |
| 162 | } | |
| 163 | var otherx: i32 = undefined; | |
| 164 | expect((x orelse &otherx) == &otherx); | |
| 160 | 165 | |
| 161 | 166 | const y: [*c]i32 = null; |
| 162 | 167 | comptime expect(y == null); |
| 163 | 168 | comptime expect(null == y); |
| 164 | 169 | comptime expect(!(y != null)); |
| 165 | 170 | comptime expect(!(null != y)); |
| 171 | if (y) |same_y| @panic("fail"); | |
| 172 | const othery: i32 = undefined; | |
| 173 | comptime expect((y orelse &othery) == &othery); | |
| 166 | 174 | |
| 167 | 175 | var n: i32 = 1234; |
| 168 | 176 | var x1: [*c]i32 = &n; |
| ... | ... | @@ -171,6 +179,12 @@ test "assign null directly to C pointer and test null equality" { |
| 171 | 179 | expect(x1 != null); |
| 172 | 180 | expect(null != x1); |
| 173 | 181 | expect(x1.?.* == 1234); |
| 182 | if (x1) |same_x1| { | |
| 183 | expect(same_x1.* == 1234); | |
| 184 | } else { | |
| 185 | @panic("fail"); | |
| 186 | } | |
| 187 | expect((x1 orelse &otherx) == x1); | |
| 174 | 188 | |
| 175 | 189 | const nc: i32 = 1234; |
| 176 | 190 | const y1: [*c]const i32 = &nc; |
| ... | ... | @@ -179,4 +193,10 @@ test "assign null directly to C pointer and test null equality" { |
| 179 | 193 | comptime expect(y1 != null); |
| 180 | 194 | comptime expect(null != y1); |
| 181 | 195 | comptime expect(y1.?.* == 1234); |
| 196 | if (y1) |same_y1| { | |
| 197 | expect(same_y1.* == 1234); | |
| 198 | } else { | |
| 199 | @compileError("fail"); | |
| 200 | } | |
| 201 | comptime expect((y1 orelse &othery) == y1); | |
| 182 | 202 | } |