authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-03 14:51:34-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-03 14:51:34-04:00
logbe17a4b6c1be11eb4b75db1972a38fc50875ebed
treeddb2dd8fce64440288d58af58873ba50f818f5d8
parente673d865fb2dfa6588505d572765ea8c5b4470ee
signaturelock-open Commit is signed but in an unrecognized format.

fix compiler crash in struct field pointers

when the llvm type has not been fully analyzed. This is a regression from lazy values.

2 files changed, 40 insertions(+), 0 deletions(-)

src/codegen.cpp+7
...@@ -4113,6 +4113,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -4113,6 +4113,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
4113static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,4113static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
4114 IrInstructionStructFieldPtr *instruction)4114 IrInstructionStructFieldPtr *instruction)
4115{4115{
4116 Error err;
4117
4116 if (instruction->base.value.special != ConstValSpecialRuntime)4118 if (instruction->base.value.special != ConstValSpecialRuntime)
4117 return nullptr;4119 return nullptr;
41184120
...@@ -4130,6 +4132,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa...@@ -4130,6 +4132,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
4130 return struct_ptr;4132 return struct_ptr;
4131 }4133 }
41324134
4135 ZigType *struct_type = (struct_ptr_type->id == ZigTypeIdPointer) ?
4136 struct_ptr_type->data.pointer.child_type : struct_ptr_type;
4137 if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull)))
4138 report_errors_and_exit(g);
4139
4133 assert(field->gen_index != SIZE_MAX);4140 assert(field->gen_index != SIZE_MAX);
4134 return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");4141 return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
4135}4142}
test/stage1/behavior/struct.zig+33
...@@ -599,3 +599,36 @@ test "extern fn returns struct by value" {...@@ -599,3 +599,36 @@ test "extern fn returns struct by value" {
599 S.entry();599 S.entry();
600 comptime S.entry();600 comptime S.entry();
601}601}
602
603test "for loop over pointers to struct, getting field from struct pointer" {
604 const S = struct {
605 const Foo = struct {
606 name: []const u8,
607 };
608
609 var ok = true;
610
611 fn eql(a: []const u8) bool {
612 return true;
613 }
614
615 const ArrayList = struct {
616 fn toSlice(self: *ArrayList) []*Foo {
617 return ([*]*Foo)(undefined)[0..0];
618 }
619 };
620
621 fn doTheTest() void {
622 var objects: ArrayList = undefined;
623
624 for (objects.toSlice()) |obj| {
625 if (eql(obj.name)) {
626 ok = false;
627 }
628 }
629
630 expect(ok);
631 }
632 };
633 S.doTheTest();
634}