diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-07-04 14:07:08 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-04 14:07:08 -0700 |
| commit | f59bd2be539ce736d2ef04d16f48980d9c02a3ab (patch) | |
| tree | a45a698a1836f350fd7992c7749932e4e1232f73 /src | |
| parent | 6db190cf708d6ddb1c51d294c6f5a9416106277f (diff) | |
| parent | d65e248ed130da21e554807c8ce6add9773e0670 (diff) | |
| download | zig-f59bd2be539ce736d2ef04d16f48980d9c02a3ab.tar.gz zig-f59bd2be539ce736d2ef04d16f48980d9c02a3ab.zip | |
Merge remote-tracking branch 'origin/master' into llvm14
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 34 | ||||
| -rw-r--r-- | src/link.zig | 1 | ||||
| -rw-r--r-- | src/link/Elf.zig | 4 | ||||
| -rw-r--r-- | src/translate_c.zig | 19 |
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); } |
