zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit be17a4b6c1be11eb4b75db1972a38fc50875ebed (tree)
parent e673d865fb2dfa6588505d572765ea8c5b4470ee
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Tue,  3 Sep 2019 14:51:34 -0400

fix compiler crash in struct field pointers

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

Diffstat:
Msrc/codegen.cpp | 7+++++++
Mtest/stage1/behavior/struct.zig | 33+++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/src/codegen.cpp b/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, ""); } diff --git a/test/stage1/behavior/struct.zig b/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(); +}