authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-26 15:24:24-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-26 15:24:24-04:00
logae65c236c55a1e22e63bb9f03c1ff925268646f1
tree989ebc145c52256ad2bca5a454f7fa2da278a529
parentd316f704501ff7fc809fdfb082226031ef875046
signaturelock-open Commit is signed but in an unrecognized format.

fix regression with global variable assignment...

...with optional unwrapping with var initialized to undefined

3 files changed, 38 insertions(+), 23 deletions(-)

src/codegen.cpp+2
...@@ -3527,6 +3527,8 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir...@@ -3527,6 +3527,8 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
3527}3527}
35283528
3529static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {3529static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
3530 if (instruction->base.value.special != ConstValSpecialRuntime)
3531 return ir_llvm_value(g, &instruction->base);
3530 ZigVar *var = instruction->var;3532 ZigVar *var = instruction->var;
3531 if (type_has_bits(var->var_type)) {3533 if (type_has_bits(var->var_type)) {
3532 assert(var->value_ref);3534 assert(var->value_ref);
src/ir.cpp+21-23
...@@ -15259,23 +15259,25 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,...@@ -15259,23 +15259,25 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
1525915259
15260 bool comptime_var_mem = ir_get_var_is_comptime(var);15260 bool comptime_var_mem = ir_get_var_is_comptime(var);
15261 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern;15261 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern;
15262 bool is_const = var->src_is_const;
15263 bool is_volatile = false;15262 bool is_volatile = false;
1526415263
15264 IrInstruction *result = ir_build_var_ptr(&ira->new_irb,
15265 instruction->scope, instruction->source_node, var);
15266 result->value.type = get_pointer_to_type_extra(ira->codegen, var->var_type,
15267 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false);
15268
15265 if (linkage_makes_it_runtime)15269 if (linkage_makes_it_runtime)
15266 goto no_mem_slot;15270 goto no_mem_slot;
1526715271
15268 if (value_is_comptime(var->const_value)) {15272 if (value_is_comptime(var->const_value)) {
15269 mem_slot = var->const_value;15273 mem_slot = var->const_value;
15270 } else {15274 } else if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) {
15271 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) {15275 // find the relevant exec_context
15272 // find the relevant exec_context15276 assert(var->owner_exec != nullptr);
15273 assert(var->owner_exec != nullptr);15277 assert(var->owner_exec->analysis != nullptr);
15274 assert(var->owner_exec->analysis != nullptr);15278 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context;
15275 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context;15279 assert(var->mem_slot_index < exec_context->mem_slot_list.length);
15276 assert(var->mem_slot_index < exec_context->mem_slot_list.length);15280 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index);
15277 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index);
15278 }
15279 }15281 }
1528015282
15281 if (mem_slot != nullptr) {15283 if (mem_slot != nullptr) {
...@@ -15294,8 +15296,11 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,...@@ -15294,8 +15296,11 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
15294 assert(!comptime_var_mem);15296 assert(!comptime_var_mem);
15295 ptr_mut = ConstPtrMutRuntimeVar;15297 ptr_mut = ConstPtrMutRuntimeVar;
15296 }15298 }
15297 return ir_get_const_ptr(ira, instruction, mem_slot, var->var_type,15299 result->value.special = ConstValSpecialStatic;
15298 ptr_mut, is_const, is_volatile, var->align_bytes);15300 result->value.data.x_ptr.mut = ptr_mut;
15301 result->value.data.x_ptr.special = ConstPtrSpecialRef;
15302 result->value.data.x_ptr.data.ref.pointee = mem_slot;
15303 return result;
15299 }15304 }
15300 }15305 }
15301 zig_unreachable();15306 zig_unreachable();
...@@ -15303,15 +15308,10 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,...@@ -15303,15 +15308,10 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
1530315308
15304no_mem_slot:15309no_mem_slot:
1530515310
15306 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb,
15307 instruction->scope, instruction->source_node, var);
15308 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->var_type,
15309 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false);
15310
15311 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);15311 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);
15312 var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack;15312 result->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack;
1531315313
15314 return var_ptr_instruction;15314 return result;
15315}15315}
1531615316
15317// This function is called when a comptime value becomes accessible at runtime.15317// This function is called when a comptime value becomes accessible at runtime.
...@@ -17317,8 +17317,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_...@@ -17317,8 +17317,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
17317 case TldIdCompTime:17317 case TldIdCompTime:
17318 case TldIdUsingNamespace:17318 case TldIdUsingNamespace:
17319 zig_unreachable();17319 zig_unreachable();
17320 case TldIdVar:17320 case TldIdVar: {
17321 {
17322 TldVar *tld_var = (TldVar *)tld;17321 TldVar *tld_var = (TldVar *)tld;
17323 ZigVar *var = tld_var->var;17322 ZigVar *var = tld_var->var;
17324 if (var == nullptr) {17323 if (var == nullptr) {
...@@ -17330,8 +17329,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_...@@ -17330,8 +17329,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
1733017329
17331 return ir_get_var_ptr(ira, source_instruction, var);17330 return ir_get_var_ptr(ira, source_instruction, var);
17332 }17331 }
17333 case TldIdFn:17332 case TldIdFn: {
17334 {
17335 TldFn *tld_fn = (TldFn *)tld;17333 TldFn *tld_fn = (TldFn *)tld;
17336 ZigFn *fn_entry = tld_fn->fn_entry;17334 ZigFn *fn_entry = tld_fn->fn_entry;
17337 assert(fn_entry->type_entry);17335 assert(fn_entry->type_entry);
test/stage1/behavior/misc.zig+15
...@@ -706,3 +706,18 @@ test "result location zero sized array inside struct field implicit cast to slic...@@ -706,3 +706,18 @@ test "result location zero sized array inside struct field implicit cast to slic
706 var foo = E{ .entries = [_]u32{} };706 var foo = E{ .entries = [_]u32{} };
707 expect(foo.entries.len == 0);707 expect(foo.entries.len == 0);
708}708}
709
710var global_foo: *i32 = undefined;
711
712test "global variable assignment with optional unwrapping with var initialized to undefined" {
713 const S = struct {
714 var data: i32 = 1234;
715 fn foo() ?*i32 {
716 return &data;
717 }
718 };
719 global_foo = S.foo() orelse {
720 @panic("bad");
721 };
722 expect(global_foo.* == 1234);
723}