compiler: disallow align etc annotations on comptime-only globals

This includes function aliases, but not function declarations.

Also, re-introduce a target check for function alignment which was
inadvertently removed in the prior commit.
This commit is contained in:
mlugg 2024-12-18 20:29:54 +00:00
parent 7408679234
commit eac87ea8d6
No known key found for this signature in database
GPG Key ID: 3F5B7DCCBF4AF02E
3 changed files with 75 additions and 5 deletions

View File

@ -1314,11 +1314,11 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
};
}
const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
.func => true, // mote that this lets function aliases reach codegen
.variable => |v| v.owner_nav == nav_index,
.@"extern" => false,
else => true,
const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(decl_val.toIntern())) {
.func => |f| .{ true, f.owner_nav == nav_index }, // note that this lets function aliases reach codegen
.variable => |v| .{ v.owner_nav == nav_index, false },
.@"extern" => |e| .{ false, Type.fromInterned(e.ty).zigTypeTag(zcu) == .@"fn" },
else => .{ true, false },
};
// Keep in sync with logic in `Sema.zirVarExtended`.
@ -1363,6 +1363,28 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx);
};
if (is_owned_fn) {
// linksection etc are legal, except some targets do not support function alignment.
if (decl_bodies.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) {
return sema.fail(&block, align_src, "target does not support function alignment", .{});
}
} else if (try decl_ty.comptimeOnlySema(pt)) {
// alignment, linksection, addrspace annotations are not allowed for comptime-only types.
const reason: []const u8 = switch (ip.indexToKey(decl_val.toIntern())) {
.func => "function alias", // slightly clearer message, since you *can* specify these on function *declarations*
else => "comptime-only type",
};
if (decl_bodies.align_body != null) {
return sema.fail(&block, align_src, "cannot specify alignment of {s}", .{reason});
}
if (decl_bodies.linksection_body != null) {
return sema.fail(&block, section_src, "cannot specify linksection of {s}", .{reason});
}
if (decl_bodies.addrspace_body != null) {
return sema.fail(&block, addrspace_src, "cannot specify addrspace of {s}", .{reason});
}
}
ip.resolveNavValue(nav_index, .{
.val = decl_val.toIntern(),
.alignment = alignment,

View File

@ -373,6 +373,17 @@ fn testFunction() !void {
try expect(!foo_ptr_fn_info.pointer.is_allowzero);
try expect(foo_ptr_fn_info.pointer.sentinel == null);
// Avoid looking at `typeInfoFooAligned` on targets which don't support function alignment.
switch (builtin.target.cpu.arch) {
.spirv,
.spirv32,
.spirv64,
.wasm32,
.wasm64,
=> return,
else => {},
}
const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned);
const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type);
try expect(aligned_foo_fn_info.@"fn".calling_convention.eql(.c));

View File

@ -0,0 +1,37 @@
fn okay_func() void {}
const a align(64) = okay_func;
const b addrspace(.generic) = okay_func;
const c linksection("irrelevant") = okay_func;
const d align(64) = 1.23;
const e addrspace(.generic) = 1.23;
const f linksection("irrelevant") = 1.23;
const g: comptime_float align(64) = 1.23;
const h: comptime_float addrspace(.generic) = 1.23;
const i: comptime_float linksection("irrelevant") = 1.23;
// zig fmt: off
comptime { _ = a; }
comptime { _ = b; }
comptime { _ = c; }
comptime { _ = d; }
comptime { _ = e; }
comptime { _ = f; }
comptime { _ = g; }
comptime { _ = h; }
comptime { _ = i; }
// zig fmt: on
// error
//
// :3:15: error: cannot specify alignment of function alias
// :4:20: error: cannot specify addrspace of function alias
// :5:21: error: cannot specify linksection of function alias
// :7:15: error: cannot specify alignment of comptime-only type
// :8:20: error: cannot specify addrspace of comptime-only type
// :9:21: error: cannot specify linksection of comptime-only type
// :11:31: error: cannot specify alignment of comptime-only type
// :12:36: error: cannot specify addrspace of comptime-only type
// :13:37: error: cannot specify linksection of comptime-only type