Commit be17a4b6c1

Andrew Kelley <andrew@ziglang.org>
2019-09-03 20:51:34
fix compiler crash in struct field pointers
when the llvm type has not been fully analyzed. This is a regression from lazy values.
1 parent e673d86
Changed files (2)
src
test
stage1
behavior
src/codegen.cpp
@@ -4113,6 +4113,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
 static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
     IrInstructionStructFieldPtr *instruction)
 {
+    Error err;
+
     if (instruction->base.value.special != ConstValSpecialRuntime)
         return nullptr;
 
@@ -4130,6 +4132,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
         return struct_ptr;
     }
 
+    ZigType *struct_type = (struct_ptr_type->id == ZigTypeIdPointer) ?
+        struct_ptr_type->data.pointer.child_type : struct_ptr_type;
+    if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull)))
+        report_errors_and_exit(g);
+
     assert(field->gen_index != SIZE_MAX);
     return LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, "");
 }
test/stage1/behavior/struct.zig
@@ -599,3 +599,36 @@ test "extern fn returns struct by value" {
     S.entry();
     comptime S.entry();
 }
+
+test "for loop over pointers to struct, getting field from struct pointer" {
+    const S = struct {
+        const Foo = struct {
+            name: []const u8,
+        };
+
+        var ok = true;
+
+        fn eql(a: []const u8) bool {
+            return true;
+        }
+
+        const ArrayList = struct {
+            fn toSlice(self: *ArrayList) []*Foo {
+                return ([*]*Foo)(undefined)[0..0];
+            }
+        };
+
+        fn doTheTest() void {
+            var objects: ArrayList = undefined;
+
+            for (objects.toSlice()) |obj| {
+                if (eql(obj.name)) {
+                    ok = false;
+                }
+            }
+
+            expect(ok);
+        }
+    };
+    S.doTheTest();
+}