Skip to content

Commit 4831c1c

Browse files
authored
Merge pull request #12277 from Vexu/stage2-compile-errors
Stage2: validate packed struct field types
2 parents 2375658 + e47706f commit 4831c1c

20 files changed

+439
-213
lines changed

src/AstGen.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7424,7 +7424,8 @@ fn builtinCall(
74247424
const token_starts = tree.tokens.items(.start);
74257425
const node_start = token_starts[tree.firstToken(node)];
74267426
astgen.advanceSourceCursor(node_start);
7427-
const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.LineColumn{
7427+
const result = try gz.addExtendedPayload(.builtin_src, Zir.Inst.Src{
7428+
.node = gz.nodeIndexToRelative(node),
74287429
.line = astgen.source_line,
74297430
.column = astgen.source_column,
74307431
});

src/Module.zig

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,10 @@ pub const SrcLoc = struct {
21612161
.local_var_decl => tree.localVarDecl(node),
21622162
.simple_var_decl => tree.simpleVarDecl(node),
21632163
.aligned_var_decl => tree.alignedVarDecl(node),
2164+
.@"usingnamespace" => {
2165+
const node_data = tree.nodes.items(.data);
2166+
return nodeToSpan(tree, node_data[node].lhs);
2167+
},
21642168
else => unreachable,
21652169
};
21662170
if (full.ast.type_node != 0) {
@@ -2171,6 +2175,58 @@ pub const SrcLoc = struct {
21712175
const end = start + @intCast(u32, tree.tokenSlice(tok_index).len);
21722176
return Span{ .start = start, .end = end, .main = start };
21732177
},
2178+
.node_offset_var_decl_align => |node_off| {
2179+
const tree = try src_loc.file_scope.getTree(gpa);
2180+
const node = src_loc.declRelativeToNodeIndex(node_off);
2181+
const node_tags = tree.nodes.items(.tag);
2182+
const full: Ast.full.VarDecl = switch (node_tags[node]) {
2183+
.global_var_decl => tree.globalVarDecl(node),
2184+
.local_var_decl => tree.localVarDecl(node),
2185+
.simple_var_decl => tree.simpleVarDecl(node),
2186+
.aligned_var_decl => tree.alignedVarDecl(node),
2187+
else => unreachable,
2188+
};
2189+
return nodeToSpan(tree, full.ast.align_node);
2190+
},
2191+
.node_offset_var_decl_section => |node_off| {
2192+
const tree = try src_loc.file_scope.getTree(gpa);
2193+
const node = src_loc.declRelativeToNodeIndex(node_off);
2194+
const node_tags = tree.nodes.items(.tag);
2195+
const full: Ast.full.VarDecl = switch (node_tags[node]) {
2196+
.global_var_decl => tree.globalVarDecl(node),
2197+
.local_var_decl => tree.localVarDecl(node),
2198+
.simple_var_decl => tree.simpleVarDecl(node),
2199+
.aligned_var_decl => tree.alignedVarDecl(node),
2200+
else => unreachable,
2201+
};
2202+
return nodeToSpan(tree, full.ast.section_node);
2203+
},
2204+
.node_offset_var_decl_addrspace => |node_off| {
2205+
const tree = try src_loc.file_scope.getTree(gpa);
2206+
const node = src_loc.declRelativeToNodeIndex(node_off);
2207+
const node_tags = tree.nodes.items(.tag);
2208+
const full: Ast.full.VarDecl = switch (node_tags[node]) {
2209+
.global_var_decl => tree.globalVarDecl(node),
2210+
.local_var_decl => tree.localVarDecl(node),
2211+
.simple_var_decl => tree.simpleVarDecl(node),
2212+
.aligned_var_decl => tree.alignedVarDecl(node),
2213+
else => unreachable,
2214+
};
2215+
return nodeToSpan(tree, full.ast.addrspace_node);
2216+
},
2217+
.node_offset_var_decl_init => |node_off| {
2218+
const tree = try src_loc.file_scope.getTree(gpa);
2219+
const node = src_loc.declRelativeToNodeIndex(node_off);
2220+
const node_tags = tree.nodes.items(.tag);
2221+
const full: Ast.full.VarDecl = switch (node_tags[node]) {
2222+
.global_var_decl => tree.globalVarDecl(node),
2223+
.local_var_decl => tree.localVarDecl(node),
2224+
.simple_var_decl => tree.simpleVarDecl(node),
2225+
.aligned_var_decl => tree.alignedVarDecl(node),
2226+
else => unreachable,
2227+
};
2228+
return nodeToSpan(tree, full.ast.init_node);
2229+
},
21742230
.node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0),
21752231
.node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1),
21762232
.node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2),
@@ -2857,6 +2913,18 @@ pub const LazySrcLoc = union(enum) {
28572913
/// to the type expression.
28582914
/// The Decl is determined contextually.
28592915
node_offset_var_decl_ty: i32,
2916+
/// The source location points to the alignment expression of a var decl.
2917+
/// The Decl is determined contextually.
2918+
node_offset_var_decl_align: i32,
2919+
/// The source location points to the linksection expression of a var decl.
2920+
/// The Decl is determined contextually.
2921+
node_offset_var_decl_section: i32,
2922+
/// The source location points to the addrspace expression of a var decl.
2923+
/// The Decl is determined contextually.
2924+
node_offset_var_decl_addrspace: i32,
2925+
/// The source location points to the initializer of a var decl.
2926+
/// The Decl is determined contextually.
2927+
node_offset_var_decl_init: i32,
28602928
/// The source location points to a for loop condition expression,
28612929
/// found by taking this AST node index offset from the containing
28622930
/// Decl AST node, which points to a for loop AST node. Next, navigate
@@ -3098,6 +3166,10 @@ pub const LazySrcLoc = union(enum) {
30983166
.node_offset,
30993167
.node_offset_initializer,
31003168
.node_offset_var_decl_ty,
3169+
.node_offset_var_decl_align,
3170+
.node_offset_var_decl_section,
3171+
.node_offset_var_decl_addrspace,
3172+
.node_offset_var_decl_init,
31013173
.node_offset_for_cond,
31023174
.node_offset_builtin_call_arg0,
31033175
.node_offset_builtin_call_arg1,
@@ -4414,17 +4486,26 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
44144486
const body = zir.extra[extra.end..][0..extra.data.body_len];
44154487
const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand;
44164488
try wip_captures.finalize();
4417-
const src = LazySrcLoc.nodeOffset(0);
4418-
const decl_tv = try sema.resolveInstValue(&block_scope, .unneeded, result_ref, undefined);
4489+
const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 };
4490+
const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 };
4491+
const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };
4492+
const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
4493+
const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
4494+
const decl_tv = try sema.resolveInstValue(&block_scope, init_src, result_ref, undefined);
44194495
const decl_align: u32 = blk: {
44204496
const align_ref = decl.zirAlignRef();
44214497
if (align_ref == .none) break :blk 0;
4422-
break :blk try sema.resolveAlign(&block_scope, src, align_ref);
4498+
break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);
44234499
};
44244500
const decl_linksection: ?[*:0]const u8 = blk: {
44254501
const linksection_ref = decl.zirLinksectionRef();
44264502
if (linksection_ref == .none) break :blk null;
4427-
const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref, "linksection must be comptime known");
4503+
const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime known");
4504+
if (mem.indexOfScalar(u8, bytes, 0) != null) {
4505+
return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
4506+
} else if (bytes.len == 0) {
4507+
return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
4508+
}
44284509
break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
44294510
};
44304511
const target = sema.mod.getTarget();
@@ -4442,27 +4523,27 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
44424523
.constant => target_util.defaultAddressSpace(target, .global_constant),
44434524
else => unreachable,
44444525
},
4445-
else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),
4526+
else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx),
44464527
};
44474528
};
44484529

44494530
// Note this resolves the type of the Decl, not the value; if this Decl
44504531
// is a struct, for example, this resolves `type` (which needs no resolution),
44514532
// not the struct itself.
4452-
try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty);
4533+
try sema.resolveTypeLayout(&block_scope, ty_src, decl_tv.ty);
44534534

44544535
const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
44554536

44564537
if (decl.is_usingnamespace) {
44574538
if (!decl_tv.ty.eql(Type.type, mod)) {
4458-
return sema.fail(&block_scope, src, "expected type, found {}", .{
4539+
return sema.fail(&block_scope, ty_src, "expected type, found {}", .{
44594540
decl_tv.ty.fmt(mod),
44604541
});
44614542
}
44624543
var buffer: Value.ToTypeBuffer = undefined;
44634544
const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator);
44644545
if (ty.getNamespace() == null) {
4465-
return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(mod)});
4546+
return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)});
44664547
}
44674548

44684549
decl.ty = Type.type;
@@ -4508,7 +4589,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45084589
decl.analysis = .complete;
45094590
decl.generation = mod.generation;
45104591

4511-
const has_runtime_bits = try sema.fnHasRuntimeBits(&block_scope, src, decl.ty);
4592+
const has_runtime_bits = try sema.fnHasRuntimeBits(&block_scope, ty_src, decl.ty);
45124593

45134594
if (has_runtime_bits) {
45144595
// We don't fully codegen the decl until later, but we do need to reserve a global
@@ -4525,7 +4606,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45254606

45264607
const is_inline = decl.ty.fnCallingConvention() == .Inline;
45274608
if (decl.is_exported) {
4528-
const export_src = src; // TODO make this point at `export` token
4609+
const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
45294610
if (is_inline) {
45304611
return sema.fail(&block_scope, export_src, "export of inline function", .{});
45314612
}
@@ -4588,14 +4669,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45884669
decl.generation = mod.generation;
45894670

45904671
const has_runtime_bits = is_extern or
4591-
(queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, src, decl.ty));
4672+
(queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, ty_src, decl.ty));
45924673

45934674
if (has_runtime_bits) {
45944675
log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });
45954676

45964677
// Needed for codegen_decl which will call updateDecl and then the
45974678
// codegen backend wants full access to the Decl Type.
4598-
try sema.resolveTypeFully(&block_scope, src, decl.ty);
4679+
try sema.resolveTypeFully(&block_scope, ty_src, decl.ty);
45994680

46004681
try mod.comp.bin_file.allocateDeclIndexes(decl_index);
46014682
try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
@@ -4606,7 +4687,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46064687
}
46074688

46084689
if (decl.is_exported) {
4609-
const export_src = src; // TODO point to the export token
4690+
const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
46104691
// The scope needs to have the decl in it.
46114692
const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
46124693
try sema.analyzeExport(&block_scope, export_src, options, decl_index);

0 commit comments

Comments
 (0)