Skip to content

Commit

Permalink
Merge pull request #535 from Vexu/c23
Browse files Browse the repository at this point in the history
Implement more C23 changes
  • Loading branch information
Vexu authored Nov 8, 2023
2 parents 1cdf4d5 + caa7832 commit d753563
Show file tree
Hide file tree
Showing 59 changed files with 758 additions and 243 deletions.
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

0 comments on commit d753563

Please sign in to comment.