authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-06-29 09:56:30+03:30
committergravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-06-29 09:56:30+03:30
log7f82c31d40dedde6e8b709d07cc836d629e09021
tree1abbc30296331586da3c8ad394e2aa29e5d0d106
parent7991efe64c8ed37498323b1e4845756a187454d7

Sema: add compile error for using many-pointer in externs


3 files changed, 42 insertions(+), 0 deletions(-)

src/Sema.zig+15
......@@ -24973,6 +24973,21 @@ fn zirBuiltinExtern(
2497324973 .location, .descriptor => {},
2497424974 };
2497524975
24976 switch (zcu.getTarget().os.tag) {
24977 .vulkan, .opengl => switch (ptr_info.flags.address_space) {
24978 .storage_buffer, .uniform, .push_constant => if (ptr_info.flags.size != .one) {
24979 return sema.failWithOwnedErrorMsg(block, msg: {
24980 const msg = try sema.errMsg(ty_src, "extern in '{s}' address space must be a single-item pointer to a struct", .{@tagName(ptr_info.flags.address_space)});
24981 errdefer msg.destroy(sema.gpa);
24982 try sema.errNote(ty_src, msg, "wrap the element type in a struct containing a runtime-sized array", .{});
24983 break :msg msg;
24984 });
24985 },
24986 else => {},
24987 },
24988 else => {},
24989 }
24990
2497624991 // TODO: error for threadlocal functions, non-const functions, etc
2497724992
2497824993 const extern_val = try pt.getExtern(.{
src/codegen/spirv/CodeGen.zig+2
......@@ -5503,6 +5503,8 @@ fn ptrAccessChain(
55035503 });
55045504 },
55055505 .vulkan, .opengl => {
5506 assert(target.cpu.has(.spirv, .variable_pointers) or
5507 target.cpu.has(.spirv, .variable_pointers_storage_buffer));
55065508 try cg.body.emit(gpa, .OpPtrAccessChain, .{
55075509 .id_result_type = result_ty_id,
55085510 .id_result = result_id,
test/cases/compile_errors/extern_spirv_storage_buffer_must_be_single_pointer.zig created+25
......@@ -0,0 +1,25 @@
1const a = @extern([*]addrspace(.storage_buffer) u32, .{
2 .name = "a",
3 .decoration = .{ .descriptor = .{ .set = 0, .binding = 0 } },
4});
5const b = @extern([]addrspace(.uniform) u32, .{
6 .name = "b",
7 .decoration = .{ .descriptor = .{ .set = 0, .binding = 1 } },
8});
9const c = @extern([*c]addrspace(.push_constant) u32, .{ .name = "c" });
10comptime {
11 _ = a;
12 _ = b;
13 _ = c;
14}
15
16// error
17// backend=selfhosted
18// target=spirv32-vulkan
19//
20// :1:19: error: extern in 'storage_buffer' address space must be a single-item pointer to a struct
21// :1:19: note: wrap the element type in a struct containing a runtime-sized array
22// :5:19: error: extern in 'uniform' address space must be a single-item pointer to a struct
23// :5:19: note: wrap the element type in a struct containing a runtime-sized array
24// :9:19: error: extern in 'push_constant' address space must be a single-item pointer to a struct
25// :9:19: note: wrap the element type in a struct containing a runtime-sized array