Skip to content

Aro translate c: Render error diagnostics properly and ignore _Static_assert decls during translation #20865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions lib/compiler/aro_translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ pub fn translate(
var tree = try pp.parse();
defer tree.deinit();

if (driver.comp.diagnostics.errors != 0) {
return error.SemanticAnalyzeFail;
// Workaround for https://github.com/Vexu/arocc/issues/603
for (comp.diagnostics.list.items) |msg| {
if (msg.kind == .@"error" or msg.kind == .@"fatal error") return error.ParsingFailed;
}

const mapper = tree.comp.string_interner.getFastTypeMapper(tree.comp.gpa) catch tree.comp.string_interner.getSlowTypeMapper();
Expand Down Expand Up @@ -227,6 +228,7 @@ fn prepopulateGlobalNameTable(c: *Context) !void {
const decl_name = c.tree.tokSlice(data.decl.name);
try c.global_names.put(c.gpa, decl_name, {});
},
.static_assert => {},
else => unreachable,
}
}
Expand Down Expand Up @@ -304,6 +306,7 @@ fn transDecl(c: *Context, scope: *Scope, decl: NodeIndex) !void {
=> {
try transVarDecl(c, decl, null);
},
.static_assert => try warn(c, &c.global_scope.base, 0, "ignoring _Static_assert declaration", .{}),
else => unreachable,
}
}
Expand Down Expand Up @@ -1622,6 +1625,33 @@ test "Macro matching" {
try helper.checkMacro(allocator, pattern_list, "IGNORE_ME(X) ((volatile const void)(X))", "DISCARD");
}

/// Renders errors and fatal errors + associated notes (e.g. "expanded from here"); does not render warnings or associated notes
/// Terminates with exit code 1
fn renderErrorsAndExit(comp: *aro.Compilation) noreturn {
defer std.process.exit(1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe/valid to have a defer which runs after control flow reaches the end of a noreturn function or is this too clever?

Copy link
Contributor

@rohlem rohlem Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defer statements run at the end of the current block, so afaiu the language has to allow it if you added another block scope encompassing the entire function body (that block would then be void instead of noreturn).
I'm not sure how much the compiler would gain by requiring this extra step of users, so I wouldn't see a point in disallowing it as-is.


var writer = aro.Diagnostics.defaultMsgWriter(std.io.tty.detectConfig(std.io.getStdErr()));
defer writer.deinit(); // writer deinit must run *before* exit so that stderr is flushed

var saw_error = false;
for (comp.diagnostics.list.items) |msg| {
switch (msg.kind) {
.@"error", .@"fatal error" => {
saw_error = true;
aro.Diagnostics.renderMessage(comp, &writer, msg);
},
.warning => saw_error = false,
.note => {
if (saw_error) {
aro.Diagnostics.renderMessage(comp, &writer, msg);
}
},
.off => {},
.default => unreachable,
}
}
}

pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_instance.deinit();
Expand All @@ -1636,12 +1666,9 @@ pub fn main() !void {
defer aro_comp.deinit();

var tree = translate(gpa, &aro_comp, args) catch |err| switch (err) {
error.SemanticAnalyzeFail, error.FatalError => {
aro.Diagnostics.render(&aro_comp, std.io.tty.detectConfig(std.io.getStdErr()));
std.process.exit(1);
},
error.ParsingFailed, error.FatalError => renderErrorsAndExit(&aro_comp),
error.OutOfMemory => return error.OutOfMemory,
error.StreamTooLong => std.zig.fatal("StreamTooLong?", .{}),
error.StreamTooLong => std.zig.fatal("An input file was larger than 4GiB", .{}),
};
defer tree.deinit(gpa);

Expand Down
7 changes: 7 additions & 0 deletions test/cases/translate_c/_Static_assert.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
_Static_assert(1 == 1, "");

// translate-c
// target=x86_64-linux
// c_frontend=aro
//
// tmp.c:1:1: warning: ignoring _Static_assert declaration