| author | |
| committer | |
| log | be17a4b6c1be11eb4b75db1972a38fc50875ebed |
| tree | ddb2dd8fce64440288d58af58873ba50f818f5d8 |
| parent | e673d865fb2dfa6588505d572765ea8c5b4470ee |
| signature |
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 | 4113 | static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable, |
| 4114 | 4114 | IrInstructionStructFieldPtr *instruction) |
| 4115 | 4115 | { |
| 4116 | Error err; | |
| 4117 | ||
| 4116 | 4118 | if (instruction->base.value.special != ConstValSpecialRuntime) |
| 4117 | 4119 | return nullptr; |
| 4118 | 4120 | |
| ... | ... | @@ -4130,6 +4132,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa |
| 4130 | 4132 | return struct_ptr; |
| 4131 | 4133 | } |
| 4132 | 4134 | |
| 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 | 4140 | assert(field->gen_index != SIZE_MAX); |
| 4134 | 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 | 599 | S.entry(); |
| 600 | 600 | comptime S.entry(); |
| 601 | 601 | } |
| 602 | ||
| 603 | test "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 | } |