authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-08-27 12:55:28+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-10-12 20:36:14+02:00
log9f14681473140cd79e6d38cb2bb46a90c1be1259
tree29a1774bb986ef24679911bfb7de662a34d66ec1
parent5d429b03e3d43e937e2b517d594275034a873959
signaturelock-open Commit is signed but in an unrecognized format.

stage2: check address space cast validity


3 files changed, 41 insertions(+), 3 deletions(-)

lib/std/target.zig+11
......@@ -1157,6 +1157,17 @@ pub const Target = struct {
11571157 };
11581158 }
11591159
1160 /// Returns whether this architecture supporst the address space
1161 pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
1162 const is_nvptx = arch == .nvptx or arch == .nvptx64;
1163 return switch (address_space) {
1164 .generic => true,
1165 .fs, .gs, .ss => arch == .x86_64 or arch == .i386,
1166 .global, .constant, .local, .shared => arch == .amdgcn or is_nvptx,
1167 .param => is_nvptx,
1168 };
1169 }
1170
11601171 pub fn ptrBitWidth(arch: Arch) u16 {
11611172 switch (arch) {
11621173 .avr,
src/Sema.zig+10-2
......@@ -18181,13 +18181,21 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
1818118181 const ptr = try sema.resolveInst(extra.rhs);
1818218182 const ptr_ty = sema.typeOf(ptr);
1818318183
18184
1818418185 // TODO in addition to pointers, this instruction is supposed to work for
1818518186 // pointer-like optionals and slices.
1818618187 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
1818718188
18188 // TODO check address space cast validity.
1818918189 const src_addrspace = ptr_ty.ptrAddressSpace();
18190 _ = src_addrspace;
18190 if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) {
18191 const msg = msg: {
18192 const msg = try sema.errMsg(block, src, "invalid address space cast", .{});
18193 errdefer msg.destroy(sema.gpa);
18194 try sema.errNote(block, src, msg, "address space '{s}' is not compatible with address space '{s}'", .{ @tagName(src_addrspace), @tagName(dest_addrspace) });
18195 break :msg msg;
18196 };
18197 return sema.failWithOwnedErrorMsg(msg);
18198 }
1819118199
1819218200 const ptr_info = ptr_ty.ptrInfo().data;
1819318201 const dest_ty = try Type.ptr(sema.arena, sema.mod, .{
src/target.zig+20-1
......@@ -1,5 +1,6 @@
11const std = @import("std");
22const Type = @import("type.zig").Type;
3const AddressSpace = std.builtin.AddressSpace;
34
45pub const ArchOsAbi = struct {
56 arch: std.Target.Cpu.Arch,
......@@ -635,12 +636,30 @@ pub fn defaultAddressSpace(
635636 /// Query the default address space for functions themselves.
636637 function,
637638 },
638) std.builtin.AddressSpace {
639) AddressSpace {
639640 _ = target;
640641 _ = context;
641642 return .generic;
642643}
643644
645/// Returns true if pointers in `from` can be converted to a pointer in `to`.
646pub fn addrSpaceCastIsValid(
647 target: std.Target,
648 from: AddressSpace,
649 to: AddressSpace,
650) bool {
651 const arch = target.cpu.arch;
652 switch (arch) {
653 .x86_64, .i386 => return arch.supportsAddressSpace(from) and arch.supportsAddressSpace(to),
654 .amdgcn => {
655 const to_generic = arch.supportsAddressSpace(from) and to == .generic;
656 const from_generic = arch.supportsAddressSpace(to) and from == .generic;
657 return to_generic or from_generic;
658 },
659 else => return from == .generic and to == .generic,
660 }
661}
662
644663pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
645664 const have_float = switch (target.abi) {
646665 .gnuilp32 => return "ilp32",