Skip to content

Commit ebde525

Browse files
authored
Sema: fix @extern error on function pointer
1 parent fd6b3db commit ebde525

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

src/Sema.zig

+14-4
Original file line numberDiff line numberDiff line change
@@ -25277,7 +25277,7 @@ fn zirBuiltinExtern(
2527725277
if (!ty.isPtrAtRuntime(mod)) {
2527825278
return sema.fail(block, ty_src, "expected (optional) pointer", .{});
2527925279
}
25280-
if (!try sema.validateExternType(ty.childType(mod), .other)) {
25280+
if (!try sema.validateExternType(ty, .other)) {
2528125281
const msg = msg: {
2528225282
const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
2528325283
errdefer msg.destroy(sema.gpa);
@@ -25618,7 +25618,12 @@ fn validateExternType(
2561825618
.Float,
2561925619
.AnyFrame,
2562025620
=> 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+
},
2562225627
.Int => switch (ty.intInfo(mod).bits) {
2562325628
0, 8, 16, 32, 64, 128 => return true,
2562425629
else => return false,
@@ -25687,8 +25692,13 @@ fn explainWhyTypeIsNotExtern(
2568725692
try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
2568825693
} else {
2568925694
const pointee_ty = ty.childType(mod);
25690-
try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
25691-
try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty);
25695+
if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
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);
2569225702
}
2569325703
},
2569425704
.Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
const x = @extern(*comptime_int, .{ .name = "foo" });
2+
const y = @extern(*fn (u8) u8, .{ .name = "bar" });
23
pub export fn entry() void {
34
_ = x;
45
}
6+
pub export fn entry2() void {
7+
_ = y;
8+
}
59

610
// error
711
// backend=stage2
812
// target=native
913
//
1014
// :1:19: error: extern symbol cannot have type '*comptime_int'
1115
// :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

0 commit comments

Comments
 (0)