aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-07-04 14:07:08 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-07-04 14:07:08 -0700
commitf59bd2be539ce736d2ef04d16f48980d9c02a3ab (patch)
treea45a698a1836f350fd7992c7749932e4e1232f73 /src
parent6db190cf708d6ddb1c51d294c6f5a9416106277f (diff)
parentd65e248ed130da21e554807c8ce6add9773e0670 (diff)
downloadzig-f59bd2be539ce736d2ef04d16f48980d9c02a3ab.tar.gz
zig-f59bd2be539ce736d2ef04d16f48980d9c02a3ab.zip
Merge remote-tracking branch 'origin/master' into llvm14
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig34
-rw-r--r--src/link.zig1
-rw-r--r--src/link/Elf.zig4
-rw-r--r--src/translate_c.zig19
4 files changed, 44 insertions, 14 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 99b502dbd7..feb9fedceb 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -2321,7 +2321,12 @@ pub fn update(comp: *Compilation) !void {
}
fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
- try comp.bin_file.flush(comp, prog_node); // This is needed before reading the error flags.
+ // This is needed before reading the error flags.
+ comp.bin_file.flush(comp, prog_node) catch |err| switch (err) {
+ error.FlushFailure => {}, // error reported through link_error_flags
+ error.LLDReportedFailure => {}, // error reported through log.err
+ else => |e| return e,
+ };
comp.link_error_flags = comp.bin_file.errorFlags();
const use_stage1 = build_options.omit_stage2 or
@@ -2593,10 +2598,11 @@ pub fn totalErrorCount(self: *Compilation) usize {
}
}
- // The "no entry point found" error only counts if there are no other errors.
+ // The "no entry point found" error only counts if there are no semantic analysis errors.
if (total == 0) {
total += @boolToInt(self.link_error_flags.no_entry_point_found);
}
+ total += @boolToInt(self.link_error_flags.missing_libc);
// Compile log errors only count if there are no other errors.
if (total == 0) {
@@ -2693,10 +2699,30 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
}
}
- if (errors.items.len == 0 and self.link_error_flags.no_entry_point_found) {
+ if (errors.items.len == 0) {
+ if (self.link_error_flags.no_entry_point_found) {
+ try errors.append(.{
+ .plain = .{
+ .msg = try std.fmt.allocPrint(arena_allocator, "no entry point found", .{}),
+ },
+ });
+ }
+ }
+
+ if (self.link_error_flags.missing_libc) {
+ const notes = try arena_allocator.create([2]AllErrors.Message);
+ notes.* = .{
+ .{ .plain = .{
+ .msg = try arena_allocator.dupe(u8, "run 'zig libc -h' to learn about libc installations"),
+ } },
+ .{ .plain = .{
+ .msg = try arena_allocator.dupe(u8, "run 'zig targets' to see the targets for which zig can always provide libc"),
+ } },
+ };
try errors.append(.{
.plain = .{
- .msg = try std.fmt.allocPrint(arena_allocator, "no entry point found", .{}),
+ .msg = try std.fmt.allocPrint(arena_allocator, "libc not available", .{}),
+ .notes = notes,
},
});
}
diff --git a/src/link.zig b/src/link.zig
index 6c5e876022..97eb9f8876 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -951,6 +951,7 @@ pub const File = struct {
pub const ErrorFlags = struct {
no_entry_point_found: bool = false,
+ missing_libc: bool = false,
};
pub const C = @import("link/C.zig");
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index faeb7c9d27..f7d582bae7 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1719,6 +1719,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
}
// libc dep
+ self.error_flags.missing_libc = false;
if (self.base.options.link_libc) {
if (self.base.options.libc_installation != null) {
const needs_grouping = self.base.options.link_mode == .Static;
@@ -1739,7 +1740,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
.Dynamic => "libc.so",
}));
} else {
- unreachable; // Compiler was supposed to emit an error for not being able to provide libc.
+ self.error_flags.missing_libc = true;
+ return error.FlushFailure;
}
}
}
diff --git a/src/translate_c.zig b/src/translate_c.zig
index 880daa6213..53481c8f5d 100644
--- a/src/translate_c.zig
+++ b/src/translate_c.zig
@@ -2945,7 +2945,6 @@ fn transDoWhileLoop(
defer cond_scope.deinit();
const cond = try transBoolExpr(c, &cond_scope.base, @ptrCast(*const clang.Expr, stmt.getCond()), .used);
const if_not_break = switch (cond.tag()) {
- .false_literal => return transStmt(c, scope, stmt.getBody(), .unused),
.true_literal => {
const body_node = try maybeBlockify(c, scope, stmt.getBody());
return Tag.while_true.create(c.arena, body_node);
@@ -2953,7 +2952,11 @@ fn transDoWhileLoop(
else => try Tag.if_not_break.create(c.arena, cond),
};
- const body_node = if (stmt.getBody().getStmtClass() == .CompoundStmtClass) blk: {
+ var body_node = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
+ if (body_node.isNoreturn(true)) {
+ // The body node ends in a noreturn statement. Simply put it in a while (true)
+ // in case it contains breaks or continues.
+ } else if (stmt.getBody().getStmtClass() == .CompoundStmtClass) {
// there's already a block in C, so we'll append our condition to it.
// c: do {
// c: a;
@@ -2964,12 +2967,10 @@ fn transDoWhileLoop(
// zig: b;
// zig: if (!cond) break;
// zig: }
- const node = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
- const block = node.castTag(.block).?;
+ const block = body_node.castTag(.block).?;
block.data.stmts.len += 1; // This is safe since we reserve one extra space in Scope.Block.complete.
block.data.stmts[block.data.stmts.len - 1] = if_not_break;
- break :blk node;
- } else blk: {
+ } else {
// the C statement is without a block, so we need to create a block to contain it.
// c: do
// c: a;
@@ -2979,10 +2980,10 @@ fn transDoWhileLoop(
// zig: if (!cond) break;
// zig: }
const statements = try c.arena.alloc(Node, 2);
- statements[0] = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
+ statements[0] = body_node;
statements[1] = if_not_break;
- break :blk try Tag.block.create(c.arena, .{ .label = null, .stmts = statements });
- };
+ body_node = try Tag.block.create(c.arena, .{ .label = null, .stmts = statements });
+ }
return Tag.while_true.create(c.arena, body_node);
}