Skip to content
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

Add protection from calling typeStr with an invalid type #601

Merged
merged 3 commits into from
Feb 13, 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
13 changes: 10 additions & 3 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,11 @@ pub fn removeNull(p: *Parser, str: Value) !Value {
}

pub fn typeStr(p: *Parser, ty: Type) ![]const u8 {
if (@import("builtin").mode != .Debug) {
if (ty.is(.invalid)) {
return "Tried to render invalid type - this is an aro bug.";
}
}
if (Type.Builder.fromType(ty).str(p.comp.langopts)) |str| return str;
const strings_top = p.strings.items.len;
defer p.strings.items.len = strings_top;
Expand All @@ -446,6 +451,11 @@ pub fn typePairStr(p: *Parser, a: Type, b: Type) ![]const u8 {
}

pub fn typePairStrExtra(p: *Parser, a: Type, msg: []const u8, b: Type) ![]const u8 {
if (@import("builtin").mode != .Debug) {
if (a.is(.invalid) or b.is(.invalid)) {
return "Tried to render invalid type - this is an aro bug.";
}
}
const strings_top = p.strings.items.len;
defer p.strings.items.len = strings_top;

Expand Down Expand Up @@ -635,7 +645,6 @@ fn diagnoseIncompleteDefinitions(p: *Parser) !void {
const tys = node_slices.items(.ty);
const data = node_slices.items(.data);

const err_start = p.comp.diagnostics.list.items.len;
for (p.decl_buf.items) |decl_node| {
const idx = @intFromEnum(decl_node);
switch (tags[idx]) {
Expand All @@ -656,8 +665,6 @@ fn diagnoseIncompleteDefinitions(p: *Parser) !void {
try p.errStr(.tentative_definition_incomplete, tentative_def_tok, type_str);
try p.errStr(.forward_declaration_here, data[idx].decl_ref, type_str);
}
const errors_added = p.comp.diagnostics.list.items.len - err_start;
assert(errors_added == 2 * p.tentative_defs.count()); // Each tentative def should add an error + note
}

/// root : (decl | assembly ';' | staticAssert)*
Expand Down
2 changes: 1 addition & 1 deletion src/aro/Type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ pub fn bitSizeof(ty: Type, comp: *const Compilation) ?u64 {
}

pub fn alignable(ty: Type) bool {
return ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void);
return (ty.isArray() or !ty.hasIncompleteSize() or ty.is(.void)) and !ty.is(.invalid);
}

/// Get the alignment of a type
Expand Down
11 changes: 11 additions & 0 deletions test/cases/incomplete types.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ void incomplete_enum_float(void) {

void incomplete_unspecified_variable_len_array(struct S b[1][*]);

void f1(struct Foo *a) { } /* should produce `warning: declaration of 'struct Foo' will not be visible outside of this function [-Wvisibility]` instead of tentative definition error */

struct Foo f;

#define TESTS_SKIPPED 1

#define EXPECTED_ERRORS "incomplete types.c:4:5: error: dereferencing pointer to incomplete type 'struct S'" \
"incomplete types.c:5:11: error: dereferencing pointer to incomplete type 'struct S'" \
"incomplete types.c:8:5: error: dereferencing pointer to incomplete type 'union U'" \
Expand All @@ -56,3 +62,8 @@ void incomplete_unspecified_variable_len_array(struct S b[1][*]);
"incomplete types.c:34:13: error: statement requires expression with integer type ('struct node' invalid)" \
"incomplete types.c:40:12: error: variable has incomplete type 'enum E'" \
"incomplete types.c:44:58: error: array has incomplete element type 'struct S [*]'" \
"incomplete types.c:48:12: error: tentative definition has type 'struct Foo' that is never completed" \
"incomplete types.c:46:16: note: forward declaration of 'struct Foo'" \
"incomplete types.c:48:12: error: tentative definition has type 'struct Foo' that is never completed" \
"incomplete types.c:48:8: note: forward declaration of 'struct Foo'" \

Loading