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

Implement more C23 changes #535

Merged
merged 9 commits into from
Nov 8, 2023
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
2 changes: 1 addition & 1 deletion include/stddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ typedef struct {

#if __STDC_VERSION__ >= 202311L
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpre-c2x-compat"
# pragma GCC diagnostic ignored "-Wpre-c23-compat"
typedef typeof(nullptr) nullptr_t;
# pragma GCC diagnostic pop

Expand Down
10 changes: 5 additions & 5 deletions src/Attribute.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ syntax: Syntax,
args: Arguments,

pub const Syntax = enum {
c2x,
c23,
declspec,
gnu,
keyword,
};

pub const Kind = enum {
c2x,
c23,
declspec,
gnu,

pub fn toSyntax(kind: Kind) Syntax {
return switch (kind) {
.c2x => .c2x,
.c23 => .c23,
.declspec => .declspec,
.gnu => .gnu,
};
Expand Down Expand Up @@ -684,7 +684,7 @@ pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
tag: Tag,
gnu: bool = false,
declspec: bool = false,
c2x: bool = false,
c23: bool = false,
};
const attribute_names = @import("Attribute/names.def").with(Properties);

Expand All @@ -707,7 +707,7 @@ pub fn fromString(kind: Kind, namespace: ?[]const u8, name: []const u8) ?Tag {
return null;
}

fn normalize(name: []const u8) []const u8 {
pub fn normalize(name: []const u8) []const u8 {
if (name.len >= 4 and mem.startsWith(u8, name, "__") and mem.endsWith(u8, name, "__")) {
return name[2 .. name.len - 2];
}
Expand Down
16 changes: 8 additions & 8 deletions src/Attribute/names.def
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# multiple
deprecated
.tag = .deprecated
.c2x = true
.c23 = true
.gnu = true
.declspec = true

fallthrough
.tag = .fallthrough
.c2x = true
.c23 = true
.gnu = true

noreturn
.tag = .@"noreturn"
.c2x = true
.c23 = true
.gnu = true
.declspec = true

Expand All @@ -26,22 +26,22 @@ noinline
.gnu = true
.declspec = true

# c2x only
# c23 only
nodiscard
.tag = .nodiscard
.c2x = true
.c23 = true

reproducible
.tag = .reproducible
.c2x = true
.c23 = true

unsequenced
.tag = .unsequenced
.c2x = true
.c23 = true

maybe_unused
.tag = .unused
.c2x = true
.c23 = true

# gnu only
access
Expand Down
3 changes: 3 additions & 0 deletions src/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,9 @@ fn genLval(c: *CodeGen, node: NodeIndex) Error!Ir.Ref {
.member_access_expr,
.member_access_ptr_expr,
.array_access_expr,
.static_compound_literal_expr,
.thread_local_compound_literal_expr,
.static_thread_local_compound_literal_expr,
=> return c.comp.diag.fatalNoSrc("TODO CodeGen.genLval {}\n", .{c.node_tag[@intFromEnum(node)]}),
else => unreachable, // Not an lval expression.
}
Expand Down
18 changes: 14 additions & 4 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1259,15 +1259,24 @@ pub const IncludeType = enum {
angle_brackets,
};

fn getFileContents(comp: *Compilation, path: []const u8) ![]const u8 {
fn getFileContents(comp: *Compilation, path: []const u8, limit: ?u32) ![]const u8 {
if (mem.indexOfScalar(u8, path, 0) != null) {
return error.FileNotFound;
}

const file = try std.fs.cwd().openFile(path, .{});
defer file.close();

return file.readToEndAlloc(comp.gpa, std.math.maxInt(u32));
var buf = std.ArrayList(u8).init(comp.gpa);
defer buf.deinit();

const max = limit orelse std.math.maxInt(u32);
file.reader().readAllArrayList(&buf, max) catch |e| switch (e) {
error.StreamTooLong => if (limit == null) return e,
else => return e,
};

return buf.toOwnedSlice();
}

pub fn findEmbed(
Expand All @@ -1276,9 +1285,10 @@ pub fn findEmbed(
includer_token_source: Source.Id,
/// angle bracket vs quotes
include_type: IncludeType,
limit: ?u32,
) !?[]const u8 {
if (std.fs.path.isAbsolute(filename)) {
return if (comp.getFileContents(filename)) |some|
return if (comp.getFileContents(filename, limit)) |some|
some
else |err| switch (err) {
error.OutOfMemory => |e| return e,
Expand All @@ -1295,7 +1305,7 @@ pub fn findEmbed(

while (try it.nextWithFile(filename, stack_fallback.get())) |found| {
defer stack_fallback.get().free(found.path);
if (comp.getFileContents(found.path)) |some|
if (comp.getFileContents(found.path, limit)) |some|
return some
else |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
Expand Down
113 changes: 88 additions & 25 deletions src/Diagnostics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub const Options = struct {
@"array-bounds": Kind = .default,
@"int-conversion": Kind = .default,
@"pointer-type-mismatch": Kind = .default,
@"c2x-extensions": Kind = .default,
@"c23-extensions": Kind = .default,
@"incompatible-pointer-types": Kind = .default,
@"excess-initializers": Kind = .default,
@"division-by-zero": Kind = .default,
Expand Down Expand Up @@ -164,7 +164,7 @@ pub const Options = struct {
@"keyword-macro": Kind = .default,
@"pointer-arith": Kind = .default,
@"sizeof-array-argument": Kind = .default,
@"pre-c2x-compat": Kind = .default,
@"pre-c23-compat": Kind = .default,
@"pointer-bool-conversion": Kind = .default,
@"string-conversion": Kind = .default,
@"gnu-auto-type": Kind = .default,
Expand All @@ -179,6 +179,9 @@ pub const Options = struct {
@"four-char-constants": Kind = .default,
@"unknown-escape-sequence": Kind = .default,
@"invalid-pp-token": Kind = .default,
@"deprecated-non-prototype": Kind = .default,
@"duplicate-embed-param": Kind = .default,
@"unsupported-embed-param": Kind = .default,
};

const messages = struct {
Expand Down Expand Up @@ -383,7 +386,7 @@ const messages = struct {
const kind = .warning;
const all = true;
};
pub const missing_type_specifier_c2x = struct {
pub const missing_type_specifier_c23 = struct {
const msg = "a type specifier is required for all declarations";
const kind = .@"error";
};
Expand Down Expand Up @@ -521,10 +524,10 @@ const messages = struct {
const kind = .@"error";
};
pub const implicit_func_decl = struct {
const msg = "implicit declaration of function '{s}' is invalid in C99";
const msg = "call to undeclared function '{s}'; ISO C99 and later do not support implicit function declarations";
const extra = .str;
const opt = "implicit-function-declaration";
const kind = .warning;
const kind = .@"error";
const all = true;
};
pub const unknown_builtin = struct {
Expand Down Expand Up @@ -1136,17 +1139,17 @@ const messages = struct {
const kind = .@"error";
};
pub const static_assert_missing_message = struct {
const msg = "static_assert with no message is a C2X extension";
const opt = "c2x-extensions";
const msg = "static_assert with no message is a C23 extension";
const opt = "c23-extensions";
const kind = .warning;
const suppress_version = .c2x;
const suppress_version = .c23;
};
pub const pre_c2x_compat = struct {
const msg = "{s} is incompatible with C standards before C2x";
pub const pre_c23_compat = struct {
const msg = "{s} is incompatible with C standards before C23";
const extra = .str;
const kind = .off;
const suppress_unless_version = .c2x;
const opt = "pre-c2x-compat";
const suppress_unless_version = .c23;
const opt = "pre-c23-compat";
};
pub const unbound_vla = struct {
const msg = "variable length array must be bound in function definition";
Expand Down Expand Up @@ -1449,10 +1452,10 @@ const messages = struct {
const pedantic = true;
};
pub const omitting_parameter_name = struct {
const msg = "omitting the parameter name in a function definition is a C2x extension";
const opt = "c2x-extensions";
const msg = "omitting the parameter name in a function definition is a C23 extension";
const opt = "c23-extensions";
const kind = .warning;
const suppress_version = .c2x;
const suppress_version = .c23;
};
pub const non_int_bitfield = struct {
const msg = "bit-field has non-integer type '{s}'";
Expand Down Expand Up @@ -2226,7 +2229,7 @@ const messages = struct {
const kind = .off;
const pedantic = true;
const opt = "bit-int-extension";
const suppress_version = .c2x;
const suppress_version = .c23;
};
pub const unsigned_bit_int_too_small = struct {
const msg = "{s} must have a bit size of at least 1";
Expand Down Expand Up @@ -2305,10 +2308,10 @@ const messages = struct {
const kind = .@"error";
};
pub const bitint_suffix = struct {
const msg = "'_BitInt' suffix for literals is a C2x extension";
const opt = "c2x-extensions";
const msg = "'_BitInt' suffix for literals is a C23 extension";
const opt = "c23-extensions";
const kind = .warning;
const suppress_version = .c2x;
const suppress_version = .c23;
};
pub const auto_type_extension = struct {
const msg = "'__auto_type' is a GNU extension";
Expand Down Expand Up @@ -2468,21 +2471,21 @@ const messages = struct {
const extra = .ascii;
};
pub const ucn_basic_char_warning = struct {
const msg = "specifying character '{c}' with a universal character name is incompatible with C standards before C2x";
const msg = "specifying character '{c}' with a universal character name is incompatible with C standards before C23";
const kind = .off;
const extra = .ascii;
const suppress_unless_version = .c2x;
const opt = "pre-c2x-compat";
const suppress_unless_version = .c23;
const opt = "pre-c23-compat";
};
pub const ucn_control_char_error = struct {
const msg = "universal character name refers to a control character";
const kind = .@"error";
};
pub const ucn_control_char_warning = struct {
const msg = "universal character name referring to a control character is incompatible with C standards before C2x";
const msg = "universal character name referring to a control character is incompatible with C standards before C23";
const kind = .off;
const suppress_unless_version = .c2x;
const opt = "pre-c2x-compat";
const suppress_unless_version = .c23;
const opt = "pre-c23-compat";
};
pub const c89_ucn_in_literal = struct {
const msg = "universal character names are only valid in C99 or later";
Expand Down Expand Up @@ -2546,6 +2549,66 @@ const messages = struct {
const msg = "unterminated comment";
const kind = .@"error";
};
pub const def_no_proto_deprecated = struct {
const msg = "a function definition without a prototype is deprecated in all versions of C and is not supported in C23";
const kind = .warning;
const opt = "deprecated-non-prototype";
};
pub const passing_args_to_kr = struct {
const msg = "passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23";
const kind = .warning;
const opt = "deprecated-non-prototype";
};
pub const unknown_type_name = struct {
const msg = "unknown type name '{s}'";
const kind = .@"error";
const extra = .str;
};
pub const label_compound_end = struct {
const msg = "label at end of compound statement is a C23 extension";
const opt = "c23-extensions";
const kind = .warning;
const suppress_version = .c23;
};
pub const u8_char_lit = struct {
const msg = "UTF-8 character literal is a C23 extension";
const opt = "c23-extensions";
const kind = .warning;
const suppress_version = .c23;
};
pub const malformed_embed_param = struct {
const msg = "unexpected token in embed parameter";
const kind = .@"error";
};
pub const malformed_embed_limit = struct {
const msg = "the limit parameter expects one non-negative integer as a parameter";
const kind = .@"error";
};
pub const duplicate_embed_param = struct {
const msg = "duplicate embed parameter '{s}'";
const kind = .warning;
const extra = .str;
const opt = "duplicate-embed-param";
};
pub const unsupported_embed_param = struct {
const msg = "unsupported embed parameter '{s}' embed parameter";
const kind = .warning;
const extra = .str;
const opt = "unsupported-embed-param";
};
pub const invalid_compound_literal_storage_class = struct {
const msg = "compound literal cannot have {s} storage class";
const kind = .@"error";
const extra = .str;
};
pub const va_opt_lparen = struct {
const msg = "missing '(' following __VA_OPT__";
const kind = .@"error";
};
pub const va_opt_rparen = struct {
const msg = "unterminated __VA_OPT__ argument list";
const kind = .@"error";
};
};

list: std.ArrayListUnmanaged(Message) = .{},
Expand Down
4 changes: 2 additions & 2 deletions src/Driver.zig
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ pub const usage =
\\ -c, --compile Only run preprocess, compile, and assemble steps
\\ -D <macro>=<value> Define <macro> to <value> (defaults to 1)
\\ -E Only run the preprocessor
\\ -fchar8_t Enable char8_t (enabled by default in C2X and later)
\\ -fno-char8_t Disable char8_t (disabled by default for pre-C2X)
\\ -fchar8_t Enable char8_t (enabled by default in C23 and later)
\\ -fno-char8_t Disable char8_t (disabled by default for pre-C23)
\\ -fcolor-diagnostics Enable colors in diagnostics
\\ -fno-color-diagnostics Disable colors in diagnostics
\\ -fdeclspec Enable support for __declspec attributes
Expand Down
Loading
Loading