authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-21 21:38:55-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-21 21:38:55-04:00
log7d50634e0ad4355e339bc243a2e2842693e133f9
treecd6f81b82b20532d40e0944e6a814519ebf7cb41
parent3cd3052d4d303dbae7d517fa40f6d171c957afdd
parent3d7c6c803b788138aa08f51cf4ee8cf7892e315d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17545 from ziglang/more-anon-decls

migrate make_ptr_const to new anonymous decl mechanism

25 files changed, 336 insertions(+), 152 deletions(-)

lib/std/elf.zig+12-12
...@@ -782,10 +782,10 @@ pub const Elf32_Sym = extern struct {...@@ -782,10 +782,10 @@ pub const Elf32_Sym = extern struct {
782 st_shndx: Elf32_Section,782 st_shndx: Elf32_Section,
783783
784 pub inline fn st_type(self: @This()) u4 {784 pub inline fn st_type(self: @This()) u4 {
785 return @as(u4, @truncate(self.st_info));785 return @truncate(self.st_info);
786 }786 }
787 pub inline fn st_bind(self: @This()) u4 {787 pub inline fn st_bind(self: @This()) u4 {
788 return @as(u4, @truncate(self.st_info >> 4));788 return @truncate(self.st_info >> 4);
789 }789 }
790};790};
791pub const Elf64_Sym = extern struct {791pub const Elf64_Sym = extern struct {
...@@ -797,10 +797,10 @@ pub const Elf64_Sym = extern struct {...@@ -797,10 +797,10 @@ pub const Elf64_Sym = extern struct {
797 st_size: Elf64_Xword,797 st_size: Elf64_Xword,
798798
799 pub inline fn st_type(self: @This()) u4 {799 pub inline fn st_type(self: @This()) u4 {
800 return @as(u4, @truncate(self.st_info));800 return @truncate(self.st_info);
801 }801 }
802 pub inline fn st_bind(self: @This()) u4 {802 pub inline fn st_bind(self: @This()) u4 {
803 return @as(u4, @truncate(self.st_info >> 4));803 return @truncate(self.st_info >> 4);
804 }804 }
805};805};
806pub const Elf32_Syminfo = extern struct {806pub const Elf32_Syminfo = extern struct {
...@@ -816,10 +816,10 @@ pub const Elf32_Rel = extern struct {...@@ -816,10 +816,10 @@ pub const Elf32_Rel = extern struct {
816 r_info: Elf32_Word,816 r_info: Elf32_Word,
817817
818 pub inline fn r_sym(self: @This()) u24 {818 pub inline fn r_sym(self: @This()) u24 {
819 return @as(u24, @truncate(self.r_info >> 8));819 return @truncate(self.r_info >> 8);
820 }820 }
821 pub inline fn r_type(self: @This()) u8 {821 pub inline fn r_type(self: @This()) u8 {
822 return @as(u8, @truncate(self.r_info));822 return @truncate(self.r_info);
823 }823 }
824};824};
825pub const Elf64_Rel = extern struct {825pub const Elf64_Rel = extern struct {
...@@ -827,10 +827,10 @@ pub const Elf64_Rel = extern struct {...@@ -827,10 +827,10 @@ pub const Elf64_Rel = extern struct {
827 r_info: Elf64_Xword,827 r_info: Elf64_Xword,
828828
829 pub inline fn r_sym(self: @This()) u32 {829 pub inline fn r_sym(self: @This()) u32 {
830 return @as(u32, @truncate(self.r_info >> 32));830 return @truncate(self.r_info >> 32);
831 }831 }
832 pub inline fn r_type(self: @This()) u32 {832 pub inline fn r_type(self: @This()) u32 {
833 return @as(u32, @truncate(self.r_info));833 return @truncate(self.r_info);
834 }834 }
835};835};
836pub const Elf32_Rela = extern struct {836pub const Elf32_Rela = extern struct {
...@@ -839,10 +839,10 @@ pub const Elf32_Rela = extern struct {...@@ -839,10 +839,10 @@ pub const Elf32_Rela = extern struct {
839 r_addend: Elf32_Sword,839 r_addend: Elf32_Sword,
840840
841 pub inline fn r_sym(self: @This()) u24 {841 pub inline fn r_sym(self: @This()) u24 {
842 return @as(u24, @truncate(self.r_info >> 8));842 return @truncate(self.r_info >> 8);
843 }843 }
844 pub inline fn r_type(self: @This()) u8 {844 pub inline fn r_type(self: @This()) u8 {
845 return @as(u8, @truncate(self.r_info));845 return @truncate(self.r_info);
846 }846 }
847};847};
848pub const Elf64_Rela = extern struct {848pub const Elf64_Rela = extern struct {
...@@ -851,10 +851,10 @@ pub const Elf64_Rela = extern struct {...@@ -851,10 +851,10 @@ pub const Elf64_Rela = extern struct {
851 r_addend: Elf64_Sxword,851 r_addend: Elf64_Sxword,
852852
853 pub inline fn r_sym(self: @This()) u32 {853 pub inline fn r_sym(self: @This()) u32 {
854 return @as(u32, @truncate(self.r_info >> 32));854 return @truncate(self.r_info >> 32);
855 }855 }
856 pub inline fn r_type(self: @This()) u32 {856 pub inline fn r_type(self: @This()) u32 {
857 return @as(u32, @truncate(self.r_info));857 return @truncate(self.r_info);
858 }858 }
859};859};
860pub const Elf32_Dyn = extern struct {860pub const Elf32_Dyn = extern struct {
src/AstGen.zig+6-4
...@@ -3123,10 +3123,10 @@ fn varDecl(...@@ -3123,10 +3123,10 @@ fn varDecl(
3123 if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node))3123 if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node))
3124 _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst });3124 _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst });
31253125
3126 if (resolve_inferred_alloc != .none) {3126 const const_ptr = if (resolve_inferred_alloc != .none) p: {
3127 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);3127 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
3128 }3128 break :p var_ptr;
3129 const const_ptr = try gz.addUnNode(.make_ptr_const, var_ptr, node);3129 } else try gz.addUnNode(.make_ptr_const, var_ptr, node);
31303130
3131 try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr);3131 try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr);
31323132
...@@ -3533,7 +3533,9 @@ fn assignDestructureMaybeDecls(...@@ -3533,7 +3533,9 @@ fn assignDestructureMaybeDecls(
3533 else => unreachable,3533 else => unreachable,
3534 };3534 };
3535 // If the alloc was const, make it const.3535 // If the alloc was const, make it const.
3536 const var_ptr = if (is_const) make_const: {3536 const var_ptr = if (is_const and full.ast.type_node != 0) make_const: {
3537 // Note that we don't do this if type_node == 0 since `resolve_inferred_alloc`
3538 // handles it for us.
3537 break :make_const try gz.addUnNode(.make_ptr_const, raw_ptr, node);3539 break :make_const try gz.addUnNode(.make_ptr_const, raw_ptr, node);
3538 } else raw_ptr;3540 } else raw_ptr;
3539 const name_token = full.ast.mut_token + 1;3541 const name_token = full.ast.mut_token + 1;
src/Compilation.zig+1
...@@ -3545,6 +3545,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v...@@ -3545,6 +3545,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
3545 .fwd_decl = fwd_decl.toManaged(gpa),3545 .fwd_decl = fwd_decl.toManaged(gpa),
3546 .ctypes = .{},3546 .ctypes = .{},
3547 .anon_decl_deps = .{},3547 .anon_decl_deps = .{},
3548 .aligned_anon_decls = .{},
3548 };3549 };
3549 defer {3550 defer {
3550 dg.ctypes.deinit(gpa);3551 dg.ctypes.deinit(gpa);
src/InternPool.zig+86-14
...@@ -1074,7 +1074,7 @@ pub const Key = union(enum) {...@@ -1074,7 +1074,7 @@ pub const Key = union(enum) {
10741074
1075 decl: Module.Decl.Index,1075 decl: Module.Decl.Index,
1076 mut_decl: MutDecl,1076 mut_decl: MutDecl,
1077 anon_decl: Index,1077 anon_decl: AnonDecl,
1078 comptime_field: Index,1078 comptime_field: Index,
1079 int: Index,1079 int: Index,
1080 eu_payload: Index,1080 eu_payload: Index,
...@@ -1090,6 +1090,14 @@ pub const Key = union(enum) {...@@ -1090,6 +1090,14 @@ pub const Key = union(enum) {
1090 base: Index,1090 base: Index,
1091 index: u64,1091 index: u64,
1092 };1092 };
1093 pub const AnonDecl = extern struct {
1094 val: Index,
1095 /// Contains the canonical pointer type of the anonymous
1096 /// declaration. This may equal `ty` of the `Ptr` or it may be
1097 /// different. Importantly, when lowering the anonymous decl,
1098 /// the original pointer type alignment must be used.
1099 orig_ty: Index,
1100 };
1093 };1101 };
1094 };1102 };
10951103
...@@ -1231,7 +1239,8 @@ pub const Key = union(enum) {...@@ -1231,7 +1239,8 @@ pub const Key = union(enum) {
1231 common ++ asBytes(&x.decl) ++ asBytes(&x.runtime_index),1239 common ++ asBytes(&x.decl) ++ asBytes(&x.runtime_index),
1232 ),1240 ),
12331241
1234 .anon_decl,1242 .anon_decl => |x| Hash.hash(seed2, common ++ asBytes(&x)),
1243
1235 .int,1244 .int,
1236 .eu_payload,1245 .eu_payload,
1237 .opt_payload,1246 .opt_payload,
...@@ -1500,7 +1509,8 @@ pub const Key = union(enum) {...@@ -1500,7 +1509,8 @@ pub const Key = union(enum) {
1500 return switch (a_info.addr) {1509 return switch (a_info.addr) {
1501 .decl => |a_decl| a_decl == b_info.addr.decl,1510 .decl => |a_decl| a_decl == b_info.addr.decl,
1502 .mut_decl => |a_mut_decl| std.meta.eql(a_mut_decl, b_info.addr.mut_decl),1511 .mut_decl => |a_mut_decl| std.meta.eql(a_mut_decl, b_info.addr.mut_decl),
1503 .anon_decl => |a_decl| a_decl == b_info.addr.anon_decl,1512 .anon_decl => |ad| ad.val == b_info.addr.anon_decl.val and
1513 ad.orig_ty == b_info.addr.anon_decl.orig_ty,
1504 .int => |a_int| a_int == b_info.addr.int,1514 .int => |a_int| a_int == b_info.addr.int,
1505 .eu_payload => |a_eu_payload| a_eu_payload == b_info.addr.eu_payload,1515 .eu_payload => |a_eu_payload| a_eu_payload == b_info.addr.eu_payload,
1506 .opt_payload => |a_opt_payload| a_opt_payload == b_info.addr.opt_payload,1516 .opt_payload => |a_opt_payload| a_opt_payload == b_info.addr.opt_payload,
...@@ -2133,6 +2143,7 @@ pub const Index = enum(u32) {...@@ -2133,6 +2143,7 @@ pub const Index = enum(u32) {
2133 ptr_decl: struct { data: *PtrDecl },2143 ptr_decl: struct { data: *PtrDecl },
2134 ptr_mut_decl: struct { data: *PtrMutDecl },2144 ptr_mut_decl: struct { data: *PtrMutDecl },
2135 ptr_anon_decl: struct { data: *PtrAnonDecl },2145 ptr_anon_decl: struct { data: *PtrAnonDecl },
2146 ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned },
2136 ptr_comptime_field: struct { data: *PtrComptimeField },2147 ptr_comptime_field: struct { data: *PtrComptimeField },
2137 ptr_int: struct { data: *PtrBase },2148 ptr_int: struct { data: *PtrBase },
2138 ptr_eu_payload: struct { data: *PtrBase },2149 ptr_eu_payload: struct { data: *PtrBase },
...@@ -2583,8 +2594,16 @@ pub const Tag = enum(u8) {...@@ -2583,8 +2594,16 @@ pub const Tag = enum(u8) {
2583 /// data is extra index of `PtrMutDecl`, which contains the type and address.2594 /// data is extra index of `PtrMutDecl`, which contains the type and address.
2584 ptr_mut_decl,2595 ptr_mut_decl,
2585 /// A pointer to an anonymous decl.2596 /// A pointer to an anonymous decl.
2586 /// data is extra index of `PtrAnonDecl`, which contains the type and decl value.2597 /// data is extra index of `PtrAnonDecl`, which contains the pointer type and decl value.
2598 /// The alignment of the anonymous decl is communicated via the pointer type.
2587 ptr_anon_decl,2599 ptr_anon_decl,
2600 /// A pointer to an anonymous decl.
2601 /// data is extra index of `PtrAnonDeclAligned`, which contains the pointer
2602 /// type and decl value.
2603 /// The original pointer type is also provided, which will be different than `ty`.
2604 /// This encoding is only used when a pointer to an anonymous decl is
2605 /// coerced to a different pointer type with a different alignment.
2606 ptr_anon_decl_aligned,
2588 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.2607 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.
2589 ptr_comptime_field,2608 ptr_comptime_field,
2590 /// A pointer with an integer value.2609 /// A pointer with an integer value.
...@@ -2781,6 +2800,7 @@ pub const Tag = enum(u8) {...@@ -2781,6 +2800,7 @@ pub const Tag = enum(u8) {
2781 .ptr_decl => PtrDecl,2800 .ptr_decl => PtrDecl,
2782 .ptr_mut_decl => PtrMutDecl,2801 .ptr_mut_decl => PtrMutDecl,
2783 .ptr_anon_decl => PtrAnonDecl,2802 .ptr_anon_decl => PtrAnonDecl,
2803 .ptr_anon_decl_aligned => PtrAnonDeclAligned,
2784 .ptr_comptime_field => PtrComptimeField,2804 .ptr_comptime_field => PtrComptimeField,
2785 .ptr_int => PtrBase,2805 .ptr_int => PtrBase,
2786 .ptr_eu_payload => PtrBase,2806 .ptr_eu_payload => PtrBase,
...@@ -3383,6 +3403,13 @@ pub const PtrAnonDecl = struct {...@@ -3383,6 +3403,13 @@ pub const PtrAnonDecl = struct {
3383 val: Index,3403 val: Index,
3384};3404};
33853405
3406pub const PtrAnonDeclAligned = struct {
3407 ty: Index,
3408 val: Index,
3409 /// Must be nonequal to `ty`. Only the alignment from this value is important.
3410 orig_ty: Index,
3411};
3412
3386pub const PtrMutDecl = struct {3413pub const PtrMutDecl = struct {
3387 ty: Index,3414 ty: Index,
3388 decl: Module.Decl.Index,3415 decl: Module.Decl.Index,
...@@ -3736,7 +3763,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -3736,7 +3763,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
3736 const info = ip.extraData(PtrAnonDecl, data);3763 const info = ip.extraData(PtrAnonDecl, data);
3737 return .{ .ptr = .{3764 return .{ .ptr = .{
3738 .ty = info.ty,3765 .ty = info.ty,
3739 .addr = .{ .anon_decl = info.val },3766 .addr = .{ .anon_decl = .{
3767 .val = info.val,
3768 .orig_ty = info.ty,
3769 } },
3770 } };
3771 },
3772 .ptr_anon_decl_aligned => {
3773 const info = ip.extraData(PtrAnonDeclAligned, data);
3774 return .{ .ptr = .{
3775 .ty = info.ty,
3776 .addr = .{ .anon_decl = .{
3777 .val = info.val,
3778 .orig_ty = info.orig_ty,
3779 } },
3740 } };3780 } };
3741 },3781 },
3742 .ptr_comptime_field => {3782 .ptr_comptime_field => {
...@@ -3817,7 +3857,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -3817,7 +3857,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
3817 } };3857 } };
3818 },3858 },
3819 .ptr_anon_decl => .{3859 .ptr_anon_decl => .{
3820 .anon_decl = ip.extraData(PtrAnonDecl, ptr_item.data).val,3860 .anon_decl = .{
3861 .val = ip.extraData(PtrAnonDecl, ptr_item.data).val,
3862 .orig_ty = info.ty,
3863 },
3864 },
3865 .ptr_anon_decl_aligned => b: {
3866 const sub_info = ip.extraData(PtrAnonDeclAligned, ptr_item.data);
3867 break :b .{ .anon_decl = .{
3868 .val = sub_info.val,
3869 .orig_ty = sub_info.orig_ty,
3870 } };
3821 },3871 },
3822 .ptr_comptime_field => .{3872 .ptr_comptime_field => .{
3823 .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val,3873 .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val,
...@@ -4571,13 +4621,22 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -4571,13 +4621,22 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
4571 .runtime_index = mut_decl.runtime_index,4621 .runtime_index = mut_decl.runtime_index,
4572 }),4622 }),
4573 }),4623 }),
4574 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(.{4624 .anon_decl => |anon_decl| ip.items.appendAssumeCapacity(
4575 .tag = .ptr_anon_decl,4625 if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) .{
4576 .data = try ip.addExtra(gpa, PtrAnonDecl{4626 .tag = .ptr_anon_decl,
4577 .ty = ptr.ty,4627 .data = try ip.addExtra(gpa, PtrAnonDecl{
4578 .val = anon_decl,4628 .ty = ptr.ty,
4579 }),4629 .val = anon_decl.val,
4580 }),4630 }),
4631 } else .{
4632 .tag = .ptr_anon_decl_aligned,
4633 .data = try ip.addExtra(gpa, PtrAnonDeclAligned{
4634 .ty = ptr.ty,
4635 .val = anon_decl.val,
4636 .orig_ty = anon_decl.orig_ty,
4637 }),
4638 },
4639 ),
4581 .comptime_field => |field_val| {4640 .comptime_field => |field_val| {
4582 assert(field_val != .none);4641 assert(field_val != .none);
4583 ip.items.appendAssumeCapacity(.{4642 ip.items.appendAssumeCapacity(.{
...@@ -7184,6 +7243,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -7184,6 +7243,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
7184 .ptr_decl => @sizeOf(PtrDecl),7243 .ptr_decl => @sizeOf(PtrDecl),
7185 .ptr_mut_decl => @sizeOf(PtrMutDecl),7244 .ptr_mut_decl => @sizeOf(PtrMutDecl),
7186 .ptr_anon_decl => @sizeOf(PtrAnonDecl),7245 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
7246 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
7187 .ptr_comptime_field => @sizeOf(PtrComptimeField),7247 .ptr_comptime_field => @sizeOf(PtrComptimeField),
7188 .ptr_int => @sizeOf(PtrBase),7248 .ptr_int => @sizeOf(PtrBase),
7189 .ptr_eu_payload => @sizeOf(PtrBase),7249 .ptr_eu_payload => @sizeOf(PtrBase),
...@@ -7314,6 +7374,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -7314,6 +7374,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
7314 .ptr_decl,7374 .ptr_decl,
7315 .ptr_mut_decl,7375 .ptr_mut_decl,
7316 .ptr_anon_decl,7376 .ptr_anon_decl,
7377 .ptr_anon_decl_aligned,
7317 .ptr_comptime_field,7378 .ptr_comptime_field,
7318 .ptr_int,7379 .ptr_int,
7319 .ptr_eu_payload,7380 .ptr_eu_payload,
...@@ -7695,6 +7756,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -7695,6 +7756,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
7695 inline .ptr_decl,7756 inline .ptr_decl,
7696 .ptr_mut_decl,7757 .ptr_mut_decl,
7697 .ptr_anon_decl,7758 .ptr_anon_decl,
7759 .ptr_anon_decl_aligned,
7698 .ptr_comptime_field,7760 .ptr_comptime_field,
7699 .ptr_int,7761 .ptr_int,
7700 .ptr_eu_payload,7762 .ptr_eu_payload,
...@@ -7855,7 +7917,7 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.Addr.Tag {...@@ -7855,7 +7917,7 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.Addr.Tag {
7855 switch (ip.items.items(.tag)[base]) {7917 switch (ip.items.items(.tag)[base]) {
7856 .ptr_decl => return .decl,7918 .ptr_decl => return .decl,
7857 .ptr_mut_decl => return .mut_decl,7919 .ptr_mut_decl => return .mut_decl,
7858 .ptr_anon_decl => return .anon_decl,7920 .ptr_anon_decl, .ptr_anon_decl_aligned => return .anon_decl,
7859 .ptr_comptime_field => return .comptime_field,7921 .ptr_comptime_field => return .comptime_field,
7860 .ptr_int => return .int,7922 .ptr_int => return .int,
7861 inline .ptr_eu_payload,7923 inline .ptr_eu_payload,
...@@ -8032,6 +8094,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -8032,6 +8094,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
8032 .ptr_decl,8094 .ptr_decl,
8033 .ptr_mut_decl,8095 .ptr_mut_decl,
8034 .ptr_anon_decl,8096 .ptr_anon_decl,
8097 .ptr_anon_decl_aligned,
8035 .ptr_comptime_field,8098 .ptr_comptime_field,
8036 .ptr_int,8099 .ptr_int,
8037 .ptr_eu_payload,8100 .ptr_eu_payload,
...@@ -8281,3 +8344,12 @@ pub fn addFieldName(...@@ -8281,3 +8344,12 @@ pub fn addFieldName(
8281 ip.extra.items[names_start + field_index] = @intFromEnum(name);8344 ip.extra.items[names_start + field_index] = @intFromEnum(name);
8282 return null;8345 return null;
8283}8346}
8347
8348/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_anon_decl`
8349/// encoding instead of `Tag.ptr_anon_decl_aligned` when possible.
8350fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
8351 if (a_ty == b_ty) return true;
8352 const b_info = ip.indexToKey(b_ty).ptr_type;
8353 return a_info.flags.alignment == b_info.flags.alignment and
8354 (a_info.child == b_info.child or a_info.flags.alignment != .none);
8355}
src/Sema.zig+43-21
...@@ -3657,9 +3657,13 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3657,9 +3657,13 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3657 const elem_ty = ptr_info.child.toType();3657 const elem_ty = ptr_info.child.toType();
36583658
3659 if (try sema.resolveComptimeKnownAllocValue(block, alloc, null)) |val| {3659 if (try sema.resolveComptimeKnownAllocValue(block, alloc, null)) |val| {
3660 var anon_decl = try block.startAnonDecl();3660 const new_mut_ptr = Air.internedToRef((try mod.intern(.{ .ptr = .{
3661 defer anon_decl.deinit();3661 .ty = alloc_ty.toIntern(),
3662 const new_mut_ptr = try sema.analyzeDeclRef(try anon_decl.finish(elem_ty, val.toValue(), ptr_info.flags.alignment));3662 .addr = .{ .anon_decl = .{
3663 .val = val,
3664 .orig_ty = alloc_ty.toIntern(),
3665 } },
3666 } })));
3663 return sema.makePtrConst(block, new_mut_ptr);3667 return sema.makePtrConst(block, new_mut_ptr);
3664 }3668 }
36653669
...@@ -3668,10 +3672,18 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3668,10 +3672,18 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3668 implicit_ct: {3672 implicit_ct: {
3669 const ptr_val = try sema.resolveMaybeUndefVal(alloc) orelse break :implicit_ct;3673 const ptr_val = try sema.resolveMaybeUndefVal(alloc) orelse break :implicit_ct;
3670 if (!ptr_val.isComptimeMutablePtr(mod)) {3674 if (!ptr_val.isComptimeMutablePtr(mod)) {
3671 // It could still be a constant pointer to a decl3675 // It could still be a constant pointer to a decl.
3672 const decl_index = ptr_val.pointerDecl(mod) orelse break :implicit_ct;3676 switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
3673 const decl_val = mod.declPtr(decl_index).val.toIntern();3677 .anon_decl => |anon_decl| {
3674 if (mod.intern_pool.isRuntimeValue(decl_val)) break :implicit_ct;3678 if (mod.intern_pool.isVariable(anon_decl.val))
3679 break :implicit_ct;
3680 },
3681 else => {
3682 const decl_index = ptr_val.pointerDecl(mod) orelse break :implicit_ct;
3683 const decl_val = mod.declPtr(decl_index).val.toIntern();
3684 if (mod.intern_pool.isRuntimeValue(decl_val)) break :implicit_ct;
3685 },
3686 }
3675 }3687 }
3676 return sema.makePtrConst(block, alloc);3688 return sema.makePtrConst(block, alloc);
3677 }3689 }
...@@ -3911,17 +3923,19 @@ fn finishResolveComptimeKnownAllocValue(sema: *Sema, result_val: InternPool.Inde...@@ -3911,17 +3923,19 @@ fn finishResolveComptimeKnownAllocValue(sema: *Sema, result_val: InternPool.Inde
3911 return result_val;3923 return result_val;
3912}3924}
39133925
3926fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
3927 var ptr_info = ptr_ty.ptrInfo(sema.mod);
3928 ptr_info.flags.is_const = true;
3929 return sema.ptrType(ptr_info);
3930}
3931
3914fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {3932fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
3915 const mod = sema.mod;
3916 const alloc_ty = sema.typeOf(alloc);3933 const alloc_ty = sema.typeOf(alloc);
39173934 const const_ptr_ty = try sema.makePtrTyConst(alloc_ty);
3918 var ptr_info = alloc_ty.ptrInfo(mod);
3919 ptr_info.flags.is_const = true;
3920 const const_ptr_ty = try sema.ptrType(ptr_info);
39213935
3922 // Detect if a comptime value simply needs to have its type changed.3936 // Detect if a comptime value simply needs to have its type changed.
3923 if (try sema.resolveMaybeUndefVal(alloc)) |val| {3937 if (try sema.resolveMaybeUndefVal(alloc)) |val| {
3924 return Air.internedToRef((try mod.getCoerced(val, const_ptr_ty)).toIntern());3938 return Air.internedToRef((try sema.mod.getCoerced(val, const_ptr_ty)).toIntern());
3925 }3939 }
39263940
3927 return block.addBitCast(const_ptr_ty, alloc);3941 return block.addBitCast(const_ptr_ty, alloc);
...@@ -4035,6 +4049,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4035,6 +4049,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4035 defer tracy.end();4049 defer tracy.end();
40364050
4037 const mod = sema.mod;4051 const mod = sema.mod;
4052 const gpa = sema.gpa;
4038 const inst_data = sema.code.instructions.items(.data)[inst].un_node;4053 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4039 const src = inst_data.src();4054 const src = inst_data.src();
4040 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };4055 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
...@@ -4100,11 +4115,14 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4100,11 +4115,14 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4100 if (!ia1.is_const) {4115 if (!ia1.is_const) {
4101 try sema.validateVarType(block, ty_src, final_elem_ty, false);4116 try sema.validateVarType(block, ty_src, final_elem_ty, false);
4102 } else if (try sema.resolveComptimeKnownAllocValue(block, ptr, final_ptr_ty)) |val| {4117 } else if (try sema.resolveComptimeKnownAllocValue(block, ptr, final_ptr_ty)) |val| {
4103 var anon_decl = try block.startAnonDecl();4118 const const_ptr_ty = (try sema.makePtrTyConst(final_ptr_ty)).toIntern();
4104 defer anon_decl.deinit();4119 const new_const_ptr = try mod.intern(.{ .ptr = .{
4105 const new_decl_index = try anon_decl.finish(final_elem_ty, val.toValue(), ia1.alignment);4120 .ty = const_ptr_ty,
4106 const new_mut_ptr = Air.refToInterned(try sema.analyzeDeclRef(new_decl_index)).?.toValue();4121 .addr = .{ .anon_decl = .{
4107 const new_const_ptr = (try mod.getCoerced(new_mut_ptr, final_ptr_ty)).toIntern();4122 .val = val,
4123 .orig_ty = const_ptr_ty,
4124 } },
4125 } });
41084126
4109 // Remap the ZIR oeprand to the resolved pointer value4127 // Remap the ZIR oeprand to the resolved pointer value
4110 sema.inst_map.putAssumeCapacity(Zir.refToIndex(inst_data.operand).?, Air.internedToRef(new_const_ptr));4128 sema.inst_map.putAssumeCapacity(Zir.refToIndex(inst_data.operand).?, Air.internedToRef(new_const_ptr));
...@@ -4127,7 +4145,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4127,7 +4145,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
41274145
4128 // Now we need to go back over all the store instructions, and do the logic as if4146 // Now we need to go back over all the store instructions, and do the logic as if
4129 // the new result ptr type was available.4147 // the new result ptr type was available.
4130 const gpa = sema.gpa;
41314148
4132 for (ia2.prongs.items) |placeholder_inst| {4149 for (ia2.prongs.items) |placeholder_inst| {
4133 var replacement_block = block.makeSubBlock();4150 var replacement_block = block.makeSubBlock();
...@@ -5539,7 +5556,10 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {...@@ -5539,7 +5556,10 @@ fn addStrLitNoAlias(sema: *Sema, bytes: []const u8) CompileError!Air.Inst.Ref {
5539 });5556 });
5540 return Air.internedToRef((try mod.intern(.{ .ptr = .{5557 return Air.internedToRef((try mod.intern(.{ .ptr = .{
5541 .ty = ptr_ty.toIntern(),5558 .ty = ptr_ty.toIntern(),
5542 .addr = .{ .anon_decl = val },5559 .addr = .{ .anon_decl = .{
5560 .val = val,
5561 .orig_ty = ptr_ty.toIntern(),
5562 } },
5543 } })));5563 } })));
5544}5564}
55455565
...@@ -30545,7 +30565,8 @@ fn beginComptimePtrLoad(...@@ -30545,7 +30565,8 @@ fn beginComptimePtrLoad(
30545 .ty_without_well_defined_layout = if (!layout_defined) decl.ty else null,30565 .ty_without_well_defined_layout = if (!layout_defined) decl.ty else null,
30546 };30566 };
30547 },30567 },
30548 .anon_decl => |decl_val| blk: {30568 .anon_decl => |anon_decl| blk: {
30569 const decl_val = anon_decl.val;
30549 if (decl_val.toValue().getVariable(mod) != null) return error.RuntimeLoad;30570 if (decl_val.toValue().getVariable(mod) != null) return error.RuntimeLoad;
30550 const decl_ty = ip.typeOf(decl_val).toType();30571 const decl_ty = ip.typeOf(decl_val).toType();
30551 const decl_tv: TypedValue = .{ .ty = decl_ty, .val = decl_val.toValue() };30572 const decl_tv: TypedValue = .{ .ty = decl_ty, .val = decl_val.toValue() };
...@@ -36649,6 +36670,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36649,6 +36670,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36649 .simple_value,36670 .simple_value,
36650 .ptr_decl,36671 .ptr_decl,
36651 .ptr_anon_decl,36672 .ptr_anon_decl,
36673 .ptr_anon_decl_aligned,
36652 .ptr_mut_decl,36674 .ptr_mut_decl,
36653 .ptr_comptime_field,36675 .ptr_comptime_field,
36654 .ptr_int,36676 .ptr_int,
src/TypedValue.zig+2-1
...@@ -321,7 +321,8 @@ pub fn print(...@@ -321,7 +321,8 @@ pub fn print(
321 .val = decl.val,321 .val = decl.val,
322 }, writer, level - 1, mod);322 }, writer, level - 1, mod);
323 },323 },
324 .anon_decl => |decl_val| {324 .anon_decl => |anon_decl| {
325 const decl_val = anon_decl.val;
325 if (level == 0) return writer.print("(anon decl '{d}')", .{326 if (level == 0) return writer.print("(anon decl '{d}')", .{
326 @intFromEnum(decl_val),327 @intFromEnum(decl_val),
327 });328 });
src/Zir.zig+3-2
...@@ -997,8 +997,9 @@ pub const Inst = struct {...@@ -997,8 +997,9 @@ pub const Inst = struct {
997 /// is the allocation that needs to have its type inferred.997 /// is the allocation that needs to have its type inferred.
998 /// Uses the `un_node` field. The AST node is the var decl.998 /// Uses the `un_node` field. The AST node is the var decl.
999 resolve_inferred_alloc,999 resolve_inferred_alloc,
1000 /// Turns a pointer coming from an `alloc`, `alloc_inferred`, `alloc_inferred_comptime` or1000 /// Turns a pointer coming from an `alloc` or `Extended.alloc` into a constant
1001 /// `Extended.alloc` into a constant version of the same pointer.1001 /// version of the same pointer. For inferred allocations this is instead implicitly
1002 /// handled by the `resolve_inferred_alloc` instruction.
1002 /// Uses the `un_node` union field.1003 /// Uses the `un_node` union field.
1003 make_ptr_const,1004 make_ptr_const,
10041005
src/arch/wasm/CodeGen.zig+10-4
...@@ -3139,16 +3139,22 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In...@@ -3139,16 +3139,22 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In
3139 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);3139 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);
3140}3140}
31413141
3142fn lowerAnonDeclRef(func: *CodeGen, anon_decl: InternPool.Index, offset: u32) InnerError!WValue {3142fn lowerAnonDeclRef(
3143 func: *CodeGen,
3144 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
3145 offset: u32,
3146) InnerError!WValue {
3143 const mod = func.bin_file.base.options.module.?;3147 const mod = func.bin_file.base.options.module.?;
3144 const ty = mod.intern_pool.typeOf(anon_decl).toType();3148 const decl_val = anon_decl.val;
3149 const ty = mod.intern_pool.typeOf(decl_val).toType();
31453150
3146 const is_fn_body = ty.zigTypeTag(mod) == .Fn;3151 const is_fn_body = ty.zigTypeTag(mod) == .Fn;
3147 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(mod)) {3152 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(mod)) {
3148 return WValue{ .imm32 = 0xaaaaaaaa };3153 return WValue{ .imm32 = 0xaaaaaaaa };
3149 }3154 }
31503155
3151 const res = try func.bin_file.lowerAnonDecl(anon_decl, func.decl.srcLoc(mod));3156 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
3157 const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.srcLoc(mod));
3152 switch (res) {3158 switch (res) {
3153 .ok => {},3159 .ok => {},
3154 .fail => |em| {3160 .fail => |em| {
...@@ -3156,7 +3162,7 @@ fn lowerAnonDeclRef(func: *CodeGen, anon_decl: InternPool.Index, offset: u32) In...@@ -3156,7 +3162,7 @@ fn lowerAnonDeclRef(func: *CodeGen, anon_decl: InternPool.Index, offset: u32) In
3156 return error.CodegenFail;3162 return error.CodegenFail;
3157 },3163 },
3158 }3164 }
3159 const target_atom_index = func.bin_file.anon_decls.get(anon_decl).?;3165 const target_atom_index = func.bin_file.anon_decls.get(decl_val).?;
3160 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;3166 const target_sym_index = func.bin_file.getAtom(target_atom_index).getSymbolIndex().?;
3161 if (is_fn_body) {3167 if (is_fn_body) {
3162 return WValue{ .function_index = target_sym_index };3168 return WValue{ .function_index = target_sym_index };
src/codegen.zig+4-2
...@@ -713,7 +713,7 @@ const RelocInfo = struct {...@@ -713,7 +713,7 @@ const RelocInfo = struct {
713fn lowerAnonDeclRef(713fn lowerAnonDeclRef(
714 bin_file: *link.File,714 bin_file: *link.File,
715 src_loc: Module.SrcLoc,715 src_loc: Module.SrcLoc,
716 decl_val: InternPool.Index,716 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
717 code: *std.ArrayList(u8),717 code: *std.ArrayList(u8),
718 debug_output: DebugInfoOutput,718 debug_output: DebugInfoOutput,
719 reloc_info: RelocInfo,719 reloc_info: RelocInfo,
...@@ -723,6 +723,7 @@ fn lowerAnonDeclRef(...@@ -723,6 +723,7 @@ fn lowerAnonDeclRef(
723 const mod = bin_file.options.module.?;723 const mod = bin_file.options.module.?;
724724
725 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);725 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
726 const decl_val = anon_decl.val;
726 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();727 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();
727 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;728 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
728 if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {729 if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {
...@@ -730,7 +731,8 @@ fn lowerAnonDeclRef(...@@ -730,7 +731,8 @@ fn lowerAnonDeclRef(
730 return Result.ok;731 return Result.ok;
731 }732 }
732733
733 const res = try bin_file.lowerAnonDecl(decl_val, src_loc);734 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
735 const res = try bin_file.lowerAnonDecl(decl_val, decl_align, src_loc);
734 switch (res) {736 switch (res) {
735 .ok => {},737 .ok => {},
736 .fail => |em| return .{ .fail = em },738 .fail => |em| return .{ .fail = em },
src/codegen/c.zig+19-2
...@@ -531,6 +531,7 @@ pub const DeclGen = struct {...@@ -531,6 +531,7 @@ pub const DeclGen = struct {
531 /// Keeps track of anonymous decls that need to be rendered before this531 /// Keeps track of anonymous decls that need to be rendered before this
532 /// (named) Decl in the output C code.532 /// (named) Decl in the output C code.
533 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),533 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),
534 aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
534535
535 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {536 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
536 @setCold(true);537 @setCold(true);
...@@ -548,11 +549,12 @@ pub const DeclGen = struct {...@@ -548,11 +549,12 @@ pub const DeclGen = struct {
548 writer: anytype,549 writer: anytype,
549 ty: Type,550 ty: Type,
550 ptr_val: Value,551 ptr_val: Value,
551 decl_val: InternPool.Index,552 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
552 location: ValueRenderLocation,553 location: ValueRenderLocation,
553 ) error{ OutOfMemory, AnalysisFail }!void {554 ) error{ OutOfMemory, AnalysisFail }!void {
554 const mod = dg.module;555 const mod = dg.module;
555 const ip = &mod.intern_pool;556 const ip = &mod.intern_pool;
557 const decl_val = anon_decl.val;
556 const decl_ty = ip.typeOf(decl_val).toType();558 const decl_ty = ip.typeOf(decl_val).toType();
557559
558 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.560 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
...@@ -592,8 +594,23 @@ pub const DeclGen = struct {...@@ -592,8 +594,23 @@ pub const DeclGen = struct {
592594
593 // Indicate that the anon decl should be rendered to the output so that595 // Indicate that the anon decl should be rendered to the output so that
594 // our reference above is not undefined.596 // our reference above is not undefined.
597 const ptr_type = ip.indexToKey(anon_decl.orig_ty).ptr_type;
595 const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, decl_val);598 const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, decl_val);
596 if (!gop.found_existing) gop.value_ptr.* = .{};599 if (!gop.found_existing) gop.value_ptr.* = .{};
600
601 // Only insert an alignment entry if the alignment is greater than ABI
602 // alignment. If there is already an entry, keep the greater alignment.
603 const explicit_alignment = ptr_type.flags.alignment;
604 if (explicit_alignment != .none) {
605 const abi_alignment = ptr_type.child.toType().abiAlignment(mod);
606 if (explicit_alignment.compareStrict(.gt, abi_alignment)) {
607 const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, decl_val);
608 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)
609 aligned_gop.value_ptr.maxStrict(explicit_alignment)
610 else
611 explicit_alignment;
612 }
613 }
597 }614 }
598615
599 fn renderDeclValue(616 fn renderDeclValue(
...@@ -651,7 +668,7 @@ pub const DeclGen = struct {...@@ -651,7 +668,7 @@ pub const DeclGen = struct {
651 switch (ptr.addr) {668 switch (ptr.addr) {
652 .decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), d, location),669 .decl => |d| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), d, location),
653 .mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), md.decl, location),670 .mut_decl => |md| try dg.renderDeclValue(writer, ptr_ty, ptr_val.toValue(), md.decl, location),
654 .anon_decl => |decl_val| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val.toValue(), decl_val, location),671 .anon_decl => |anon_decl| try dg.renderAnonDeclValue(writer, ptr_ty, ptr_val.toValue(), anon_decl, location),
655 .int => |int| {672 .int => |int| {
656 try writer.writeByte('(');673 try writer.writeByte('(');
657 try dg.renderCType(writer, ptr_cty);674 try dg.renderCType(writer, ptr_cty);
src/codegen/llvm.zig+18-13
...@@ -3049,10 +3049,19 @@ pub const Object = struct {...@@ -3049,10 +3049,19 @@ pub const Object = struct {
3049 o: *Object,3049 o: *Object,
3050 decl_val: InternPool.Index,3050 decl_val: InternPool.Index,
3051 llvm_addr_space: Builder.AddrSpace,3051 llvm_addr_space: Builder.AddrSpace,
3052 alignment: InternPool.Alignment,
3052 ) Error!Builder.Variable.Index {3053 ) Error!Builder.Variable.Index {
3054 assert(alignment != .none);
3053 // TODO: Add address space to the anon_decl_map3055 // TODO: Add address space to the anon_decl_map
3054 const gop = try o.anon_decl_map.getOrPut(o.gpa, decl_val);3056 const gop = try o.anon_decl_map.getOrPut(o.gpa, decl_val);
3055 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;3057 if (gop.found_existing) {
3058 // Keep the greater of the two alignments.
3059 const variable_index = gop.value_ptr.ptr(&o.builder).kind.variable;
3060 const old_alignment = InternPool.Alignment.fromLlvm(variable_index.getAlignment(&o.builder));
3061 const max_alignment = old_alignment.maxStrict(alignment);
3062 variable_index.setAlignment(max_alignment.toLlvm(), &o.builder);
3063 return variable_index;
3064 }
3056 errdefer assert(o.anon_decl_map.remove(decl_val));3065 errdefer assert(o.anon_decl_map.remove(decl_val));
30573066
3058 const mod = o.module;3067 const mod = o.module;
...@@ -3068,6 +3077,7 @@ pub const Object = struct {...@@ -3068,6 +3077,7 @@ pub const Object = struct {
3068 try variable_index.setInitializer(try o.lowerValue(decl_val), &o.builder);3077 try variable_index.setInitializer(try o.lowerValue(decl_val), &o.builder);
3069 variable_index.setLinkage(.internal, &o.builder);3078 variable_index.setLinkage(.internal, &o.builder);
3070 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);3079 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
3080 variable_index.setAlignment(alignment.toLlvm(), &o.builder);
3071 return variable_index;3081 return variable_index;
3072 }3082 }
30733083
...@@ -4250,13 +4260,6 @@ pub const Object = struct {...@@ -4250,13 +4260,6 @@ pub const Object = struct {
4250 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);4260 return o.builder.bigIntConst(try o.builder.intType(ty.intInfo(mod).bits), bigint);
4251 }4261 }
42524262
4253 fn lowerParentPtrAnonDecl(o: *Object, decl_val: InternPool.Index) Error!Builder.Constant {
4254 const mod = o.module;
4255 const decl_ty = mod.intern_pool.typeOf(decl_val).toType();
4256 const ptr_ty = try mod.singleMutPtrType(decl_ty);
4257 return o.lowerAnonDeclRef(ptr_ty, decl_val);
4258 }
4259
4260 fn lowerParentPtrDecl(o: *Object, decl_index: Module.Decl.Index) Allocator.Error!Builder.Constant {4263 fn lowerParentPtrDecl(o: *Object, decl_index: Module.Decl.Index) Allocator.Error!Builder.Constant {
4261 const mod = o.module;4264 const mod = o.module;
4262 const decl = mod.declPtr(decl_index);4265 const decl = mod.declPtr(decl_index);
...@@ -4272,7 +4275,7 @@ pub const Object = struct {...@@ -4272,7 +4275,7 @@ pub const Object = struct {
4272 return switch (ptr.addr) {4275 return switch (ptr.addr) {
4273 .decl => |decl| try o.lowerParentPtrDecl(decl),4276 .decl => |decl| try o.lowerParentPtrDecl(decl),
4274 .mut_decl => |mut_decl| try o.lowerParentPtrDecl(mut_decl.decl),4277 .mut_decl => |mut_decl| try o.lowerParentPtrDecl(mut_decl.decl),
4275 .anon_decl => |anon_decl| try o.lowerParentPtrAnonDecl(anon_decl),4278 .anon_decl => |ad| try o.lowerAnonDeclRef(ad.orig_ty.toType(), ad),
4276 .int => |int| try o.lowerIntAsPtr(int),4279 .int => |int| try o.lowerIntAsPtr(int),
4277 .eu_payload => |eu_ptr| {4280 .eu_payload => |eu_ptr| {
4278 const parent_ptr = try o.lowerParentPtr(eu_ptr.toValue());4281 const parent_ptr = try o.lowerParentPtr(eu_ptr.toValue());
...@@ -4391,10 +4394,11 @@ pub const Object = struct {...@@ -4391,10 +4394,11 @@ pub const Object = struct {
4391 fn lowerAnonDeclRef(4394 fn lowerAnonDeclRef(
4392 o: *Object,4395 o: *Object,
4393 ptr_ty: Type,4396 ptr_ty: Type,
4394 decl_val: InternPool.Index,4397 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
4395 ) Error!Builder.Constant {4398 ) Error!Builder.Constant {
4396 const mod = o.module;4399 const mod = o.module;
4397 const ip = &mod.intern_pool;4400 const ip = &mod.intern_pool;
4401 const decl_val = anon_decl.val;
4398 const decl_ty = ip.typeOf(decl_val).toType();4402 const decl_ty = ip.typeOf(decl_val).toType();
4399 const target = mod.getTarget();4403 const target = mod.getTarget();
44004404
...@@ -4413,9 +4417,10 @@ pub const Object = struct {...@@ -4413,9 +4417,10 @@ pub const Object = struct {
4413 if (is_fn_body)4417 if (is_fn_body)
4414 @panic("TODO");4418 @panic("TODO");
44154419
4416 const addr_space = target_util.defaultAddressSpace(target, .global_constant);4420 const orig_ty = anon_decl.orig_ty.toType();
4417 const llvm_addr_space = toLlvmAddressSpace(addr_space, target);4421 const llvm_addr_space = toLlvmAddressSpace(orig_ty.ptrAddressSpace(mod), target);
4418 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space)).ptrConst(&o.builder).global;4422 const alignment = orig_ty.ptrAlignment(mod);
4423 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
44194424
4420 const llvm_val = try o.builder.convConst(4425 const llvm_val = try o.builder.convConst(
4421 .unneeded,4426 .unneeded,
src/codegen/llvm/Builder.zig+6
...@@ -2477,6 +2477,12 @@ pub const Variable = struct {...@@ -2477,6 +2477,12 @@ pub const Variable = struct {
2477 self.ptr(builder).alignment = alignment;2477 self.ptr(builder).alignment = alignment;
2478 }2478 }
24792479
2480 pub fn getAlignment(self: Index, builder: *Builder) Alignment {
2481 if (builder.useLibLlvm())
2482 return Alignment.fromByteUnits(self.toLlvm(builder).getAlignment());
2483 return self.ptr(builder).alignment;
2484 }
2485
2480 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {2486 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
2481 return self.ptrConst(builder).global.toLlvm(builder);2487 return self.ptrConst(builder).global.toLlvm(builder);
2482 }2488 }
src/codegen/llvm/bindings.zig+3
...@@ -273,6 +273,9 @@ pub const Value = opaque {...@@ -273,6 +273,9 @@ pub const Value = opaque {
273 pub const setAlignment = LLVMSetAlignment;273 pub const setAlignment = LLVMSetAlignment;
274 extern fn LLVMSetAlignment(V: *Value, Bytes: c_uint) void;274 extern fn LLVMSetAlignment(V: *Value, Bytes: c_uint) void;
275275
276 pub const getAlignment = LLVMGetAlignment;
277 extern fn LLVMGetAlignment(V: *Value) c_uint;
278
276 pub const setFunctionCallConv = LLVMSetFunctionCallConv;279 pub const setFunctionCallConv = LLVMSetFunctionCallConv;
277 extern fn LLVMSetFunctionCallConv(Fn: *Value, CC: CallConv) void;280 extern fn LLVMSetFunctionCallConv(Fn: *Value, CC: CallConv) void;
278281
src/codegen/spirv.zig+6-1
...@@ -959,12 +959,17 @@ const DeclGen = struct {...@@ -959,12 +959,17 @@ const DeclGen = struct {
959 }959 }
960 }960 }
961961
962 fn constantAnonDeclRef(self: *DeclGen, ty: Type, decl_val: InternPool.Index) !IdRef {962 fn constantAnonDeclRef(
963 self: *DeclGen,
964 ty: Type,
965 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
966 ) !IdRef {
963 // TODO: Merge this function with constantDeclRef.967 // TODO: Merge this function with constantDeclRef.
964968
965 const mod = self.module;969 const mod = self.module;
966 const ip = &mod.intern_pool;970 const ip = &mod.intern_pool;
967 const ty_ref = try self.resolveType(ty, .direct);971 const ty_ref = try self.resolveType(ty, .direct);
972 const decl_val = anon_decl.val;
968 const decl_ty = ip.typeOf(decl_val).toType();973 const decl_ty = ip.typeOf(decl_val).toType();
969974
970 if (decl_val.toValue().getFunction(mod)) |func| {975 if (decl_val.toValue().getFunction(mod)) |func| {
src/link.zig+5-5
...@@ -940,15 +940,15 @@ pub const File = struct {...@@ -940,15 +940,15 @@ pub const File = struct {
940940
941 pub const LowerResult = @import("codegen.zig").Result;941 pub const LowerResult = @import("codegen.zig").Result;
942942
943 pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !LowerResult {943 pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult {
944 if (build_options.only_c) unreachable;944 if (build_options.only_c) unreachable;
945 switch (base.tag) {945 switch (base.tag) {
946 .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, src_loc),946 .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
947 .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, src_loc),947 .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
948 .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, src_loc),948 .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
949 .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc),949 .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc),
950 .c => unreachable,950 .c => unreachable,
951 .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, src_loc),951 .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
952 .spirv => unreachable,952 .spirv => unreachable,
953 .nvptx => unreachable,953 .nvptx => unreachable,
954 }954 }
src/link/C.zig+18-1
...@@ -7,6 +7,7 @@ const fs = std.fs;...@@ -7,6 +7,7 @@ const fs = std.fs;
7const C = @This();7const C = @This();
8const Module = @import("../Module.zig");8const Module = @import("../Module.zig");
9const InternPool = @import("../InternPool.zig");9const InternPool = @import("../InternPool.zig");
10const Alignment = InternPool.Alignment;
10const Compilation = @import("../Compilation.zig");11const Compilation = @import("../Compilation.zig");
11const codegen = @import("../codegen/c.zig");12const codegen = @import("../codegen/c.zig");
12const link = @import("../link.zig");13const link = @import("../link.zig");
...@@ -30,6 +31,10 @@ string_bytes: std.ArrayListUnmanaged(u8) = .{},...@@ -30,6 +31,10 @@ string_bytes: std.ArrayListUnmanaged(u8) = .{},
30/// Tracks all the anonymous decls that are used by all the decls so they can31/// Tracks all the anonymous decls that are used by all the decls so they can
31/// be rendered during flush().32/// be rendered during flush().
32anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{},33anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{},
34/// Sparse set of anon decls that are overaligned. Underaligned anon decls are
35/// lowered the same as ABI-aligned anon decls. The keys here are a subset of
36/// the keys of `anon_decls`.
37aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{},
3338
34/// Optimization, `updateDecl` reuses this buffer rather than creating a new39/// Optimization, `updateDecl` reuses this buffer rather than creating a new
35/// one with every call.40/// one with every call.
...@@ -125,6 +130,7 @@ pub fn deinit(self: *C) void {...@@ -125,6 +130,7 @@ pub fn deinit(self: *C) void {
125 db.deinit(gpa);130 db.deinit(gpa);
126 }131 }
127 self.anon_decls.deinit(gpa);132 self.anon_decls.deinit(gpa);
133 self.aligned_anon_decls.deinit(gpa);
128134
129 self.string_bytes.deinit(gpa);135 self.string_bytes.deinit(gpa);
130 self.fwd_decl_buf.deinit(gpa);136 self.fwd_decl_buf.deinit(gpa);
...@@ -179,6 +185,7 @@ pub fn updateFunc(...@@ -179,6 +185,7 @@ pub fn updateFunc(
179 .fwd_decl = fwd_decl.toManaged(gpa),185 .fwd_decl = fwd_decl.toManaged(gpa),
180 .ctypes = ctypes.*,186 .ctypes = ctypes.*,
181 .anon_decl_deps = self.anon_decls,187 .anon_decl_deps = self.anon_decls,
188 .aligned_anon_decls = self.aligned_anon_decls,
182 },189 },
183 .code = code.toManaged(gpa),190 .code = code.toManaged(gpa),
184 .indent_writer = undefined, // set later so we can get a pointer to object.code191 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -189,6 +196,7 @@ pub fn updateFunc(...@@ -189,6 +196,7 @@ pub fn updateFunc(
189 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };196 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
190 defer {197 defer {
191 self.anon_decls = function.object.dg.anon_decl_deps;198 self.anon_decls = function.object.dg.anon_decl_deps;
199 self.aligned_anon_decls = function.object.dg.aligned_anon_decls;
192 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();200 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();
193 code.* = function.object.code.moveToUnmanaged();201 code.* = function.object.code.moveToUnmanaged();
194 function.deinit();202 function.deinit();
...@@ -232,6 +240,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -232,6 +240,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
232 .fwd_decl = fwd_decl.toManaged(gpa),240 .fwd_decl = fwd_decl.toManaged(gpa),
233 .ctypes = .{},241 .ctypes = .{},
234 .anon_decl_deps = self.anon_decls,242 .anon_decl_deps = self.anon_decls,
243 .aligned_anon_decls = self.aligned_anon_decls,
235 },244 },
236 .code = code.toManaged(gpa),245 .code = code.toManaged(gpa),
237 .indent_writer = undefined, // set later so we can get a pointer to object.code246 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -240,6 +249,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -240,6 +249,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
240249
241 defer {250 defer {
242 self.anon_decls = object.dg.anon_decl_deps;251 self.anon_decls = object.dg.anon_decl_deps;
252 self.aligned_anon_decls = object.dg.aligned_anon_decls;
243 object.dg.ctypes.deinit(object.dg.gpa);253 object.dg.ctypes.deinit(object.dg.gpa);
244 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();254 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
245 code.* = object.code.moveToUnmanaged();255 code.* = object.code.moveToUnmanaged();
...@@ -250,7 +260,8 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {...@@ -250,7 +260,8 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
250 .val = anon_decl.toValue(),260 .val = anon_decl.toValue(),
251 };261 };
252 const c_value: codegen.CValue = .{ .constant = anon_decl };262 const c_value: codegen.CValue = .{ .constant = anon_decl };
253 codegen.genDeclValue(&object, tv, false, c_value, .none, .none) catch |err| switch (err) {263 const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;
264 codegen.genDeclValue(&object, tv, false, c_value, alignment, .none) catch |err| switch (err) {
254 error.AnalysisFail => {265 error.AnalysisFail => {
255 @panic("TODO: C backend AnalysisFail on anonymous decl");266 @panic("TODO: C backend AnalysisFail on anonymous decl");
256 //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);267 //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
...@@ -296,6 +307,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -296,6 +307,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
296 .fwd_decl = fwd_decl.toManaged(gpa),307 .fwd_decl = fwd_decl.toManaged(gpa),
297 .ctypes = ctypes.*,308 .ctypes = ctypes.*,
298 .anon_decl_deps = self.anon_decls,309 .anon_decl_deps = self.anon_decls,
310 .aligned_anon_decls = self.aligned_anon_decls,
299 },311 },
300 .code = code.toManaged(gpa),312 .code = code.toManaged(gpa),
301 .indent_writer = undefined, // set later so we can get a pointer to object.code313 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -303,6 +315,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi...@@ -303,6 +315,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
303 object.indent_writer = .{ .underlying_writer = object.code.writer() };315 object.indent_writer = .{ .underlying_writer = object.code.writer() };
304 defer {316 defer {
305 self.anon_decls = object.dg.anon_decl_deps;317 self.anon_decls = object.dg.anon_decl_deps;
318 self.aligned_anon_decls = object.dg.aligned_anon_decls;
306 object.dg.ctypes.deinit(object.dg.gpa);319 object.dg.ctypes.deinit(object.dg.gpa);
307 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();320 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
308 code.* = object.code.moveToUnmanaged();321 code.* = object.code.moveToUnmanaged();
...@@ -602,6 +615,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {...@@ -602,6 +615,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
602 .fwd_decl = fwd_decl.toManaged(gpa),615 .fwd_decl = fwd_decl.toManaged(gpa),
603 .ctypes = ctypes.*,616 .ctypes = ctypes.*,
604 .anon_decl_deps = self.anon_decls,617 .anon_decl_deps = self.anon_decls,
618 .aligned_anon_decls = self.aligned_anon_decls,
605 },619 },
606 .code = code.toManaged(gpa),620 .code = code.toManaged(gpa),
607 .indent_writer = undefined, // set later so we can get a pointer to object.code621 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -609,6 +623,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {...@@ -609,6 +623,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
609 object.indent_writer = .{ .underlying_writer = object.code.writer() };623 object.indent_writer = .{ .underlying_writer = object.code.writer() };
610 defer {624 defer {
611 self.anon_decls = object.dg.anon_decl_deps;625 self.anon_decls = object.dg.anon_decl_deps;
626 self.aligned_anon_decls = object.dg.aligned_anon_decls;
612 object.dg.ctypes.deinit(gpa);627 object.dg.ctypes.deinit(gpa);
613 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();628 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
614 code.* = object.code.moveToUnmanaged();629 code.* = object.code.moveToUnmanaged();
...@@ -642,6 +657,7 @@ fn flushLazyFn(...@@ -642,6 +657,7 @@ fn flushLazyFn(
642 .fwd_decl = fwd_decl.toManaged(gpa),657 .fwd_decl = fwd_decl.toManaged(gpa),
643 .ctypes = ctypes.*,658 .ctypes = ctypes.*,
644 .anon_decl_deps = .{},659 .anon_decl_deps = .{},
660 .aligned_anon_decls = .{},
645 },661 },
646 .code = code.toManaged(gpa),662 .code = code.toManaged(gpa),
647 .indent_writer = undefined, // set later so we can get a pointer to object.code663 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -651,6 +667,7 @@ fn flushLazyFn(...@@ -651,6 +667,7 @@ fn flushLazyFn(
651 // If this assert trips just handle the anon_decl_deps the same as667 // If this assert trips just handle the anon_decl_deps the same as
652 // `updateFunc()` does.668 // `updateFunc()` does.
653 assert(object.dg.anon_decl_deps.count() == 0);669 assert(object.dg.anon_decl_deps.count() == 0);
670 assert(object.dg.aligned_anon_decls.count() == 0);
654 object.dg.ctypes.deinit(gpa);671 object.dg.ctypes.deinit(gpa);
655 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();672 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
656 code.* = object.code.moveToUnmanaged();673 code.* = object.code.moveToUnmanaged();
src/link/Coff.zig+18-10
...@@ -1091,7 +1091,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In...@@ -1091,7 +1091,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
1091 const index = unnamed_consts.items.len;1091 const index = unnamed_consts.items.len;
1092 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });1092 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
1093 defer gpa.free(sym_name);1093 defer gpa.free(sym_name);
1094 const atom_index = switch (try self.lowerConst(sym_name, tv, self.rdata_section_index.?, decl.srcLoc(mod))) {1094 const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) {
1095 .ok => |atom_index| atom_index,1095 .ok => |atom_index| atom_index,
1096 .fail => |em| {1096 .fail => |em| {
1097 decl.analysis = .codegen_failure;1097 decl.analysis = .codegen_failure;
...@@ -1109,13 +1109,12 @@ const LowerConstResult = union(enum) {...@@ -1109,13 +1109,12 @@ const LowerConstResult = union(enum) {
1109 fail: *Module.ErrorMsg,1109 fail: *Module.ErrorMsg,
1110};1110};
11111111
1112fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {1112fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
1113 const gpa = self.base.allocator;1113 const gpa = self.base.allocator;
11141114
1115 var code_buffer = std.ArrayList(u8).init(gpa);1115 var code_buffer = std.ArrayList(u8).init(gpa);
1116 defer code_buffer.deinit();1116 defer code_buffer.deinit();
11171117
1118 const mod = self.base.options.module.?;
1119 const atom_index = try self.createAtom();1118 const atom_index = try self.createAtom();
1120 const sym = self.getAtom(atom_index).getSymbolPtr(self);1119 const sym = self.getAtom(atom_index).getSymbolPtr(self);
1121 try self.setSymbolName(sym, name);1120 try self.setSymbolName(sym, name);
...@@ -1129,10 +1128,13 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_l...@@ -1129,10 +1128,13 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_l
1129 .fail => |em| return .{ .fail = em },1128 .fail => |em| return .{ .fail = em },
1130 };1129 };
11311130
1132 const required_alignment: u32 = @intCast(tv.ty.abiAlignment(mod).toByteUnits(0));
1133 const atom = self.getAtomPtr(atom_index);1131 const atom = self.getAtomPtr(atom_index);
1134 atom.size = @as(u32, @intCast(code.len));1132 atom.size = @as(u32, @intCast(code.len));
1135 atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment);1133 atom.getSymbolPtr(self).value = try self.allocateAtom(
1134 atom_index,
1135 atom.size,
1136 @intCast(required_alignment.toByteUnitsOptional().?),
1137 );
1136 errdefer self.freeAtom(atom_index);1138 errdefer self.freeAtom(atom_index);
11371139
1138 log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(self).value });1140 log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(self).value });
...@@ -1736,7 +1738,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link...@@ -1736,7 +1738,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link
1736 return 0;1738 return 0;
1737}1739}
17381740
1739pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {1741pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
1740 // This is basically the same as lowerUnnamedConst.1742 // This is basically the same as lowerUnnamedConst.
1741 // example:1743 // example:
1742 // const ty = mod.intern_pool.typeOf(decl_val).toType();1744 // const ty = mod.intern_pool.typeOf(decl_val).toType();
...@@ -1747,15 +1749,21 @@ pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.Sr...@@ -1747,15 +1749,21 @@ pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.Sr
1747 // to put it in some location.1749 // to put it in some location.
1748 // ...1750 // ...
1749 const gpa = self.base.allocator;1751 const gpa = self.base.allocator;
1752 const mod = self.base.options.module.?;
1753 const ty = mod.intern_pool.typeOf(decl_val).toType();
1750 const gop = try self.anon_decls.getOrPut(gpa, decl_val);1754 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
1751 if (!gop.found_existing) {1755 const required_alignment = switch (decl_align) {
1752 const mod = self.base.options.module.?;1756 .none => ty.abiAlignment(mod),
1753 const ty = mod.intern_pool.typeOf(decl_val).toType();1757 else => decl_align,
1758 };
1759 if (!gop.found_existing or
1760 !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value))
1761 {
1754 const val = decl_val.toValue();1762 const val = decl_val.toValue();
1755 const tv = TypedValue{ .ty = ty, .val = val };1763 const tv = TypedValue{ .ty = ty, .val = val };
1756 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});1764 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
1757 defer gpa.free(name);1765 defer gpa.free(name);
1758 const res = self.lowerConst(name, tv, self.rdata_section_index.?, src_loc) catch |err| switch (err) {1766 const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
1759 else => {1767 else => {
1760 // TODO improve error message1768 // TODO improve error message
1761 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{1769 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
src/link/Dwarf.zig+19-14
...@@ -87,15 +87,6 @@ pub const DeclState = struct {...@@ -87,15 +87,6 @@ pub const DeclState = struct {
87 self.exprloc_relocs.deinit(self.gpa);87 self.exprloc_relocs.deinit(self.gpa);
88 }88 }
8989
90 fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void {
91 log.debug("{x}: target sym %{d}, via GOT {}", .{ offset, target, is_ptr });
92 try self.exprloc_relocs.append(self.gpa, .{
93 .type = if (is_ptr) .got_load else .direct_load,
94 .target = target,
95 .offset = offset,
96 });
97 }
98
99 /// Adds local type relocation of the form: @offset => @this + addend90 /// Adds local type relocation of the form: @offset => @this + addend
100 /// @this signifies the offset within the .debug_abbrev section of the containing atom.91 /// @this signifies the offset within the .debug_abbrev section of the containing atom.
101 fn addTypeRelocLocal(self: *DeclState, atom_index: Atom.Index, offset: u32, addend: u32) !void {92 fn addTypeRelocLocal(self: *DeclState, atom_index: Atom.Index, offset: u32, addend: u32) !void {
...@@ -807,11 +798,25 @@ pub const DeclState = struct {...@@ -807,11 +798,25 @@ pub const DeclState = struct {
807 try dbg_info.append(DW.OP.deref);798 try dbg_info.append(DW.OP.deref);
808 }799 }
809 switch (loc) {800 switch (loc) {
810 .linker_load => |load_struct| try self.addExprlocReloc(801 .linker_load => |load_struct| switch (load_struct.type) {
811 load_struct.sym_index,802 .direct => {
812 offset,803 log.debug("{x}: target sym %{d}", .{ offset, load_struct.sym_index });
813 is_ptr,804 try self.exprloc_relocs.append(self.gpa, .{
814 ),805 .type = .direct_load,
806 .target = load_struct.sym_index,
807 .offset = offset,
808 });
809 },
810 .got => {
811 log.debug("{x}: target sym %{d} via GOT", .{ offset, load_struct.sym_index });
812 try self.exprloc_relocs.append(self.gpa, .{
813 .type = .got_load,
814 .target = load_struct.sym_index,
815 .offset = offset,
816 });
817 },
818 else => {}, // TODO
819 },
815 else => {},820 else => {},
816 }821 }
817 },822 },
src/link/Elf.zig+13-8
...@@ -473,7 +473,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link....@@ -473,7 +473,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
473 return vaddr;473 return vaddr;
474}474}
475475
476pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {476pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
477 // This is basically the same as lowerUnnamedConst.477 // This is basically the same as lowerUnnamedConst.
478 // example:478 // example:
479 // const ty = mod.intern_pool.typeOf(decl_val).toType();479 // const ty = mod.intern_pool.typeOf(decl_val).toType();
...@@ -484,15 +484,21 @@ pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.Src...@@ -484,15 +484,21 @@ pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.Src
484 // to put it in some location.484 // to put it in some location.
485 // ...485 // ...
486 const gpa = self.base.allocator;486 const gpa = self.base.allocator;
487 const mod = self.base.options.module.?;
488 const ty = mod.intern_pool.typeOf(decl_val).toType();
487 const gop = try self.anon_decls.getOrPut(gpa, decl_val);489 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
488 if (!gop.found_existing) {490 const required_alignment = switch (decl_align) {
489 const mod = self.base.options.module.?;491 .none => ty.abiAlignment(mod),
490 const ty = mod.intern_pool.typeOf(decl_val).toType();492 else => decl_align,
493 };
494 if (!gop.found_existing or
495 required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt))
496 {
491 const val = decl_val.toValue();497 const val = decl_val.toValue();
492 const tv = TypedValue{ .ty = ty, .val = val };498 const tv = TypedValue{ .ty = ty, .val = val };
493 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});499 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
494 defer gpa.free(name);500 defer gpa.free(name);
495 const res = self.lowerConst(name, tv, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {501 const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
496 else => {502 else => {
497 // TODO improve error message503 // TODO improve error message
498 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{504 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
...@@ -3479,7 +3485,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module...@@ -3479,7 +3485,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
3479 const index = unnamed_consts.items.len;3485 const index = unnamed_consts.items.len;
3480 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });3486 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
3481 defer gpa.free(name);3487 defer gpa.free(name);
3482 const sym_index = switch (try self.lowerConst(name, typed_value, self.zig_rodata_section_index.?, decl.srcLoc(mod))) {3488 const sym_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.zig_rodata_section_index.?, decl.srcLoc(mod))) {
3483 .ok => |sym_index| sym_index,3489 .ok => |sym_index| sym_index,
3484 .fail => |em| {3490 .fail => |em| {
3485 decl.analysis = .codegen_failure;3491 decl.analysis = .codegen_failure;
...@@ -3502,6 +3508,7 @@ fn lowerConst(...@@ -3502,6 +3508,7 @@ fn lowerConst(
3502 self: *Elf,3508 self: *Elf,
3503 name: []const u8,3509 name: []const u8,
3504 tv: TypedValue,3510 tv: TypedValue,
3511 required_alignment: InternPool.Alignment,
3505 output_section_index: u16,3512 output_section_index: u16,
3506 src_loc: Module.SrcLoc,3513 src_loc: Module.SrcLoc,
3507) !LowerConstResult {3514) !LowerConstResult {
...@@ -3510,7 +3517,6 @@ fn lowerConst(...@@ -3510,7 +3517,6 @@ fn lowerConst(
3510 var code_buffer = std.ArrayList(u8).init(gpa);3517 var code_buffer = std.ArrayList(u8).init(gpa);
3511 defer code_buffer.deinit();3518 defer code_buffer.deinit();
35123519
3513 const mod = self.base.options.module.?;
3514 const zig_module = self.file(self.zig_module_index.?).?.zig_module;3520 const zig_module = self.file(self.zig_module_index.?).?.zig_module;
3515 const sym_index = try zig_module.addAtom(self);3521 const sym_index = try zig_module.addAtom(self);
35163522
...@@ -3524,7 +3530,6 @@ fn lowerConst(...@@ -3524,7 +3530,6 @@ fn lowerConst(
3524 .fail => |em| return .{ .fail = em },3530 .fail => |em| return .{ .fail = em },
3525 };3531 };
35263532
3527 const required_alignment = tv.ty.abiAlignment(mod);
3528 const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;3533 const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;
3529 const local_sym = self.symbol(sym_index);3534 const local_sym = self.symbol(sym_index);
3530 const name_str_index = try self.strtab.insert(gpa, name);3535 const name_str_index = try self.strtab.insert(gpa, name);
src/link/MachO.zig+13-9
...@@ -2196,7 +2196,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu...@@ -2196,7 +2196,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
2196 const index = unnamed_consts.items.len;2196 const index = unnamed_consts.items.len;
2197 const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index });2197 const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index });
2198 defer gpa.free(name);2198 defer gpa.free(name);
2199 const atom_index = switch (try self.lowerConst(name, typed_value, self.data_const_section_index.?, decl.srcLoc(mod))) {2199 const atom_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.data_const_section_index.?, decl.srcLoc(mod))) {
2200 .ok => |atom_index| atom_index,2200 .ok => |atom_index| atom_index,
2201 .fail => |em| {2201 .fail => |em| {
2202 decl.analysis = .codegen_failure;2202 decl.analysis = .codegen_failure;
...@@ -2219,6 +2219,7 @@ fn lowerConst(...@@ -2219,6 +2219,7 @@ fn lowerConst(
2219 self: *MachO,2219 self: *MachO,
2220 name: []const u8,2220 name: []const u8,
2221 tv: TypedValue,2221 tv: TypedValue,
2222 required_alignment: InternPool.Alignment,
2222 sect_id: u8,2223 sect_id: u8,
2223 src_loc: Module.SrcLoc,2224 src_loc: Module.SrcLoc,
2224) !LowerConstResult {2225) !LowerConstResult {
...@@ -2227,8 +2228,6 @@ fn lowerConst(...@@ -2227,8 +2228,6 @@ fn lowerConst(
2227 var code_buffer = std.ArrayList(u8).init(gpa);2228 var code_buffer = std.ArrayList(u8).init(gpa);
2228 defer code_buffer.deinit();2229 defer code_buffer.deinit();
22292230
2230 const mod = self.base.options.module.?;
2231
2232 log.debug("allocating symbol indexes for {s}", .{name});2231 log.debug("allocating symbol indexes for {s}", .{name});
22332232
2234 const sym_index = try self.allocateSymbol();2233 const sym_index = try self.allocateSymbol();
...@@ -2243,7 +2242,6 @@ fn lowerConst(...@@ -2243,7 +2242,6 @@ fn lowerConst(
2243 .fail => |em| return .{ .fail = em },2242 .fail => |em| return .{ .fail = em },
2244 };2243 };
22452244
2246 const required_alignment = tv.ty.abiAlignment(mod);
2247 const atom = self.getAtomPtr(atom_index);2245 const atom = self.getAtomPtr(atom_index);
2248 atom.size = code.len;2246 atom.size = code.len;
2249 // TODO: work out logic for disambiguating functions from function pointers2247 // TODO: work out logic for disambiguating functions from function pointers
...@@ -2868,7 +2866,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil...@@ -2868,7 +2866,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
2868 return 0;2866 return 0;
2869}2867}
28702868
2871pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {2869pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
2872 // This is basically the same as lowerUnnamedConst.2870 // This is basically the same as lowerUnnamedConst.
2873 // example:2871 // example:
2874 // const ty = mod.intern_pool.typeOf(decl_val).toType();2872 // const ty = mod.intern_pool.typeOf(decl_val).toType();
...@@ -2879,15 +2877,21 @@ pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.S...@@ -2879,15 +2877,21 @@ pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.S
2879 // to put it in some location.2877 // to put it in some location.
2880 // ...2878 // ...
2881 const gpa = self.base.allocator;2879 const gpa = self.base.allocator;
2880 const mod = self.base.options.module.?;
2881 const ty = mod.intern_pool.typeOf(decl_val).toType();
2882 const gop = try self.anon_decls.getOrPut(gpa, decl_val);2882 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
2883 if (!gop.found_existing) {2883 const required_alignment = switch (decl_align) {
2884 const mod = self.base.options.module.?;2884 .none => ty.abiAlignment(mod),
2885 const ty = mod.intern_pool.typeOf(decl_val).toType();2885 else => decl_align,
2886 };
2887 if (!gop.found_existing or
2888 !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value))
2889 {
2886 const val = decl_val.toValue();2890 const val = decl_val.toValue();
2887 const tv = TypedValue{ .ty = ty, .val = val };2891 const tv = TypedValue{ .ty = ty, .val = val };
2888 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});2892 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
2889 defer gpa.free(name);2893 defer gpa.free(name);
2890 const res = self.lowerConst(name, tv, self.data_const_section_index.?, src_loc) catch |err| switch (err) {2894 const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
2891 else => {2895 else => {
2892 // TODO improve error message2896 // TODO improve error message
2893 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{2897 const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
src/link/Wasm.zig+20-15
...@@ -1702,25 +1702,30 @@ pub fn getDeclVAddr(...@@ -1702,25 +1702,30 @@ pub fn getDeclVAddr(
1702 return target_symbol_index;1702 return target_symbol_index;
1703}1703}
17041704
1705pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {1705pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result {
1706 const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);1706 const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
1707 if (gop.found_existing) {1707 if (!gop.found_existing) {
1708 return .ok;1708 const mod = wasm.base.options.module.?;
1709 }1709 const ty = mod.intern_pool.typeOf(decl_val).toType();
1710 const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
1711 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
1712 defer wasm.base.allocator.free(name);
17101713
1711 const mod = wasm.base.options.module.?;1714 switch (try wasm.lowerConst(name, tv, src_loc)) {
1712 const ty = mod.intern_pool.typeOf(decl_val).toType();1715 .ok => |atom_index| gop.value_ptr.* = atom_index,
1713 const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };1716 .fail => |em| return .{ .fail = em },
1714 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});1717 }
1715 defer wasm.base.allocator.free(name);1718 }
17161719
1717 switch (try wasm.lowerConst(name, tv, src_loc)) {1720 const atom = wasm.getAtomPtr(gop.value_ptr.*);
1718 .ok => |atom_index| {1721 atom.alignment = switch (atom.alignment) {
1719 gop.value_ptr.* = atom_index;1722 .none => decl_align,
1720 return .ok;1723 else => switch (decl_align) {
1724 .none => atom.alignment,
1725 else => atom.alignment.maxStrict(decl_align),
1721 },1726 },
1722 .fail => |em| return .{ .fail = em },1727 };
1723 }1728 return .ok;
1724}1729}
17251730
1726pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1731pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
src/value.zig+2-2
...@@ -1571,7 +1571,7 @@ pub const Value = struct {...@@ -1571,7 +1571,7 @@ pub const Value = struct {
1571 .none => switch (ip.indexToKey(switch (ptr.addr) {1571 .none => switch (ip.indexToKey(switch (ptr.addr) {
1572 .decl => |decl| mod.declPtr(decl).ty.toIntern(),1572 .decl => |decl| mod.declPtr(decl).ty.toIntern(),
1573 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),1573 .mut_decl => |mut_decl| mod.declPtr(mut_decl.decl).ty.toIntern(),
1574 .anon_decl => |anon_decl| ip.typeOf(anon_decl),1574 .anon_decl => |anon_decl| ip.typeOf(anon_decl.val),
1575 .comptime_field => |comptime_field| ip.typeOf(comptime_field),1575 .comptime_field => |comptime_field| ip.typeOf(comptime_field),
1576 else => unreachable,1576 else => unreachable,
1577 })) {1577 })) {
...@@ -1604,7 +1604,7 @@ pub const Value = struct {...@@ -1604,7 +1604,7 @@ pub const Value = struct {
1604 })).toValue(),1604 })).toValue(),
1605 .ptr => |ptr| switch (ptr.addr) {1605 .ptr => |ptr| switch (ptr.addr) {
1606 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),1606 .decl => |decl| mod.declPtr(decl).val.maybeElemValue(mod, index),
1607 .anon_decl => |anon_decl| anon_decl.toValue().maybeElemValue(mod, index),1607 .anon_decl => |anon_decl| anon_decl.val.toValue().maybeElemValue(mod, index),
1608 .mut_decl => |mut_decl| (try mod.declPtr(mut_decl.decl).internValue(mod))1608 .mut_decl => |mut_decl| (try mod.declPtr(mut_decl.decl).internValue(mod))
1609 .toValue().maybeElemValue(mod, index),1609 .toValue().maybeElemValue(mod, index),
1610 .int, .eu_payload => null,1610 .int, .eu_payload => null,
test/behavior.zig-1
...@@ -37,7 +37,6 @@ test {...@@ -37,7 +37,6 @@ test {
37 _ = @import("behavior/bugs/1500.zig");37 _ = @import("behavior/bugs/1500.zig");
38 _ = @import("behavior/bugs/1607.zig");38 _ = @import("behavior/bugs/1607.zig");
39 _ = @import("behavior/bugs/1735.zig");39 _ = @import("behavior/bugs/1735.zig");
40 _ = @import("behavior/bugs/1741.zig");
41 _ = @import("behavior/bugs/1851.zig");40 _ = @import("behavior/bugs/1851.zig");
42 _ = @import("behavior/bugs/1914.zig");41 _ = @import("behavior/bugs/1914.zig");
43 _ = @import("behavior/bugs/2006.zig");42 _ = @import("behavior/bugs/2006.zig");
test/behavior/align.zig+9
...@@ -15,6 +15,15 @@ test "global variable alignment" {...@@ -15,6 +15,15 @@ test "global variable alignment" {
15 }15 }
16}16}
1717
18test "large alignment of local constant" {
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
21 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
22
23 const x: f32 align(128) = 12.34;
24 try std.testing.expect(@intFromPtr(&x) % 128 == 0);
25}
26
18test "slicing array of length 1 can not assume runtime index is always zero" {27test "slicing array of length 1 can not assume runtime index is always zero" {
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/bugs/1741.zig deleted-11
...@@ -1,11 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4test "fixed" {
5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
8
9 const x: f32 align(128) = 12.34;
10 try std.testing.expect(@intFromPtr(&x) % 128 == 0);
11}