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,
1684816848static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {
1684916849 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) {
1685216852 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)
1685516872 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
1685716876 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val));
1685816877 }
test/stage1/behavior/pointers.zig+20
......@@ -157,12 +157,20 @@ test "assign null directly to C pointer and test null equality" {
157157 expect(null == x);
158158 expect(!(x != null));
159159 expect(!(null != x));
160 if (x) |same_x| {
161 @panic("fail");
162 }
163 var otherx: i32 = undefined;
164 expect((x orelse &otherx) == &otherx);
160165
161166 const y: [*c]i32 = null;
162167 comptime expect(y == null);
163168 comptime expect(null == y);
164169 comptime expect(!(y != null));
165170 comptime expect(!(null != y));
171 if (y) |same_y| @panic("fail");
172 const othery: i32 = undefined;
173 comptime expect((y orelse &othery) == &othery);
166174
167175 var n: i32 = 1234;
168176 var x1: [*c]i32 = &n;
......@@ -171,6 +179,12 @@ test "assign null directly to C pointer and test null equality" {
171179 expect(x1 != null);
172180 expect(null != x1);
173181 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
175189 const nc: i32 = 1234;
176190 const y1: [*c]const i32 = &nc;
......@@ -179,4 +193,10 @@ test "assign null directly to C pointer and test null equality" {
179193 comptime expect(y1 != null);
180194 comptime expect(null != y1);
181195 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);
182202}