authorgravatar for me@sassanh.comSassan Haradji <me@sassanh.com> 2026-10-23 12:29:43+03:30
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-25 01:46:35+02:00
logdaed36ce0f883a7298aefc1857fbb190cc6efde0
tree3ade6bbdd5f4db511abfab37ff4694fa4b235422
parent0be75fc840b38906424822a3cadc78610d6b1876
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Zcu: allow align(1) on functions for targets without function alignment

Targets such as wasm32 and wasm64 do not support setting function alignment, but align(1) is a no-op and should be accepted. Reject only alignments greater than 1 on those targets. Update the compile-error tests and add a positive test covering align(1) on wasm.

5 files changed, 19 insertions(+), 10 deletions(-)

src/Zcu/PerThread.zig+7-3
...@@ -1857,9 +1857,13 @@ fn analyzeNavVal(...@@ -1857,9 +1857,13 @@ fn analyzeNavVal(
1857 };1857 };
18581858
1859 if (is_owned_fn) {1859 if (is_owned_fn) {
1860 // linksection etc are legal, except some targets do not support function alignment.1860 // linksection etc are legal, except some targets do not support function alignment
1861 if (zir_decl.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) {1861 // greater than 1. `align(1)` is a no-op, so it is allowed even on those targets.
1862 return sema.fail(&block, align_src, "target does not support function alignment", .{});1862 if (zir_decl.align_body != null and
1863 modifiers.@"align" != .@"1" and
1864 !target_util.supportsFunctionAlignment(zcu.getTarget()))
1865 {
1866 return sema.fail(&block, align_src, "target does not support function alignment greater than 1", .{});
1863 }1867 }
1864 } else if (nav_ty.comptimeOnly(zcu)) {1868 } else if (nav_ty.comptimeOnly(zcu)) {
1865 // alignment, linksection, addrspace annotations are not allowed for comptime-only types.1869 // alignment, linksection, addrspace annotations are not allowed for comptime-only types.
test/behavior/align.zig+4-4
...@@ -312,7 +312,7 @@ test "function alignment" {...@@ -312,7 +312,7 @@ test "function alignment" {
312 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO312 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
313 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;313 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
314314
315 // function alignment is a compile error on wasm315 // function alignment greater than 1 is a compile error on wasm
316 if (native_arch.isWasm()) return error.SkipZigTest;316 if (native_arch.isWasm()) return error.SkipZigTest;
317317
318 const S = struct {318 const S = struct {
...@@ -341,7 +341,7 @@ test "implicitly decreasing fn alignment" {...@@ -341,7 +341,7 @@ test "implicitly decreasing fn alignment" {
341 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO341 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
342 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;342 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
343343
344 // function alignment is a compile error on wasm344 // function alignment greater than 1 is a compile error on wasm
345 if (native_arch.isWasm()) return error.SkipZigTest;345 if (native_arch.isWasm()) return error.SkipZigTest;
346346
347 try testImplicitlyDecreaseFnAlign(alignedSmall, 1234);347 try testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
...@@ -364,7 +364,7 @@ test "@alignCast functions" {...@@ -364,7 +364,7 @@ test "@alignCast functions" {
364 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO364 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
365 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;365 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
366366
367 // function alignment is a compile error on wasm367 // function alignment greater than 1 is a compile error on wasm
368 if (native_arch.isWasm()) return error.SkipZigTest;368 if (native_arch.isWasm()) return error.SkipZigTest;
369369
370 try expect(fnExpectsOnly1(simple4) == 0x19);370 try expect(fnExpectsOnly1(simple4) == 0x19);
...@@ -510,7 +510,7 @@ test "align(N) on functions" {...@@ -510,7 +510,7 @@ test "align(N) on functions" {
510 return error.SkipZigTest;510 return error.SkipZigTest;
511 }511 }
512512
513 // function alignment is a compile error on wasm513 // function alignment greater than 1 is a compile error on wasm
514 if (native_arch.isWasm()) return error.SkipZigTest;514 if (native_arch.isWasm()) return error.SkipZigTest;
515 if (native_arch.isThumb()) return error.SkipZigTest;515 if (native_arch.isThumb()) return error.SkipZigTest;
516516
test/cases/compile_errors/align_n_expr_function_pointers_is_a_compile_error.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1export fn foo() align(1) void {1export fn foo() align(2) void {
2 return;2 return;
3}3}
44
5// error5// error
6// target=wasm32-freestanding-none6// target=wasm32-freestanding-none
7//7//
8// :1:23: error: target does not support function alignment8// :1:23: error: target does not support function alignment greater than 1
test/cases/compile_errors/function_alignment_on_unsupported_target.zig+1-1
...@@ -3,4 +3,4 @@ export fn entry() align(64) void {}...@@ -3,4 +3,4 @@ export fn entry() align(64) void {}
3// error3// error
4// target=nvptx-cuda,nvptx64-cuda,spirv32-opengl,spirv32-vulkan,spirv32-opencl,spirv64-opencl,spirv64-amdhsa,wasm32-freestanding,wasm64-freestanding4// target=nvptx-cuda,nvptx64-cuda,spirv32-opengl,spirv32-vulkan,spirv32-opencl,spirv64-opencl,spirv64-amdhsa,wasm32-freestanding,wasm64-freestanding
5//5//
6// :1:25: error: target does not support function alignment6// :1:25: error: target does not support function alignment greater than 1
test/cases/function_alignment_one_on_virtual_target.zig created+5
...@@ -0,0 +1,5 @@
1export fn foo() align(1) void {}
2
3// compile
4// backend=selfhosted
5// target=wasm32-freestanding