authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-07-05 09:53:39+03:30
committergravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-07-05 09:53:39+03:30
log18f2ab7882235009c9e8a45a776ae375132db247
treed535a10bd0fde4a23e0aafaad67577f2810feda3
parenteb2a1bb0d04532c84c042eaad1c3ee092c8c8a23

Sema: disallow loading spirv runtime arrays


4 files changed, 63 insertions(+), 2 deletions(-)

src/Sema.zig+9-1
......@@ -25377,12 +25377,16 @@ pub fn explainWhyTypeIsNotExtern(
2537725377 .noreturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
2537825378
2537925379 .@"opaque",
25380 .spirv,
2538125380 .bool,
2538225381 .float,
2538325382 .@"anyframe",
2538425383 => unreachable, // these *are* allowed
2538525384
25385 .spirv => {
25386 assert(ty.isSpirvRuntimeArray(zcu));
25387 try sema.errNote(src_loc, msg, "SPIR-V runtime arrays must be the last field of an extern struct", .{});
25388 },
25389
2538625390 .pointer => if (ty.isSlice(zcu)) {
2538725391 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
2538825392 } else {
......@@ -30541,6 +30545,10 @@ fn analyzeLoad(
3054130545
3054230546 try sema.ensureLayoutResolved(elem_ty, src, .ptr_access);
3054330547
30548 if (elem_ty.isSpirvRuntimeArray(zcu)) {
30549 return sema.fail(block, src, "cannot load SPIR-V runtime array value", .{});
30550 }
30551
3054430552 const comptime_only = switch (elem_ty.classify(zcu)) {
3054530553 .no_possible_value => switch (elem_ty.zigTypeTag(zcu)) {
3054630554 .@"opaque" => return sema.fail(block, src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)}),
src/Type.zig+5-1
......@@ -3119,12 +3119,16 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
31193119 .noreturn => position == .ret_ty,
31203120
31213121 .@"opaque",
3122 .spirv,
31233122 .bool,
31243123 .float,
31253124 .@"anyframe",
31263125 => true,
31273126
3127 .spirv => switch (position) {
3128 .struct_field, .union_field => true,
3129 .ret_ty, .param_ty, .element, .other => !ty.isSpirvRuntimeArray(zcu),
3130 },
3131
31283132 .pointer => {
31293133 if (ty.isSlice(zcu)) return false;
31303134 const child_ty = ty.childType(zcu);
test/cases/compile_errors/loading_spirv_runtime_array_value.zig created+23
......@@ -0,0 +1,23 @@
1const RuntimeArray = @SpirvType(.{ .runtime_array = f32 });
2const Buffer = extern struct {
3 data: RuntimeArray,
4};
5const buf = @extern(*addrspace(.storage_buffer) Buffer, .{
6 .name = "buf",
7 .decoration = .{ .descriptor = .{ .set = 0, .binding = 0 } },
8});
9export fn main() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
10 const a = buf.data;
11 _ = a;
12}
13export fn main2() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
14 const p: *addrspace(.storage_buffer) const RuntimeArray = &buf.data;
15 _ = p.*;
16}
17
18// error
19// backend=selfhosted
20// target=spirv32-vulkan
21//
22// :10:15: error: cannot load SPIR-V runtime array value
23// :15:12: error: cannot load SPIR-V runtime array value
test/cases/compile_errors/spirv_runtime_array_as_value_type.zig created+26
......@@ -0,0 +1,26 @@
1const RuntimeArray = @SpirvType(.{ .runtime_array = u32 });
2
3const a = @extern(*addrspace(.storage_buffer) RuntimeArray, .{
4 .name = "a",
5 .decoration = .{ .descriptor = .{ .set = 0, .binding = 0 } },
6});
7const b = @extern(*addrspace(.uniform) const RuntimeArray, .{
8 .name = "b",
9 .decoration = .{ .descriptor = .{ .set = 0, .binding = 1 } },
10});
11
12comptime {
13 _ = a;
14 _ = b;
15}
16
17// error
18// backend=selfhosted
19// target=spirv32-vulkan
20//
21// :3:19: error: extern symbol cannot have type '*addrspace(.storage_buffer) @SpirvType(.runtime_array, u32)'
22// :3:19: note: pointer element type '@SpirvType(.runtime_array, u32)' is not extern compatible
23// :3:19: note: SPIR-V runtime arrays must be the last field of an extern struct
24// :7:19: error: extern symbol cannot have type '*addrspace(.uniform) const @SpirvType(.runtime_array, u32)'
25// :7:19: note: pointer element type '@SpirvType(.runtime_array, u32)' is not extern compatible
26// :7:19: note: SPIR-V runtime arrays must be the last field of an extern struct