From 92f64899c110808a80c70d05e572bbd8e2448732 Mon Sep 17 00:00:00 2001 From: xdBronch <51252236+xdBronch@users.noreply.github.com> Date: Mon, 27 Oct 2025 19:41:32 -0400 Subject: [PATCH] sema: disallow slices of opaque types --- src/Sema.zig | 14 ++--- .../compile_errors/C_pointer_to_anyopaque.zig | 9 --- .../double_pointer_to_anyopaque_pointer.zig | 8 --- .../invalid_pointer_to_opaque.zig | 55 +++++++++++++++++++ .../pointer_to_anyopaque_slice.zig | 10 ---- .../unknown_length_pointer_to_opaque.zig | 5 -- test/cases/error_in_nested_declaration.zig | 2 +- 7 files changed, 60 insertions(+), 43 deletions(-) delete mode 100644 test/cases/compile_errors/C_pointer_to_anyopaque.zig create mode 100644 test/cases/compile_errors/invalid_pointer_to_opaque.zig delete mode 100644 test/cases/compile_errors/pointer_to_anyopaque_slice.zig delete mode 100644 test/cases/compile_errors/unknown_length_pointer_to_opaque.zig diff --git a/src/Sema.zig b/src/Sema.zig index 4016041d82..0b303d9ad7 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -19168,8 +19168,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air if (inst_data.size != .one) { return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); } - } else if (inst_data.size == .many and elem_ty.zigTypeTag(zcu) == .@"opaque") { - return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{}); + } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") { + return sema.fail(block, elem_ty_src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)}); } else if (inst_data.size == .c) { if (!try sema.validateExternType(elem_ty, .other)) { const msg = msg: { @@ -19183,9 +19183,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air }; return sema.failWithOwnedErrorMsg(block, msg); } - if (elem_ty.zigTypeTag(zcu) == .@"opaque") { - return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{}); - } } if (host_size != 0 and !try sema.validatePackedType(elem_ty)) { @@ -20674,8 +20671,8 @@ fn zirReify( if (ptr_size != .one) { return sema.fail(block, src, "function pointers must be single pointers", .{}); } - } else if (ptr_size == .many and elem_ty.zigTypeTag(zcu) == .@"opaque") { - return sema.fail(block, src, "unknown-length pointer to opaque not allowed", .{}); + } else if (ptr_size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") { + return sema.fail(block, src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)}); } else if (ptr_size == .c) { if (!try sema.validateExternType(elem_ty, .other)) { const msg = msg: { @@ -20689,9 +20686,6 @@ fn zirReify( }; return sema.failWithOwnedErrorMsg(block, msg); } - if (elem_ty.zigTypeTag(zcu) == .@"opaque") { - return sema.fail(block, src, "C pointers cannot point to opaque types", .{}); - } } const ty = try pt.ptrTypeSema(.{ diff --git a/test/cases/compile_errors/C_pointer_to_anyopaque.zig b/test/cases/compile_errors/C_pointer_to_anyopaque.zig deleted file mode 100644 index 10dd0ee4d1..0000000000 --- a/test/cases/compile_errors/C_pointer_to_anyopaque.zig +++ /dev/null @@ -1,9 +0,0 @@ -export fn a() void { - var x: *anyopaque = undefined; - var y: [*c]anyopaque = x; - _ = .{ &x, &y }; -} - -// error -// -// :3:16: error: C pointers cannot point to opaque types diff --git a/test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig b/test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig index d628c56f44..69a9d582d0 100644 --- a/test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig +++ b/test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig @@ -15,12 +15,6 @@ pub export fn entry3() void { const ptr: *const anyopaque = x; _ = ptr; } -export fn entry4() void { - var a: []*u32 = undefined; - _ = &a; - var b: []anyopaque = undefined; - b = a; -} // error // @@ -31,5 +25,3 @@ export fn entry4() void { // :11:12: note: parameter type declared here // :15:35: error: expected type '*const anyopaque', found '*?*usize' // :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque' -// :22:9: error: expected type '[]anyopaque', found '[]*u32' -// :22:9: note: cannot implicitly cast double pointer '[]*u32' to anyopaque pointer '[]anyopaque' diff --git a/test/cases/compile_errors/invalid_pointer_to_opaque.zig b/test/cases/compile_errors/invalid_pointer_to_opaque.zig new file mode 100644 index 0000000000..8b80b2eb25 --- /dev/null +++ b/test/cases/compile_errors/invalid_pointer_to_opaque.zig @@ -0,0 +1,55 @@ +export fn a() void { + _ = []anyopaque; +} +export fn b() void { + _ = [*]anyopaque; +} +export fn c() void { + _ = [*c]anyopaque; +} + +export fn d() void { + _ = @Type(.{ .pointer = .{ + .size = .slice, + .is_const = false, + .is_volatile = false, + .alignment = 1, + .address_space = .generic, + .child = anyopaque, + .is_allowzero = false, + .sentinel_ptr = null, + } }); +} +export fn e() void { + _ = @Type(.{ .pointer = .{ + .size = .many, + .is_const = false, + .is_volatile = false, + .alignment = 1, + .address_space = .generic, + .child = anyopaque, + .is_allowzero = false, + .sentinel_ptr = null, + } }); +} +export fn f() void { + _ = @Type(.{ .pointer = .{ + .size = .c, + .is_const = false, + .is_volatile = false, + .alignment = 1, + .address_space = .generic, + .child = anyopaque, + .is_allowzero = false, + .sentinel_ptr = null, + } }); +} + +// error +// +// :2:11: error: indexable pointer to opaque type 'anyopaque' not allowed +// :5:12: error: indexable pointer to opaque type 'anyopaque' not allowed +// :8:13: error: indexable pointer to opaque type 'anyopaque' not allowed +// :12:9: error: indexable pointer to opaque type 'anyopaque' not allowed +// :24:9: error: indexable pointer to opaque type 'anyopaque' not allowed +// :36:9: error: indexable pointer to opaque type 'anyopaque' not allowed diff --git a/test/cases/compile_errors/pointer_to_anyopaque_slice.zig b/test/cases/compile_errors/pointer_to_anyopaque_slice.zig deleted file mode 100644 index 8b9aaaacf2..0000000000 --- a/test/cases/compile_errors/pointer_to_anyopaque_slice.zig +++ /dev/null @@ -1,10 +0,0 @@ -export fn x() void { - var a: *u32 = undefined; - var b: []anyopaque = undefined; - b = a; - _ = &a; -} - -// error -// -// :4:9: error: expected type '[]anyopaque', found '*u32' diff --git a/test/cases/compile_errors/unknown_length_pointer_to_opaque.zig b/test/cases/compile_errors/unknown_length_pointer_to_opaque.zig deleted file mode 100644 index dfb8d95eb2..0000000000 --- a/test/cases/compile_errors/unknown_length_pointer_to_opaque.zig +++ /dev/null @@ -1,5 +0,0 @@ -export const T = [*]opaque {}; - -// error -// -// :1:21: error: unknown-length pointer to opaque not allowed diff --git a/test/cases/error_in_nested_declaration.zig b/test/cases/error_in_nested_declaration.zig index dba41d9ba6..92759cd151 100644 --- a/test/cases/error_in_nested_declaration.zig +++ b/test/cases/error_in_nested_declaration.zig @@ -27,4 +27,4 @@ pub export fn entry2() void { // // :6:20: error: cannot @bitCast to '[]i32' // :6:20: note: use @ptrCast to cast from '[]u32' -// :17:12: error: C pointers cannot point to opaque types +// :17:12: error: indexable pointer to opaque type 'anyopaque' not allowed