authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-22 13:37:13-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-22 13:37:13-04:00
log3c4b255a3c184e43e70bb8380f6e388c5594f149
tree9d0bbd16d7e46f2dee328d8ebf9886350d2d0d08
parent65997f816bd7aa48f585c61e4d966253d9947ec5
signaturelock-open Commit is signed but in an unrecognized format.

fix implicit cast fn call result to optional in field result


2 files changed, 33 insertions(+), 8 deletions(-)

src/ir.cpp+10-8
...@@ -187,7 +187,7 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc...@@ -187,7 +187,7 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc
187static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,187static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
188 ZigType *dest_type);188 ZigType *dest_type);
189static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,189static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool non_null_comptime);190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);
191static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,191static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
192 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);192 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);
193static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,193static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
...@@ -15012,7 +15012,7 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {...@@ -15012,7 +15012,7 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {
1501215012
15013// when calling this function, at the callsite must check for result type noreturn and propagate it up15013// when calling this function, at the callsite must check for result type noreturn and propagate it up
15014static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,15014static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15015 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool non_null_comptime)15015 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime)
15016{15016{
15017 Error err;15017 Error err;
15018 if (result_loc->resolved_loc != nullptr) {15018 if (result_loc->resolved_loc != nullptr) {
...@@ -15108,7 +15108,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15108,7 +15108,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1510815108
15109 if (peer_parent->peers.length == 1) {15109 if (peer_parent->peers.length == 1) {
15110 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,15110 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15111 value_type, value, false, non_null_comptime);15111 value_type, value, force_runtime, non_null_comptime);
15112 result_peer->suspend_pos.basic_block_index = SIZE_MAX;15112 result_peer->suspend_pos.basic_block_index = SIZE_MAX;
15113 result_peer->suspend_pos.instruction_index = SIZE_MAX;15113 result_peer->suspend_pos.instruction_index = SIZE_MAX;
15114 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||15114 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
...@@ -15128,7 +15128,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15128,7 +15128,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15128 if (peer_parent->skipped) {15128 if (peer_parent->skipped) {
15129 if (non_null_comptime) {15129 if (non_null_comptime) {
15130 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,15130 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15131 value_type, value, false, non_null_comptime);15131 value_type, value, force_runtime, non_null_comptime);
15132 }15132 }
15133 return nullptr;15133 return nullptr;
15134 }15134 }
...@@ -15146,7 +15146,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15146,7 +15146,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15146 }15146 }
1514715147
15148 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,15148 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15149 peer_parent->resolved_type, nullptr, false, non_null_comptime);15149 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime);
15150 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||15150 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15151 parent_result_loc->value.type->id == ZigTypeIdUnreachable)15151 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15152 {15152 {
...@@ -15196,7 +15196,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15196,7 +15196,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15196 }15196 }
1519715197
15198 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent,15198 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent,
15199 dest_type, bitcasted_value, false, non_null_comptime);15199 dest_type, bitcasted_value, force_runtime, non_null_comptime);
15200 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||15200 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15201 parent_result_loc->value.type->id == ZigTypeIdUnreachable)15201 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15202 {15202 {
...@@ -15228,11 +15228,13 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -15228,11 +15228,13 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
15228 bool non_null_comptime)15228 bool non_null_comptime)
15229{15229{
15230 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,15230 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
15231 value, non_null_comptime);15231 value, force_runtime, non_null_comptime);
15232 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))15232 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))
15233 return result_loc;15233 return result_loc;
1523415234
15235 if (force_runtime && result_loc_pass1->written && result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {15235 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) &&
15236 result_loc_pass1->written && result_loc->value.data.x_ptr.mut == ConstPtrMutInfer)
15237 {
15236 result_loc->value.special = ConstValSpecialRuntime;15238 result_loc->value.special = ConstValSpecialRuntime;
15237 }15239 }
1523815240
test/stage1/behavior/fn.zig+23
...@@ -205,3 +205,26 @@ test "extern struct with stdcallcc fn pointer" {...@@ -205,3 +205,26 @@ test "extern struct with stdcallcc fn pointer" {
205 s.ptr = S.foo;205 s.ptr = S.foo;
206 expect(s.ptr() == 1234);206 expect(s.ptr() == 1234);
207}207}
208
209test "implicit cast fn call result to optional in field result" {
210 const S = struct {
211 fn entry() void {
212 var x = Foo{
213 .field = optionalPtr(),
214 };
215 expect(x.field.?.* == 999);
216 }
217
218 const glob: i32 = 999;
219
220 fn optionalPtr() *const i32 {
221 return &glob;
222 }
223
224 const Foo = struct {
225 field: ?*const i32,
226 };
227 };
228 S.entry();
229 comptime S.entry();
230}