diff options
| author | Robin Voetter <robin@voetter.nl> | 2024-10-27 16:31:45 +0100 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2024-10-27 16:31:45 +0100 |
| commit | 49a067ccfe6cc3ee59b0fe0f2dc32f80ab75d574 (patch) | |
| tree | 349a61aee17121afb7a63e37c6ce4c49073ab8cb /src/Sema.zig | |
| parent | 39013619b943956f0c26422a01f026d845dc96a9 (diff) | |
| download | zig-49a067ccfe6cc3ee59b0fe0f2dc32f80ab75d574.tar.gz zig-49a067ccfe6cc3ee59b0fe0f2dc32f80ab75d574.zip | |
spirv: forbid merging logical pointers
Under some architecture/operating system combinations it is forbidden
to return a pointer from a merge, as these pointers must point to a
location at compile time. This adds a check for those cases when
returning a pointer from a block merge.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index b0ce7729cf..b0ce90d277 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -6319,6 +6319,9 @@ fn resolveAnalyzedBlock( for (merges.results.items, merges.src_locs.items) |merge_inst, merge_src| { try sema.validateRuntimeValue(child_block, merge_src orelse src, merge_inst); } + + try sema.checkMergeAllowed(child_block, type_src, resolved_ty); + const ty_inst = Air.internedToRef(resolved_ty.toIntern()); switch (block_tag) { .block => { @@ -9754,6 +9757,39 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: } } +fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type) !void { + const pt = sema.pt; + const zcu = pt.zcu; + const target = zcu.getTarget(); + + if (!peer_ty.isPtrAtRuntime(zcu)) { + return; + } + + const as = peer_ty.ptrAddressSpace(zcu); + if (!target_util.arePointersLogical(target, as)) { + return; + } + + return sema.failWithOwnedErrorMsg(block, msg: { + const msg = try sema.errMsg(src, "value with non-mergable pointer type '{}' depends on runtime control flow", .{peer_ty.fmt(pt)}); + errdefer msg.destroy(sema.gpa); + + const runtime_src = block.runtime_cond orelse block.runtime_loop.?; + try sema.errNote(runtime_src, msg, "runtime control flow here", .{}); + + const backend = target_util.zigBackend(target, zcu.comp.config.use_llvm); + try sema.errNote(src, msg, "pointers with address space '{s}' cannot be returned from a branch on target {s}-{s} by compiler backend {s}", .{ + @tagName(as), + target.cpu.arch.genericName(), + @tagName(target.os.tag), + @tagName(backend), + }); + + break :msg msg; + }); +} + const Section = union(enum) { generic, default, |
