| author | |
| committer | |
| log | eac87ea8d646ccf07d25152649a9ff9ede23fc3d |
| tree | 5490d77c42080daec9443a889703f6c4d46dfc69 |
| parent | 7408679234ae84afaf0130fb21c49b031ef52e3c |
| signature |
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.3 files changed, 75 insertions(+), 5 deletions(-)
src/Zcu/PerThread.zig+27-5| ... | ... | @@ -1314,11 +1314,11 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1314 | 1314 | }; |
| 1315 | 1315 | } |
| 1316 | 1316 | |
| 1317 | const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1318 | .func => true, // mote that this lets function aliases reach codegen | |
| 1319 | .variable => |v| v.owner_nav == nav_index, | |
| 1320 | .@"extern" => false, | |
| 1321 | else => true, | |
| 1317 | const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1318 | .func => |f| .{ true, f.owner_nav == nav_index }, // note that this lets function aliases reach codegen | |
| 1319 | .variable => |v| .{ v.owner_nav == nav_index, false }, | |
| 1320 | .@"extern" => |e| .{ false, Type.fromInterned(e.ty).zigTypeTag(zcu) == .@"fn" }, | |
| 1321 | else => .{ true, false }, | |
| 1322 | 1322 | }; |
| 1323 | 1323 | |
| 1324 | 1324 | // Keep in sync with logic in `Sema.zirVarExtended`. |
| ... | ... | @@ -1363,6 +1363,28 @@ fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { |
| 1363 | 1363 | break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx); |
| 1364 | 1364 | }; |
| 1365 | 1365 | |
| 1366 | if (is_owned_fn) { | |
| 1367 | // linksection etc are legal, except some targets do not support function alignment. | |
| 1368 | if (decl_bodies.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) { | |
| 1369 | return sema.fail(&block, align_src, "target does not support function alignment", .{}); | |
| 1370 | } | |
| 1371 | } else if (try decl_ty.comptimeOnlySema(pt)) { | |
| 1372 | // alignment, linksection, addrspace annotations are not allowed for comptime-only types. | |
| 1373 | const reason: []const u8 = switch (ip.indexToKey(decl_val.toIntern())) { | |
| 1374 | .func => "function alias", // slightly clearer message, since you *can* specify these on function *declarations* | |
| 1375 | else => "comptime-only type", | |
| 1376 | }; | |
| 1377 | if (decl_bodies.align_body != null) { | |
| 1378 | return sema.fail(&block, align_src, "cannot specify alignment of {s}", .{reason}); | |
| 1379 | } | |
| 1380 | if (decl_bodies.linksection_body != null) { | |
| 1381 | return sema.fail(&block, section_src, "cannot specify linksection of {s}", .{reason}); | |
| 1382 | } | |
| 1383 | if (decl_bodies.addrspace_body != null) { | |
| 1384 | return sema.fail(&block, addrspace_src, "cannot specify addrspace of {s}", .{reason}); | |
| 1385 | } | |
| 1386 | } | |
| 1387 | ||
| 1366 | 1388 | ip.resolveNavValue(nav_index, .{ |
| 1367 | 1389 | .val = decl_val.toIntern(), |
| 1368 | 1390 | .alignment = alignment, |
test/behavior/type_info.zig+11| ... | ... | @@ -373,6 +373,17 @@ fn testFunction() !void { |
| 373 | 373 | try expect(!foo_ptr_fn_info.pointer.is_allowzero); |
| 374 | 374 | try expect(foo_ptr_fn_info.pointer.sentinel == null); |
| 375 | 375 | |
| 376 | // Avoid looking at `typeInfoFooAligned` on targets which don't support function alignment. | |
| 377 | switch (builtin.target.cpu.arch) { | |
| 378 | .spirv, | |
| 379 | .spirv32, | |
| 380 | .spirv64, | |
| 381 | .wasm32, | |
| 382 | .wasm64, | |
| 383 | => return, | |
| 384 | else => {}, | |
| 385 | } | |
| 386 | ||
| 376 | 387 | const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned); |
| 377 | 388 | const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type); |
| 378 | 389 | try expect(aligned_foo_fn_info.@"fn".calling_convention.eql(.c)); |
test/cases/compile_errors/comptime_only_global_align_section_addrspace.zig created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | fn okay_func() void {} | |
| 2 | ||
| 3 | const a align(64) = okay_func; | |
| 4 | const b addrspace(.generic) = okay_func; | |
| 5 | const c linksection("irrelevant") = okay_func; | |
| 6 | ||
| 7 | const d align(64) = 1.23; | |
| 8 | const e addrspace(.generic) = 1.23; | |
| 9 | const f linksection("irrelevant") = 1.23; | |
| 10 | ||
| 11 | const g: comptime_float align(64) = 1.23; | |
| 12 | const h: comptime_float addrspace(.generic) = 1.23; | |
| 13 | const i: comptime_float linksection("irrelevant") = 1.23; | |
| 14 | ||
| 15 | // zig fmt: off | |
| 16 | comptime { _ = a; } | |
| 17 | comptime { _ = b; } | |
| 18 | comptime { _ = c; } | |
| 19 | comptime { _ = d; } | |
| 20 | comptime { _ = e; } | |
| 21 | comptime { _ = f; } | |
| 22 | comptime { _ = g; } | |
| 23 | comptime { _ = h; } | |
| 24 | comptime { _ = i; } | |
| 25 | // zig fmt: on | |
| 26 | ||
| 27 | // error | |
| 28 | // | |
| 29 | // :3:15: error: cannot specify alignment of function alias | |
| 30 | // :4:20: error: cannot specify addrspace of function alias | |
| 31 | // :5:21: error: cannot specify linksection of function alias | |
| 32 | // :7:15: error: cannot specify alignment of comptime-only type | |
| 33 | // :8:20: error: cannot specify addrspace of comptime-only type | |
| 34 | // :9:21: error: cannot specify linksection of comptime-only type | |
| 35 | // :11:31: error: cannot specify alignment of comptime-only type | |
| 36 | // :12:36: error: cannot specify addrspace of comptime-only type | |
| 37 | // :13:37: error: cannot specify linksection of comptime-only type |