| author | |
| committer | |
| log | 3deb86bafdb2f622b9099c405e0e861f70c36a45 |
| tree | 95b57acfe21742cc527d37ab166aef2ea6deb810 |
| parent | 783a9df0b8f159062710a94bf5ee9a54002f59ed |
Closes #357303 files changed, 73 insertions(+), 2 deletions(-)
lib/std/zig/AstGen.zig+2-2| ... | @@ -3130,7 +3130,7 @@ fn varDecl( | ... | @@ -3130,7 +3130,7 @@ fn varDecl( |
| 3130 | } | 3130 | } |
| 3131 | 3131 | ||
| 3132 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node.unwrap()) |align_node| | 3132 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node.unwrap()) |align_node| |
| 3133 | try expr(gz, scope, coerced_align_ri, align_node) | 3133 | try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align") |
| 3134 | else | 3134 | else |
| 3135 | .none; | 3135 | .none; |
| 3136 | 3136 | ||
| ... | @@ -3477,7 +3477,7 @@ fn assignDestructureMaybeDecls( | ... | @@ -3477,7 +3477,7 @@ fn assignDestructureMaybeDecls( |
| 3477 | const this_variable_comptime = is_comptime or (is_const and value_is_comptime); | 3477 | const this_variable_comptime = is_comptime or (is_const and value_is_comptime); |
| 3478 | 3478 | ||
| 3479 | const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node.unwrap()) |align_node| | 3479 | const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node.unwrap()) |align_node| |
| 3480 | try expr(gz, scope, coerced_align_ri, align_node) | 3480 | try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align") |
| 3481 | else | 3481 | else |
| 3482 | .none; | 3482 | .none; |
| 3483 | 3483 |
test/behavior/align.zig+25| ... | @@ -616,3 +616,28 @@ test "function pointer align mask" { | ... | @@ -616,3 +616,28 @@ test "function pointer align mask" { |
| 616 | const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned); | 616 | const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned); |
| 617 | try expect(@intFromPtr(aligned) == int); | 617 | try expect(@intFromPtr(aligned) == int); |
| 618 | } | 618 | } |
| 619 | |||
| 620 | test "align expression is implicitly comptime" { | ||
| 621 | const S = struct { | ||
| 622 | fn alignment() usize { | ||
| 623 | return 4; | ||
| 624 | } | ||
| 625 | |||
| 626 | var global: [3]u8 align(alignment()) = @splat(0); | ||
| 627 | fn check() !void { | ||
| 628 | try std.testing.expect(@intFromPtr(&global) % alignment() == 0); | ||
| 629 | var local: [3]u8 align(alignment()) = @splat(0); | ||
| 630 | try std.testing.expect(@intFromPtr(&local) % alignment() == 0); | ||
| 631 | var de: [3]u8 align(alignment()), var structure: [3]u8 align(alignment()) = .{ @splat(0), @splat(0) }; | ||
| 632 | try std.testing.expect(@intFromPtr(&de) % alignment() == 0); | ||
| 633 | try std.testing.expect(@intFromPtr(&structure) % alignment() == 0); | ||
| 634 | var @"struct": struct { field: [3]u8 align(alignment()) } = .{ .field = @splat(0) }; | ||
| 635 | try std.testing.expect(@intFromPtr(&@"struct".field) % alignment() == 0); | ||
| 636 | var @"union": union { field: [3]u8 align(alignment()) } = .{ .field = @splat(0) }; | ||
| 637 | try std.testing.expect(@intFromPtr(&@"union".field) % alignment() == 0); | ||
| 638 | const ptr: *align(alignment()) [3]u8 = &global; | ||
| 639 | try std.testing.expect(@intFromPtr(ptr) % alignment() == 0); | ||
| 640 | } | ||
| 641 | }; | ||
| 642 | try S.check(); | ||
| 643 | } |
test/cases/compile_errors/runtime_align.zig created+46| ... | @@ -0,0 +1,46 @@ | ||
| 1 | var alignment: u29 = 4; | ||
| 2 | |||
| 3 | var global: u8 align(alignment) = 0; | ||
| 4 | export fn globalWithRuntimeAlign() u8 { | ||
| 5 | return global; | ||
| 6 | } | ||
| 7 | |||
| 8 | export fn localWithRuntimeAlign() u8 { | ||
| 9 | const local: u8 align(alignment) = 0; | ||
| 10 | return local; | ||
| 11 | } | ||
| 12 | |||
| 13 | export fn destructureWithRuntimeAlign() u8 { | ||
| 14 | const de: u8 align(alignment), const structure align(alignment) = .{ 0, 0 }; | ||
| 15 | return de | structure; | ||
| 16 | } | ||
| 17 | |||
| 18 | export fn structFieldWithRuntimeAlign() u8 { | ||
| 19 | const @"struct": struct { field: u8 align(alignment) } = .{ .field = 0 }; | ||
| 20 | return @"struct".field; | ||
| 21 | } | ||
| 22 | |||
| 23 | export fn unionFieldWithRuntimeAlign() u8 { | ||
| 24 | const @"union": union { field: u8 align(alignment) } = .{ .field = 0 }; | ||
| 25 | return @"union".field; | ||
| 26 | } | ||
| 27 | |||
| 28 | export fn pointerWithRuntimeAlign() u8 { | ||
| 29 | const ptr: *align(alignment) u8 = &global; | ||
| 30 | return ptr.*; | ||
| 31 | } | ||
| 32 | |||
| 33 | // error | ||
| 34 | // | ||
| 35 | // :3:22: error: unable to resolve comptime value | ||
| 36 | // :3:22: note: alignment must be comptime-known | ||
| 37 | // :9:27: error: unable to resolve comptime value | ||
| 38 | // :9:27: note: alignment must be comptime-known | ||
| 39 | // :14:24: error: unable to resolve comptime value | ||
| 40 | // :14:24: note: alignment must be comptime-known | ||
| 41 | // :19:47: error: unable to resolve comptime value | ||
| 42 | // :19:47: note: alignment must be comptime-known | ||
| 43 | // :24:45: error: unable to resolve comptime value | ||
| 44 | // :24:45: note: alignment must be comptime-known | ||
| 45 | // :29:23: error: unable to resolve comptime value | ||
| 46 | // :29:23: note: alignment must be comptime-known | ||