aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2024-10-27 16:31:45 +0100
committerRobin Voetter <robin@voetter.nl>2024-10-27 16:31:45 +0100
commit49a067ccfe6cc3ee59b0fe0f2dc32f80ab75d574 (patch)
tree349a61aee17121afb7a63e37c6ce4c49073ab8cb /src/Sema.zig
parent39013619b943956f0c26422a01f026d845dc96a9 (diff)
downloadzig-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.zig36
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,