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
41134113static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
41144114 IrInstructionStructFieldPtr *instruction)
41154115{
4116 Error err;
4117
41164118 if (instruction->base.value.special != ConstValSpecialRuntime)
41174119 return nullptr;
41184120
......@@ -4130,6 +4132,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
41304132 return struct_ptr;
41314133 }
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
41334140 assert(field->gen_index != SIZE_MAX);
41344141 return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
41354142}
test/stage1/behavior/struct.zig+33
......@@ -599,3 +599,36 @@ test "extern fn returns struct by value" {
599599 S.entry();
600600 comptime S.entry();
601601}
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}