stage2: fix crash on empty source file
This commit is contained in:
@@ -949,10 +949,8 @@ pub fn update(self: *Module) !void {
|
||||
try self.deleteDecl(decl);
|
||||
}
|
||||
|
||||
if (self.totalErrorCount() == 0) {
|
||||
// This is needed before reading the error flags.
|
||||
try self.bin_file.flush();
|
||||
}
|
||||
// This is needed before reading the error flags.
|
||||
try self.bin_file.flush();
|
||||
|
||||
self.link_error_flags = self.bin_file.errorFlags();
|
||||
|
||||
@@ -2537,7 +2535,7 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst
|
||||
}
|
||||
}
|
||||
|
||||
return self.fail(scope, inst.src, "TODO implement type coercion from {} to {}", .{ inst.ty, dest_type });
|
||||
return self.fail(scope, inst.src, "expected {}, found {}", .{ dest_type, inst.ty });
|
||||
}
|
||||
|
||||
pub fn storePtr(self: *Module, scope: *Scope, src: usize, ptr: *Inst, uncasted_value: *Inst) !*Inst {
|
||||
|
||||
@@ -1172,7 +1172,10 @@ pub const File = struct {
|
||||
|
||||
self.debug_aranges_section_dirty = false;
|
||||
}
|
||||
if (self.debug_line_header_dirty) {
|
||||
if (self.debug_line_header_dirty) debug_line: {
|
||||
if (self.dbg_line_fn_first == null) {
|
||||
break :debug_line; // Error in module; leave debug_line_header_dirty=true.
|
||||
}
|
||||
const dbg_line_prg_off = self.getDebugLineProgramOff();
|
||||
const dbg_line_prg_end = self.getDebugLineProgramEnd();
|
||||
assert(dbg_line_prg_end != 0);
|
||||
@@ -1403,18 +1406,21 @@ pub const File = struct {
|
||||
self.shdr_table_dirty = false;
|
||||
}
|
||||
if (self.entry_addr == null and self.base.options.output_mode == .Exe) {
|
||||
log.debug(.link, "no_entry_point_found = true\n", .{});
|
||||
log.debug(.link, "flushing. no_entry_point_found = true\n", .{});
|
||||
self.error_flags.no_entry_point_found = true;
|
||||
} else {
|
||||
log.debug(.link, "flushing. no_entry_point_found = false\n", .{});
|
||||
self.error_flags.no_entry_point_found = false;
|
||||
try self.writeElfHeader();
|
||||
}
|
||||
|
||||
// The point of flush() is to commit changes, so nothing should be dirty after this.
|
||||
// The point of flush() is to commit changes, so in theory, nothing should
|
||||
// be dirty after this. However, it is possible for some things to remain
|
||||
// dirty because they fail to be written in the event of compile errors,
|
||||
// such as debug_line_header_dirty.
|
||||
assert(!self.debug_info_section_dirty);
|
||||
assert(!self.debug_abbrev_section_dirty);
|
||||
assert(!self.debug_aranges_section_dirty);
|
||||
assert(!self.debug_line_header_dirty);
|
||||
assert(!self.phdr_table_dirty);
|
||||
assert(!self.shdr_table_dirty);
|
||||
assert(!self.shstrtab_dirty);
|
||||
|
||||
@@ -64,6 +64,9 @@ var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
|
||||
pub fn main() !void {
|
||||
const gpa = if (std.builtin.link_libc) std.heap.c_allocator else &general_purpose_allocator.allocator;
|
||||
defer if (!std.builtin.link_libc) {
|
||||
_ = general_purpose_allocator.deinit();
|
||||
};
|
||||
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_instance.deinit();
|
||||
const arena = &arena_instance.allocator;
|
||||
|
||||
@@ -23,6 +23,9 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
|
||||
{
|
||||
var case = ctx.exe("hello world with updates", linux_x64);
|
||||
|
||||
case.addError("", &[_][]const u8{":1:1: error: no entry point found"});
|
||||
|
||||
// Regular old hello world
|
||||
case.addCompareOutput(
|
||||
\\export fn _start() noreturn {
|
||||
@@ -123,7 +126,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
var case = ctx.exe("hello world", linux_riscv64);
|
||||
// Regular old hello world
|
||||
|
||||
Reference in New Issue
Block a user