authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-05-25 16:18:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-05-26 12:38:31-04:00
log6e5e7e7b1966632399a942f975af23401d3e2137
tree9b41e21c4c43cecb379bd77ab61b4f7a219777ca
parent793f820b393e0a79842b99afb008d13eb1343ed8

Compilation: fix regressed assembly diagnostics

Regressed by #17947

1 files changed, 41 insertions(+), 19 deletions(-)

src/Compilation.zig+41-19
......@@ -4568,17 +4568,18 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
45684568 // We can't know the digest until we do the C compiler invocation,
45694569 // so we need a temporary filename.
45704570 const out_obj_path = try comp.tmpFilePath(arena, o_basename);
4571 const out_diag_path = if (comp.clang_passthrough_mode)
4572 undefined
4573 else
4574 try std.fmt.allocPrint(arena, "{s}.diag", .{out_obj_path});
45754571 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
45764572 defer zig_cache_tmp_dir.close();
45774573
4578 const out_dep_path: ?[]const u8 = if (comp.disable_c_depfile or !ext.clangSupportsDepFile())
4574 const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics())
4575 null
4576 else
4577 try std.fmt.allocPrint(arena, "{s}.diag", .{out_obj_path});
4578 const out_dep_path = if (comp.disable_c_depfile or !ext.clangSupportsDepFile())
45794579 null
45804580 else
45814581 try std.fmt.allocPrint(arena, "{s}.d", .{out_obj_path});
4582
45824583 try comp.addCCArgs(arena, &argv, ext, out_dep_path, c_object.src.owner);
45834584 try argv.appendSlice(c_object.src.extra_flags);
45844585 try argv.appendSlice(c_object.src.cache_exempt_flags);
......@@ -4590,7 +4591,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
45904591 .pch => argv.appendSliceAssumeCapacity(&.{ "-Xclang", "-emit-pch", "-o", out_obj_path }),
45914592 .stdout => argv.appendAssumeCapacity("-E"),
45924593 }
4593 if (comp.clang_passthrough_mode) {
4594 if (out_diag_path) |diag_file_path| {
4595 argv.appendSliceAssumeCapacity(&.{ "--serialize-diagnostics", diag_file_path });
4596 } else if (comp.clang_passthrough_mode) {
45944597 if (comp.emit_asm != null) {
45954598 argv.appendAssumeCapacity("-S");
45964599 } else if (comp.emit_llvm_ir != null) {
......@@ -4598,8 +4601,6 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
45984601 } else if (comp.emit_llvm_bc != null) {
45994602 argv.appendAssumeCapacity("-emit-llvm");
46004603 }
4601 } else {
4602 argv.appendSliceAssumeCapacity(&.{ "--serialize-diagnostics", out_diag_path });
46034604 }
46044605
46054606 if (comp.verbose_cc) {
......@@ -4607,8 +4608,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
46074608 }
46084609
46094610 // Just to save disk space, we delete the files that are never needed again.
4610 defer if (!comp.clang_passthrough_mode) zig_cache_tmp_dir.deleteFile(std.fs.path.basename(out_diag_path)) catch |err| {
4611 log.warn("failed to delete '{s}': {s}", .{ out_diag_path, @errorName(err) });
4611 defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(std.fs.path.basename(diag_file_path)) catch |err| {
4612 log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) });
46124613 };
46134614 defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(std.fs.path.basename(dep_file_path)) catch |err| {
46144615 log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) });
......@@ -4647,14 +4648,15 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
46474648 };
46484649
46494650 switch (term) {
4650 .Exited => |code| {
4651 if (code != 0) {
4652 const bundle = CObject.Diag.Bundle.parse(comp.gpa, out_diag_path) catch |err| {
4653 log.err("{}: failed to parse clang diagnostics: {s}", .{ err, stderr });
4654 return comp.failCObj(c_object, "clang exited with code {d}", .{code});
4655 };
4656 return comp.failCObjWithOwnedDiagBundle(c_object, bundle);
4657 }
4651 .Exited => |code| if (code != 0) if (out_diag_path) |diag_file_path| {
4652 const bundle = CObject.Diag.Bundle.parse(comp.gpa, diag_file_path) catch |err| {
4653 log.err("{}: failed to parse clang diagnostics: {s}", .{ err, stderr });
4654 return comp.failCObj(c_object, "clang exited with code {d}", .{code});
4655 };
4656 return comp.failCObjWithOwnedDiagBundle(c_object, bundle);
4657 } else {
4658 log.err("clang failed with stderr: {s}", .{stderr});
4659 return comp.failCObj(c_object, "clang exited with code {d}", .{code});
46584660 },
46594661 else => {
46604662 log.err("clang terminated with stderr: {s}", .{stderr});
......@@ -5110,7 +5112,7 @@ pub fn addCCArgs(
51105112 // We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode
51115113 // we want Clang to infer it, and in normal mode we always want it off, which will be true since
51125114 // clang will detect stderr as a pipe rather than a terminal.
5113 if (!comp.clang_passthrough_mode) {
5115 if (!comp.clang_passthrough_mode and ext.clangSupportsDiagnostics()) {
51145116 // Make stderr more easily parseable.
51155117 try argv.append("-fno-caret-diagnostics");
51165118 }
......@@ -5544,6 +5546,7 @@ fn failCObjWithOwnedDiagBundle(
55445546 diag_bundle: *CObject.Diag.Bundle,
55455547) SemaError {
55465548 @setCold(true);
5549 assert(diag_bundle.diags.len > 0);
55475550 {
55485551 comp.mutex.lock();
55495552 defer comp.mutex.unlock();
......@@ -5619,6 +5622,25 @@ pub const FileExt = enum {
56195622 manifest,
56205623 unknown,
56215624
5625 pub fn clangSupportsDiagnostics(ext: FileExt) bool {
5626 return switch (ext) {
5627 .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu, .ll, .bc => true,
5628
5629 .assembly,
5630 .assembly_with_cpp,
5631 .shared_library,
5632 .object,
5633 .static_library,
5634 .zig,
5635 .def,
5636 .rc,
5637 .res,
5638 .manifest,
5639 .unknown,
5640 => false,
5641 };
5642 }
5643
56225644 pub fn clangSupportsDepFile(ext: FileExt) bool {
56235645 return switch (ext) {
56245646 .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true,