From 7f82c31d40dedde6e8b709d07cc836d629e09021 Mon Sep 17 00:00:00 2001 From: Ali Cheraghi Date: Mon, 29 Jun 2026 09:56:30 +0330 Subject: [PATCH] Sema: add compile error for using many-pointer in externs --- src/Sema.zig | 15 +++++++++++ src/codegen/spirv/CodeGen.zig | 2 ++ ..._storage_buffer_must_be_single_pointer.zig | 25 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 test/cases/compile_errors/extern_spirv_storage_buffer_must_be_single_pointer.zig diff --git a/src/Sema.zig b/src/Sema.zig index 10272d2a207a3b0b462df67c2a415141bf48d428..9e7e5b45885f9994ec96f33db8525233b2aaf1b3 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -24973,6 +24973,21 @@ fn zirBuiltinExtern( .location, .descriptor => {}, }; + switch (zcu.getTarget().os.tag) { + .vulkan, .opengl => switch (ptr_info.flags.address_space) { + .storage_buffer, .uniform, .push_constant => if (ptr_info.flags.size != .one) { + return sema.failWithOwnedErrorMsg(block, msg: { + 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)}); + errdefer msg.destroy(sema.gpa); + try sema.errNote(ty_src, msg, "wrap the element type in a struct containing a runtime-sized array", .{}); + break :msg msg; + }); + }, + else => {}, + }, + else => {}, + } + // TODO: error for threadlocal functions, non-const functions, etc const extern_val = try pt.getExtern(.{ diff --git a/src/codegen/spirv/CodeGen.zig b/src/codegen/spirv/CodeGen.zig index b2ce676d4db04fcfb27a8e7f9e5b75683ea3e862..17cededf80410fa15a499d949d1376d4a83e7fd9 100644 --- a/src/codegen/spirv/CodeGen.zig +++ b/src/codegen/spirv/CodeGen.zig @@ -5503,6 +5503,8 @@ fn ptrAccessChain( }); }, .vulkan, .opengl => { + assert(target.cpu.has(.spirv, .variable_pointers) or + target.cpu.has(.spirv, .variable_pointers_storage_buffer)); try cg.body.emit(gpa, .OpPtrAccessChain, .{ .id_result_type = result_ty_id, .id_result = result_id, diff --git a/test/cases/compile_errors/extern_spirv_storage_buffer_must_be_single_pointer.zig b/test/cases/compile_errors/extern_spirv_storage_buffer_must_be_single_pointer.zig new file mode 100644 index 0000000000000000000000000000000000000000..3b8ac3c8338afff5ca93773f973d399fd6c51d1b --- /dev/null +++ b/test/cases/compile_errors/extern_spirv_storage_buffer_must_be_single_pointer.zig @@ -0,0 +1,25 @@ +const a = @extern([*]addrspace(.storage_buffer) u32, .{ + .name = "a", + .decoration = .{ .descriptor = .{ .set = 0, .binding = 0 } }, +}); +const b = @extern([]addrspace(.uniform) u32, .{ + .name = "b", + .decoration = .{ .descriptor = .{ .set = 0, .binding = 1 } }, +}); +const c = @extern([*c]addrspace(.push_constant) u32, .{ .name = "c" }); +comptime { + _ = a; + _ = b; + _ = c; +} + +// error +// backend=selfhosted +// target=spirv32-vulkan +// +// :1:19: error: extern in 'storage_buffer' address space must be a single-item pointer to a struct +// :1:19: note: wrap the element type in a struct containing a runtime-sized array +// :5:19: error: extern in 'uniform' address space must be a single-item pointer to a struct +// :5:19: note: wrap the element type in a struct containing a runtime-sized array +// :9:19: error: extern in 'push_constant' address space must be a single-item pointer to a struct +// :9:19: note: wrap the element type in a struct containing a runtime-sized array -- 2.54.0