authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-02 02:11:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-03 04:25:14-04:00
logf894ec264b3e2af7e0f66a1ea76b4d06ac6c5e3a
tree1d94482218dd87a15abfcd73931dbf8c6dac0667
parent3a30b827414926dceccf606d6557e00f1cc6458d

codegen: fix global nested field_ptr


2 files changed, 39 insertions(+), 71 deletions(-)

src/codegen.zig+39-70
...@@ -374,66 +374,7 @@ pub fn generateSymbol(...@@ -374,66 +374,7 @@ pub fn generateSymbol(
374374
375 return Result.ok;375 return Result.ok;
376 },376 },
377 .field_ptr => {377 .field_ptr, .elem_ptr => return lowerParentPtr(
378 const field_ptr = typed_value.val.castTag(.field_ptr).?.data;
379 const container_ptr = field_ptr.container_ptr;
380
381 switch (container_ptr.tag()) {
382 .decl_ref => {
383 const decl_index = container_ptr.castTag(.decl_ref).?.data;
384 const decl = mod.declPtr(decl_index);
385 const addend = blk: {
386 switch (decl.ty.zigTypeTag()) {
387 .Struct => {
388 const addend = decl.ty.structFieldOffset(field_ptr.field_index, target);
389 break :blk @intCast(u32, addend);
390 },
391 .Pointer => {
392 assert(decl.ty.isSlice());
393 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
394 const addend = switch (field_ptr.field_index) {
395 0 => 0,
396 1 => decl.ty.slicePtrFieldType(&buf).abiSize(target),
397 else => unreachable,
398 };
399 break :blk @intCast(u32, addend);
400 },
401 else => return Result{
402 .fail = try ErrorMsg.create(
403 bin_file.allocator,
404 src_loc,
405 "TODO implement generateSymbol for pointer type value: '{s}'",
406 .{@tagName(typed_value.val.tag())},
407 ),
408 },
409 }
410 };
411 return lowerDeclRef(bin_file, src_loc, typed_value, decl_index, code, debug_output, .{
412 .parent_atom_index = reloc_info.parent_atom_index,
413 .addend = (reloc_info.addend orelse 0) + addend,
414 });
415 },
416 .field_ptr => {
417 switch (try generateSymbol(bin_file, src_loc, .{
418 .ty = typed_value.ty,
419 .val = container_ptr,
420 }, code, debug_output, reloc_info)) {
421 .ok => {},
422 .fail => |em| return Result{ .fail = em },
423 }
424 return Result.ok;
425 },
426 else => return Result{
427 .fail = try ErrorMsg.create(
428 bin_file.allocator,
429 src_loc,
430 "TODO implement generateSymbol for pointer type value: '{s}'",
431 .{@tagName(typed_value.val.tag())},
432 ),
433 },
434 }
435 },
436 .elem_ptr => return lowerParentPtr(
437 bin_file,378 bin_file,
438 src_loc,379 src_loc,
439 typed_value,380 typed_value,
...@@ -846,16 +787,12 @@ pub fn generateSymbol(...@@ -846,16 +787,12 @@ pub fn generateSymbol(
846 },787 },
847 else => unreachable,788 else => unreachable,
848 },789 },
849 else => |t| {790 else => |t| return Result{ .fail = try ErrorMsg.create(
850 return Result{791 bin_file.allocator,
851 .fail = try ErrorMsg.create(792 src_loc,
852 bin_file.allocator,793 "TODO implement generateSymbol for type '{s}'",
853 src_loc,794 .{@tagName(t)},
854 "TODO implement generateSymbol for type '{s}'",795 ) },
855 .{@tagName(t)},
856 ),
857 };
858 },
859 }796 }
860}797}
861798
...@@ -871,6 +808,38 @@ fn lowerParentPtr(...@@ -871,6 +808,38 @@ fn lowerParentPtr(
871 const target = bin_file.options.target;808 const target = bin_file.options.target;
872809
873 switch (parent_ptr.tag()) {810 switch (parent_ptr.tag()) {
811 .field_ptr => {
812 const field_ptr = parent_ptr.castTag(.field_ptr).?.data;
813 return lowerParentPtr(
814 bin_file,
815 src_loc,
816 typed_value,
817 field_ptr.container_ptr,
818 code,
819 debug_output,
820 reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag()) {
821 .Pointer => offset: {
822 assert(field_ptr.container_ty.isSlice());
823 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
824 break :offset switch (field_ptr.field_index) {
825 0 => 0,
826 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(target),
827 else => unreachable,
828 };
829 },
830 .Struct, .Union => field_ptr.container_ty.structFieldOffset(
831 field_ptr.field_index,
832 target,
833 ),
834 else => return Result{ .fail = try ErrorMsg.create(
835 bin_file.allocator,
836 src_loc,
837 "TODO implement lowerParentPtr for field_ptr with a container of type {}",
838 .{field_ptr.container_ty.fmt(bin_file.options.module.?)},
839 ) },
840 })),
841 );
842 },
874 .elem_ptr => {843 .elem_ptr => {
875 const elem_ptr = parent_ptr.castTag(.elem_ptr).?.data;844 const elem_ptr = parent_ptr.castTag(.elem_ptr).?.data;
876 return lowerParentPtr(845 return lowerParentPtr(
test/behavior/union.zig-1
...@@ -448,7 +448,6 @@ const Foo1 = union(enum) {...@@ -448,7 +448,6 @@ const Foo1 = union(enum) {
448var glbl: Foo1 = undefined;448var glbl: Foo1 = undefined;
449449
450test "global union with single field is correctly initialized" {450test "global union with single field is correctly initialized" {
451 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
452 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;451 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
453 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;452 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
454 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO453 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO