authorgravatar for wrongnull@gmail.comBogdan Romanyuk <wrongnull@gmail.com> 2023-10-16 04:30:39+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-16 01:30:39+00:00
logebde525ccee41a8eefbb868cf4df756f1a937dd2
tree5cb5a1b6780edb493d23275d01ab958651c0a556
parentfd6b3db34252f2a548630c0e57fe80f32202aa12
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Sema: fix `@extern` error on function pointer


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

src/Sema.zig+14-4
...@@ -25277,7 +25277,7 @@ fn zirBuiltinExtern(...@@ -25277,7 +25277,7 @@ fn zirBuiltinExtern(
25277 if (!ty.isPtrAtRuntime(mod)) {25277 if (!ty.isPtrAtRuntime(mod)) {
25278 return sema.fail(block, ty_src, "expected (optional) pointer", .{});25278 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
25279 }25279 }
25280 if (!try sema.validateExternType(ty.childType(mod), .other)) {25280 if (!try sema.validateExternType(ty, .other)) {
25281 const msg = msg: {25281 const msg = msg: {
25282 const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});25282 const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
25283 errdefer msg.destroy(sema.gpa);25283 errdefer msg.destroy(sema.gpa);
...@@ -25618,7 +25618,12 @@ fn validateExternType(...@@ -25618,7 +25618,12 @@ fn validateExternType(
25618 .Float,25618 .Float,
25619 .AnyFrame,25619 .AnyFrame,
25620 => return true,25620 => return true,
25621 .Pointer => return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty)),25621 .Pointer => {
25622 if (ty.childType(mod).zigTypeTag(mod) == .Fn) {
25623 return ty.isConstPtr(mod) and try sema.validateExternType(ty.childType(mod), .other);
25624 }
25625 return !(ty.isSlice(mod) or try sema.typeRequiresComptime(ty));
25626 },
25622 .Int => switch (ty.intInfo(mod).bits) {25627 .Int => switch (ty.intInfo(mod).bits) {
25623 0, 8, 16, 32, 64, 128 => return true,25628 0, 8, 16, 32, 64, 128 => return true,
25624 else => return false,25629 else => return false,
...@@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern(...@@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern(
25687 try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});25692 try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
25688 } else {25693 } else {
25689 const pointee_ty = ty.childType(mod);25694 const pointee_ty = ty.childType(mod);
25690 try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});25695 if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
25691 try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty);25696 try mod.errNoteNonLazy(src_loc, msg, "pointer to extern function must be 'const'", .{});
25697 } else if (try sema.typeRequiresComptime(ty)) {
25698 try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
25699 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
25700 }
25701 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, position);
25692 }25702 }
25693 },25703 },
25694 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),25704 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
test/cases/compile_errors/invalid_type_in_builtin_extern.zig+7
...@@ -1,7 +1,11 @@...@@ -1,7 +1,11 @@
1const x = @extern(*comptime_int, .{ .name = "foo" });1const x = @extern(*comptime_int, .{ .name = "foo" });
2const y = @extern(*fn (u8) u8, .{ .name = "bar" });
2pub export fn entry() void {3pub export fn entry() void {
3 _ = x;4 _ = x;
4}5}
6pub export fn entry2() void {
7 _ = y;
8}
59
6// error10// error
7// backend=stage211// backend=stage2
...@@ -9,3 +13,6 @@ pub export fn entry() void {...@@ -9,3 +13,6 @@ pub export fn entry() void {
9//13//
10// :1:19: error: extern symbol cannot have type '*comptime_int'14// :1:19: error: extern symbol cannot have type '*comptime_int'
11// :1:19: note: pointer to comptime-only type 'comptime_int'15// :1:19: note: pointer to comptime-only type 'comptime_int'
16// :2:19: error: extern symbol cannot have type '*fn (u8) u8'
17// :2:19: note: pointer to extern function must be 'const'
18// :2:19: note: extern function must specify calling convention