mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
x64+aarch64: check for pointer to zero-bit type when lowering decl
Unless the pointer is a pointer to a function, if the pointee type has zero-bits, we need to return `MCValue.none` as the `Decl` has not been lowered to memory, and therefore, any GOT reference will be wrong.
This commit is contained in:
parent
4b14384989
commit
e0f5627d4a
@ -3550,6 +3550,15 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
|
||||
fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {
|
||||
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
|
||||
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
|
||||
|
||||
// TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
|
||||
if (tv.ty.zigTypeTag() == .Pointer) blk: {
|
||||
if (tv.ty.castPtrToFn()) |_| break :blk;
|
||||
if (!tv.ty.elemType2().hasRuntimeBits()) {
|
||||
return MCValue.none;
|
||||
}
|
||||
}
|
||||
|
||||
decl.alive = true;
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
|
||||
@ -3558,6 +3567,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
// Because MachO is PIE-always-on, we defer memory address resolution until
|
||||
// the linker has enough info to perform relocations.
|
||||
assert(decl.link.macho.local_sym_index != 0);
|
||||
return MCValue{ .got_load = decl.link.macho.local_sym_index };
|
||||
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
|
||||
|
||||
@ -5333,6 +5333,14 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
|
||||
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
|
||||
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
|
||||
|
||||
// TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
|
||||
if (tv.ty.zigTypeTag() == .Pointer) blk: {
|
||||
if (tv.ty.castPtrToFn()) |_| break :blk;
|
||||
if (!tv.ty.elemType2().hasRuntimeBits()) {
|
||||
return MCValue.none;
|
||||
}
|
||||
}
|
||||
|
||||
decl.alive = true;
|
||||
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
|
||||
@ -5341,6 +5349,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
// Because MachO is PIE-always-on, we defer memory address resolution until
|
||||
// the linker has enough info to perform relocations.
|
||||
assert(decl.link.macho.local_sym_index != 0);
|
||||
return MCValue{ .got_load = decl.link.macho.local_sym_index };
|
||||
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
|
||||
|
||||
@ -857,6 +857,7 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
||||
else => return emit.fail("TODO unused LEA PIE variants 0b10 and 0b11", .{}),
|
||||
};
|
||||
const atom = macho_file.atom_by_index_table.get(load_reloc.atom_index).?;
|
||||
log.debug("adding reloc of type {} to local @{d}", .{ reloc_type, load_reloc.sym_index });
|
||||
try atom.relocs.append(emit.bin_file.allocator, .{
|
||||
.offset = @intCast(u32, end_offset - 4),
|
||||
.target = .{ .local = load_reloc.sym_index },
|
||||
|
||||
@ -4286,6 +4286,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
|
||||
}
|
||||
|
||||
fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void {
|
||||
log.debug("freeUnnamedConsts for decl {*}", .{decl});
|
||||
const unnamed_consts = self.unnamed_const_atoms.getPtr(decl) orelse return;
|
||||
for (unnamed_consts.items) |atom| {
|
||||
self.freeAtom(atom, .{
|
||||
@ -4295,6 +4296,7 @@ fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void {
|
||||
self.locals_free_list.append(self.base.allocator, atom.local_sym_index) catch {};
|
||||
self.locals.items[atom.local_sym_index].n_type = 0;
|
||||
_ = self.atom_by_index_table.remove(atom.local_sym_index);
|
||||
log.debug(" adding local symbol index {d} to free list", .{atom.local_sym_index});
|
||||
atom.local_sym_index = 0;
|
||||
}
|
||||
unnamed_consts.clearAndFree(self.base.allocator);
|
||||
@ -4319,10 +4321,15 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
|
||||
self.got_entries_free_list.append(self.base.allocator, @intCast(u32, got_index)) catch {};
|
||||
self.got_entries.items[got_index] = .{ .target = .{ .local = 0 }, .atom = undefined };
|
||||
_ = self.got_entries_table.swapRemove(.{ .local = decl.link.macho.local_sym_index });
|
||||
log.debug(" adding GOT index {d} to free list (target local@{d})", .{
|
||||
got_index,
|
||||
decl.link.macho.local_sym_index,
|
||||
});
|
||||
}
|
||||
|
||||
self.locals.items[decl.link.macho.local_sym_index].n_type = 0;
|
||||
_ = self.atom_by_index_table.remove(decl.link.macho.local_sym_index);
|
||||
log.debug(" adding local symbol index {d} to free list", .{decl.link.macho.local_sym_index});
|
||||
decl.link.macho.local_sym_index = 0;
|
||||
}
|
||||
if (self.d_sym) |*d_sym| {
|
||||
|
||||
@ -399,8 +399,6 @@ fn testTakeAddressOfParameter(f: f32) !void {
|
||||
|
||||
test "pointer to void return type" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .macos) return error.SkipZigTest;
|
||||
|
||||
try testPointerToVoidReturnType();
|
||||
}
|
||||
|
||||
@ -370,8 +370,6 @@ test "empty struct method call" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.os.tag == .macos) return error.SkipZigTest; // TODO
|
||||
|
||||
const es = EmptyStruct{};
|
||||
try expect(es.method() == 1234);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user