authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-03-19 11:59:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-19 19:41:23-04:00
log19331b323d15b0fa0bae7add37a03528256a119f
treefcd72015345f8524892a32102d59f966eceebb7b
parent5c3325588ef4e85e85cb201ad9328fe26bbb8dca

stage2: Correctly align decls for comptime allocs

This updates WipAnonDecl to require an alignment provided by the caller, which is needed for explicitly aligned comptime allocs.

2 files changed, 54 insertions(+), 7 deletions(-)

src/Sema.zig+39-7
......@@ -486,15 +486,19 @@ pub const Block = struct {
486486 wad.* = undefined;
487487 }
488488
489 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value) !*Decl {
489 pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value, alignment: u32) !*Decl {
490490 const sema = wad.block.sema;
491491 // Do this ahead of time because `createAnonymousDecl` depends on calling
492492 // `type.hasRuntimeBits()`.
493493 _ = try sema.typeHasRuntimeBits(wad.block, wad.src, ty);
494 const align_val = if (alignment != 0) blk: {
495 break :blk try Value.Tag.int_u64.create(wad.arena(), alignment);
496 } else Value.@"null";
494497 const new_decl = try sema.mod.createAnonymousDecl(wad.block, .{
495498 .ty = ty,
496499 .val = val,
497500 });
501 new_decl.align_val = align_val;
498502 errdefer sema.mod.abortAnonDecl(new_decl);
499503 try new_decl.finalizeNewArena(&wad.new_decl_arena);
500504 wad.finished = true;
......@@ -1644,6 +1648,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
16441648 iac.data.decl = try anon_decl.finish(
16451649 try pointee_ty.copy(anon_decl.arena()),
16461650 Value.undef,
1651 iac.data.alignment,
16471652 );
16481653 if (iac.data.alignment != 0) {
16491654 try sema.resolveTypeLayout(block, src, pointee_ty);
......@@ -2711,6 +2716,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
27112716 const new_decl = try anon_decl.finish(
27122717 try final_elem_ty.copy(anon_decl.arena()),
27132718 try store_val.copy(anon_decl.arena()),
2719 inferred_alloc.data.alignment,
27142720 );
27152721 break :d new_decl;
27162722 };
......@@ -3503,8 +3509,8 @@ fn storeToInferredAllocComptime(
35033509 iac.data.decl = try anon_decl.finish(
35043510 try operand_ty.copy(anon_decl.arena()),
35053511 try operand_val.copy(anon_decl.arena()),
3512 iac.data.alignment,
35063513 );
3507 // TODO set the alignment on the decl
35083514 return;
35093515 } else {
35103516 return sema.failWithNeededComptime(block, src);
......@@ -3583,6 +3589,7 @@ fn addStrLit(sema: *Sema, block: *Block, zir_bytes: []const u8) CompileError!Air
35833589 const new_decl = try anon_decl.finish(
35843590 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
35853591 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
3592 0, // default alignment
35863593 );
35873594
35883595 return sema.analyzeDeclRef(new_decl);
......@@ -8147,6 +8154,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
81478154 embed_file.owner_decl = try anon_decl.finish(
81488155 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), embed_file.bytes.len),
81498156 try Value.Tag.bytes.create(anon_decl.arena(), bytes_including_null),
8157 0, // default alignment
81508158 );
81518159
81528160 return sema.analyzeDeclRef(embed_file.owner_decl);
......@@ -8560,7 +8568,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
85608568 .elem_type = try lhs_info.elem_type.copy(anon_decl.arena()),
85618569 });
85628570 const val = try Value.Tag.aggregate.create(anon_decl.arena(), buf);
8563 const decl = try anon_decl.finish(ty, val);
8571 const decl = try anon_decl.finish(ty, val, 0);
85648572 if (lhs_single_ptr or rhs_single_ptr) {
85658573 return sema.analyzeDeclRef(decl);
85668574 } else {
......@@ -8733,7 +8741,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
87338741 }
87348742 break :blk try Value.Tag.aggregate.create(anon_decl.arena(), buf);
87358743 };
8736 const decl = try anon_decl.finish(final_ty, val);
8744 const decl = try anon_decl.finish(final_ty, val, 0);
87378745 if (is_single_ptr) {
87388746 return sema.analyzeDeclRef(decl);
87398747 } else {
......@@ -10384,6 +10392,7 @@ fn zirBuiltinSrc(
1038410392 const new_decl = try anon_decl.finish(
1038510393 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len - 1),
1038610394 try Value.Tag.bytes.create(anon_decl.arena(), bytes),
10395 0, // default alignment
1038710396 );
1038810397 break :blk try Value.Tag.decl_ref.create(sema.arena, new_decl);
1038910398 };
......@@ -10395,6 +10404,7 @@ fn zirBuiltinSrc(
1039510404 const new_decl = try anon_decl.finish(
1039610405 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), name.len),
1039710406 try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]),
10407 0, // default alignment
1039810408 );
1039910409 break :blk try Value.Tag.decl_ref.create(sema.arena, new_decl);
1040010410 };
......@@ -10547,6 +10557,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1054710557 params_anon_decl.arena(),
1054810558 param_vals,
1054910559 ),
10560 0, // default alignment
1055010561 );
1055110562 break :v try Value.Tag.slice.create(sema.arena, .{
1055210563 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
......@@ -10736,6 +10747,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1073610747 const new_decl = try anon_decl.finish(
1073710748 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1073810749 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
10750 0, // default alignment
1073910751 );
1074010752 break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl);
1074110753 };
......@@ -10766,6 +10778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1076610778 fields_anon_decl.arena(),
1076710779 vals,
1076810780 ),
10781 0, // default alignment
1076910782 );
1077010783
1077110784 const new_decl_val = try Value.Tag.decl_ref.create(sema.arena, new_decl);
......@@ -10844,6 +10857,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1084410857 const new_decl = try anon_decl.finish(
1084510858 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1084610859 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
10860 0, // default alignment
1084710861 );
1084810862 break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl);
1084910863 };
......@@ -10868,6 +10882,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1086810882 fields_anon_decl.arena(),
1086910883 enum_field_vals,
1087010884 ),
10885 0, // default alignment
1087110886 );
1087210887 break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
1087310888 };
......@@ -10936,6 +10951,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1093610951 const new_decl = try anon_decl.finish(
1093710952 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1093810953 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
10954 0, // default alignment
1093910955 );
1094010956 break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl);
1094110957 };
......@@ -10967,6 +10983,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1096710983 fields_anon_decl.arena(),
1096810984 try fields_anon_decl.arena().dupe(Value, union_field_vals),
1096910985 ),
10986 0, // default alignment
1097010987 );
1097110988 break :v try Value.Tag.slice.create(sema.arena, .{
1097210989 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
......@@ -11044,6 +11061,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1104411061 const new_decl = try anon_decl.finish(
1104511062 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1104611063 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
11064 0, // default alignment
1104711065 );
1104811066 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
1104911067 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
......@@ -11087,6 +11105,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1108711105 const new_decl = try anon_decl.finish(
1108811106 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1108911107 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
11108 0, // default alignment
1109011109 );
1109111110 break :v try Value.Tag.slice.create(fields_anon_decl.arena(), .{
1109211111 .ptr = try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl),
......@@ -11132,6 +11151,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1113211151 fields_anon_decl.arena(),
1113311152 try fields_anon_decl.arena().dupe(Value, struct_field_vals),
1113411153 ),
11154 0, // default alignment
1113511155 );
1113611156 break :v try Value.Tag.slice.create(sema.arena, .{
1113711157 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
......@@ -11225,6 +11245,7 @@ fn typeInfoDecls(
1122511245 const new_decl = try anon_decl.finish(
1122611246 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1122711247 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
11248 0, // default alignment
1122811249 );
1122911250 break :v try Value.Tag.slice.create(decls_anon_decl.arena(), .{
1123011251 .ptr = try Value.Tag.decl_ref.create(decls_anon_decl.arena(), new_decl),
......@@ -11251,6 +11272,7 @@ fn typeInfoDecls(
1125111272 decls_anon_decl.arena(),
1125211273 try decls_anon_decl.arena().dupe(Value, decls_vals),
1125311274 ),
11275 0, // default alignment
1125411276 );
1125511277 return try Value.Tag.slice.create(sema.arena, .{
1125611278 .ptr = try Value.Tag.decl_ref.create(sema.arena, new_decl),
......@@ -12350,6 +12372,7 @@ fn addConstantMaybeRef(
1235012372 const decl = try anon_decl.finish(
1235112373 try ty.copy(anon_decl.arena()),
1235212374 try val.copy(anon_decl.arena()),
12375 0, // default alignment
1235312376 );
1235412377 return sema.analyzeDeclRef(decl);
1235512378}
......@@ -13227,6 +13250,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1322713250 const new_decl = try anon_decl.finish(
1322813251 try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
1322913252 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
13253 0, // default alignment
1323013254 );
1323113255
1323213256 return sema.analyzeDeclRef(new_decl);
......@@ -15851,6 +15875,7 @@ fn safetyPanic(
1585115875 break :msg_inst try sema.analyzeDeclRef(try anon_decl.finish(
1585215876 try Type.Tag.array_u8.create(anon_decl.arena(), msg.len),
1585315877 try Value.Tag.bytes.create(anon_decl.arena(), msg),
15878 0, // default alignment
1585415879 ));
1585515880 };
1585615881
......@@ -16080,6 +16105,7 @@ fn fieldPtr(
1608016105 return sema.analyzeDeclRef(try anon_decl.finish(
1608116106 Type.usize,
1608216107 try Value.Tag.int_u64.create(anon_decl.arena(), inner_ty.arrayLen()),
16108 0, // default alignment
1608316109 ));
1608416110 } else {
1608516111 return sema.fail(
......@@ -16107,6 +16133,7 @@ fn fieldPtr(
1610716133 return sema.analyzeDeclRef(try anon_decl.finish(
1610816134 try slice_ptr_ty.copy(anon_decl.arena()),
1610916135 try val.slicePtr().copy(anon_decl.arena()),
16136 0, // default alignment
1611016137 ));
1611116138 }
1611216139 try sema.requireRuntimeBlock(block, src);
......@@ -16126,6 +16153,7 @@ fn fieldPtr(
1612616153 return sema.analyzeDeclRef(try anon_decl.finish(
1612716154 Type.usize,
1612816155 try Value.Tag.int_u64.create(anon_decl.arena(), val.sliceLen()),
16156 0, // default alignment
1612916157 ));
1613016158 }
1613116159 try sema.requireRuntimeBlock(block, src);
......@@ -16175,6 +16203,7 @@ fn fieldPtr(
1617516203 return sema.analyzeDeclRef(try anon_decl.finish(
1617616204 try child_type.copy(anon_decl.arena()),
1617716205 try Value.Tag.@"error".create(anon_decl.arena(), .{ .name = name }),
16206 0, // default alignment
1617816207 ));
1617916208 },
1618016209 .Union => {
......@@ -16191,6 +16220,7 @@ fn fieldPtr(
1619116220 return sema.analyzeDeclRef(try anon_decl.finish(
1619216221 try enum_ty.copy(anon_decl.arena()),
1619316222 try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32),
16223 0, // default alignment
1619416224 ));
1619516225 }
1619616226 }
......@@ -16211,6 +16241,7 @@ fn fieldPtr(
1621116241 return sema.analyzeDeclRef(try anon_decl.finish(
1621216242 try child_type.copy(anon_decl.arena()),
1621316243 try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32),
16244 0, // default alignment
1621416245 ));
1621516246 },
1621616247 .Struct, .Opaque => {
......@@ -16522,10 +16553,8 @@ fn structFieldPtrByIndex(
1652216553 const decl = try anon_decl.finish(
1652316554 try field.ty.copy(anon_decl.arena()),
1652416555 try field.default_val.copy(anon_decl.arena()),
16556 ptr_ty_data.@"align",
1652516557 );
16526 if (ptr_ty_data.@"align" != 0) {
16527 decl.align_val = field.abi_align;
16528 }
1652916558 return sema.analyzeDeclRef(decl);
1653016559 }
1653116560
......@@ -19114,6 +19143,7 @@ fn refValue(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, val: Value) !
1911419143 const decl = try anon_decl.finish(
1911519144 try ty.copy(anon_decl.arena()),
1911619145 try val.copy(anon_decl.arena()),
19146 0, // default alignment
1911719147 );
1911819148 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
1911919149 return try Value.Tag.decl_ref.create(sema.arena, decl);
......@@ -19170,6 +19200,7 @@ fn analyzeRef(
1917019200 return sema.analyzeDeclRef(try anon_decl.finish(
1917119201 try operand_ty.copy(anon_decl.arena()),
1917219202 try val.copy(anon_decl.arena()),
19203 0, // default alignment
1917319204 ));
1917419205 }
1917519206
......@@ -21614,6 +21645,7 @@ fn analyzeComptimeAlloc(
2161421645 // sub-fields. So we need to initialize with undef to allow the mechanism to expand
2161521646 // into fields/elements and have those overridden with stored values.
2161621647 Value.undef,
21648 alignment,
2161721649 );
2161821650 decl.align_val = align_val;
2161921651
test/behavior/align.zig+15
......@@ -416,3 +416,18 @@ test "align(N) on functions" {
416416fn overaligned_fn() align(0x1000) i32 {
417417 return 42;
418418}
419
420test "comptime alloc alignment" {
421 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
422 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
423 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
424 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
425 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
426
427 comptime var bytes1 = [_]u8{0};
428 _ = bytes1;
429
430 comptime var bytes2 align(256) = [_]u8{0};
431 var bytes2_addr = @ptrToInt(&bytes2);
432 try std.testing.expect(bytes2_addr & 0xff == 0);
433}