authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-08 18:36:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-08 18:47:14-04:00
loga4aee8b24d321aa4c7a791d20500e5847a08b587
treeb628bc75fc9e41eecff4e5242e0b2367f4d3aa33
parent0099583bd3eccbecbb827edbde46a40cf821fecf
signaturelock-open Commit is signed but in an unrecognized format.

C pointers support if and orelse

See #1967

2 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,11 +16848,30 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
16848static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {16848static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {
16849 ZigType *type_entry = value->value.type;16849 ZigType *type_entry = value->value.type;
1685016850
16851 if (type_entry->id == ZigTypeIdOptional) {16851 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) {
16852 if (instr_is_comptime(value)) {16852 if (instr_is_comptime(value)) {
16853 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad);16853 ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk);
16854 if (!maybe_val)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 return ira->codegen->invalid_instruction;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);
1685616875
16857 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val));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,12 +157,20 @@ test "assign null directly to C pointer and test null equality" {
157 expect(null == x);157 expect(null == x);
158 expect(!(x != null));158 expect(!(x != null));
159 expect(!(null != x));159 expect(!(null != x));
160 if (x) |same_x| {
161 @panic("fail");
162 }
163 var otherx: i32 = undefined;
164 expect((x orelse &otherx) == &otherx);
160165
161 const y: [*c]i32 = null;166 const y: [*c]i32 = null;
162 comptime expect(y == null);167 comptime expect(y == null);
163 comptime expect(null == y);168 comptime expect(null == y);
164 comptime expect(!(y != null));169 comptime expect(!(y != null));
165 comptime expect(!(null != y));170 comptime expect(!(null != y));
171 if (y) |same_y| @panic("fail");
172 const othery: i32 = undefined;
173 comptime expect((y orelse &othery) == &othery);
166174
167 var n: i32 = 1234;175 var n: i32 = 1234;
168 var x1: [*c]i32 = &n;176 var x1: [*c]i32 = &n;
...@@ -171,6 +179,12 @@ test "assign null directly to C pointer and test null equality" {...@@ -171,6 +179,12 @@ test "assign null directly to C pointer and test null equality" {
171 expect(x1 != null);179 expect(x1 != null);
172 expect(null != x1);180 expect(null != x1);
173 expect(x1.?.* == 1234);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);
174188
175 const nc: i32 = 1234;189 const nc: i32 = 1234;
176 const y1: [*c]const i32 = &nc;190 const y1: [*c]const i32 = &nc;
...@@ -179,4 +193,10 @@ test "assign null directly to C pointer and test null equality" {...@@ -179,4 +193,10 @@ test "assign null directly to C pointer and test null equality" {
179 comptime expect(y1 != null);193 comptime expect(y1 != null);
180 comptime expect(null != y1);194 comptime expect(null != y1);
181 comptime expect(y1.?.* == 1234);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}