From: Bart Van Assche <bvanassche@acm.org>
To: linux-sparse@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Bart Van Assche <bvanassche@acm.org>
Subject: [PATCH 49/73] c23: Support auto type inference
Date: Mon, 9 Nov 2026 12:32:35 -0800 [thread overview]
Message-ID: <20261109203259.362845-50-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>
Add ISO C23 'auto' type inference when 'auto' appears without a type
specifier, while preserving 'auto' as a block-scope storage-class
specifier when combined with an explicit type:
- Infer the variable type from its assignment-expression initializer
after array-to-pointer, function-to-pointer, and lvalue conversion so
top-level qualifiers and _Atomic are stripped per C23 6.7.10p2.
- Bind C23 'auto' symbols before parsing their initializers and mark
them underspecified during initializer parsing and evaluation so
self-references are diagnosed per C23 6.2.1p7.
- Diagnose underspecified redeclarations in the same scope per C23
6.7p12, braced initializers, typedefs, empty declarations, type names,
parameters, struct/union members, and file-scope 'auto' specifiers.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
evaluate.c | 14 +++-
parse.c | 129 +++++++++++++++++++++++++++++++++---
symbol.c | 59 ++++++++++++++++-
symbol.h | 3 +
validation/c23-auto-error.c | 68 +++++++++++++++++++
validation/c23-auto.c | 107 ++++++++++++++++++++++++++++++
6 files changed, 365 insertions(+), 15 deletions(-)
create mode 100644 validation/c23-auto-error.c
create mode 100644 validation/c23-auto.c
diff --git a/evaluate.c b/evaluate.c
index c0d039105881..1b1a72577d18 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -87,6 +87,12 @@ static struct symbol *evaluate_symbol_expression(struct expression *expr)
expression_error(expr, "undefined identifier '%s'", show_ident(expr->symbol_name));
return NULL;
}
+ if (sym->underspecified) {
+ expression_error(expr,
+ "underspecified symbol '%s' used in its own initializer",
+ show_ident(sym->ident));
+ return NULL;
+ }
examine_symbol_type(sym);
@@ -3853,8 +3859,14 @@ static struct symbol *evaluate_symbol(struct symbol *sym)
return NULL;
/* Evaluate the initializers */
- if (sym->initializer)
+ if (sym->initializer) {
+ bool mark_underspec = sym->c23_auto;
+ if (mark_underspec)
+ sym->underspecified = 1;
evaluate_initializer(sym, &sym->initializer);
+ if (mark_underspec)
+ sym->underspecified = 0;
+ }
/* And finally, evaluate the body of the symbol too */
if (base_type->type == SYM_FN) {
diff --git a/parse.c b/parse.c
index 1e91825f8d38..324da8e40423 100644
--- a/parse.c
+++ b/parse.c
@@ -57,7 +57,7 @@ static declarator_t
attribute_specifier, typeof_specifier, typeof_unqual_specifier,
storage_specifier, thread_specifier;
static declarator_t generic_qualifier;
-static declarator_t autotype_specifier;
+static declarator_t autotype_specifier, auto_specifier;
static struct token *parse_if_statement(struct token *token, struct statement *stmt);
static struct token *parse_return_statement(struct token *token, struct statement *stmt);
@@ -143,7 +143,7 @@ static struct symbol_op alignas_op = {
static struct symbol_op auto_op = {
.type = KW_MODIFIER,
- .declarator = storage_specifier,
+ .declarator = auto_specifier,
};
static struct symbol_op register_op = {
@@ -472,7 +472,7 @@ static struct init_keyword {
#define U(I, O,...) N("__" I,O,##__VA_ARGS__), \
N("__" I "__",O,##__VA_ARGS__)
/* Storage classes */
- N("auto", &auto_op, .mods = MOD_AUTO),
+ N("auto", &auto_op),
N("register", ®ister_op, .mods = MOD_REGISTER),
N("static", &static_op, .mods = MOD_STATIC),
N("extern", &extern_op, .mods = MOD_EXTERN),
@@ -1202,6 +1202,15 @@ static struct token *autotype_specifier(struct token *token, struct symbol *sym,
return token;
}
+static struct token *auto_specifier(struct token *token, struct symbol *sym,
+ struct decl_state *ctx)
+{
+ if (ctx->has_auto)
+ sparse_error(token->pos, "duplicate auto");
+ ctx->has_auto = 1;
+ return token;
+}
+
static struct token *ignore_attribute(struct token *token, struct symbol *attr, struct decl_state *ctx)
{
struct expression *expr = NULL;
@@ -1732,6 +1741,23 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta
}
}
+ if (ctx->has_auto) {
+ if (seen & (Set_S | Set_Any)) {
+ if (ctx->storage_class)
+ sparse_error(token->pos,
+ "multiple storage classes");
+ else
+ ctx->storage_class = MOD_AUTO;
+ } else {
+ if (standard < STANDARD_C23 && Wpedantic)
+ warning(token->pos,
+ "'auto' type inference is a C23 feature");
+ ctx->ctype.base_type = &autotype_ctype;
+ ctx->autotype = 1;
+ seen |= Set_S;
+ }
+ }
+
if (!(seen & Set_S)) { /* not set explicitly? */
struct symbol *base = &incomplete_ctype;
if (seen & Set_Any)
@@ -2085,6 +2111,14 @@ static struct token *declaration_list(struct token *token, struct symbol_list **
decl->ctype.modifiers |= mod;
decl->cleanup = ctx.cleanup;
decl->endpos = token->pos;
+ if (ctx.has_auto) {
+ sparse_error(
+ decl->pos,
+ "struct or union member '%s' cannot be declared auto",
+ show_ident(decl->ident));
+ if (ctx.autotype)
+ decl->ctype.base_type = &bad_ctype;
+ }
if (decl->ctype.modifiers & MOD_TLS)
sparse_error(
decl->pos,
@@ -2136,6 +2170,14 @@ static struct token *parameter_declaration(struct token *token, struct symbol *s
sparse_error(sym->pos,
"alignment specified for parameter '%s'",
show_ident(sym->ident));
+ if (ctx.has_auto || ctx.autotype) {
+ sparse_error(sym->pos,
+ "parameter '%s' cannot be declared %s",
+ show_ident(sym->ident),
+ ctx.has_auto ? "auto" : "__auto_type");
+ if (ctx.autotype)
+ sym->ctype.base_type = &bad_ctype;
+ }
if (sym->ctype.modifiers & MOD_TLS)
sparse_error(sym->pos,
"parameter '%s' cannot be thread-local",
@@ -2152,6 +2194,11 @@ struct token *typename(struct token *token, struct symbol **p, int *forced)
token = declaration_specifiers(token, &ctx);
if (ctx.has_alignas)
sparse_error(sym->pos, "alignment specified for type name");
+ if (ctx.autotype) {
+ sparse_error(sym->pos, "'%s' in type name",
+ ctx.has_auto ? "auto" : "__auto_type");
+ ctx.ctype.base_type = &bad_ctype;
+ }
token = declarator(token, &ctx);
apply_modifiers(token->pos, &ctx);
sym->ctype = ctx.ctype;
@@ -3199,6 +3246,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
struct symbol *base_type;
unsigned long mod;
int is_typedef;
+ bool delay_bind = false;
/* Top-level inline asm or static assertion? */
if (token_type(token) == TOKEN_IDENT) {
@@ -3213,6 +3261,9 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
decl = alloc_symbol(token->pos, SYM_NODE);
/* Just a type declaration? */
if (match_op(token, ';')) {
+ if (ctx.autotype)
+ sparse_error(token->pos, "%s in empty declaration",
+ ctx.has_auto ? "auto" : "__auto_type");
apply_modifiers(token->pos, &ctx);
return token->next;
}
@@ -3226,6 +3277,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
decl->ctype = ctx.ctype;
decl->ctype.modifiers |= mod;
decl->cleanup = ctx.cleanup;
+ decl->c23_auto = ctx.autotype && ctx.has_auto;
decl->endpos = token->pos;
/* Just a type declaration? */
@@ -3241,9 +3293,15 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
if (is_typedef)
decl->ctype.modifiers |= MOD_USERTYPE;
- bind_symbol(decl, ident, is_typedef ? NS_TYPEDEF: NS_SYMBOL);
-
base_type = decl->ctype.base_type;
+ if (!is_typedef && ctx.autotype && !ctx.has_auto &&
+ base_type == &autotype_ctype) {
+ struct symbol *prev = lookup_symbol(ident, NS_SYMBOL | NS_TYPEDEF);
+ if (prev && is_outer_scope(prev->scope))
+ delay_bind = true;
+ }
+ if (!delay_bind)
+ bind_symbol(decl, ident, is_typedef ? NS_TYPEDEF: NS_SYMBOL);
if (is_typedef) {
if (base_type && !base_type->ident) {
@@ -3260,8 +3318,9 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
}
} else if (base_type && base_type->type == SYM_FN) {
if (base_type->ctype.base_type == &autotype_ctype) {
- sparse_error(decl->pos, "'%s()' has __auto_type return type",
- show_ident(decl->ident));
+ sparse_error(decl->pos, "'%s()' has %s return type",
+ show_ident(decl->ident),
+ ctx.has_auto ? "auto" : "__auto_type");
base_type->ctype.base_type = &int_ctype;
}
if (base_type->ctype.base_type == &incomplete_ctype) {
@@ -3301,11 +3360,26 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
for (;;) {
if (!is_typedef && match_op(token, '=')) {
struct token *next = token->next;
+ bool mark_underspec = decl->c23_auto;
+ if (mark_underspec)
+ decl->underspecified = 1;
token = initializer(&decl->initializer, next);
+ if (mark_underspec)
+ decl->underspecified = 0;
if (token == next)
sparse_error(token->pos, "expression expected before '%s'", show_token(token));
}
+ if (delay_bind) {
+ bind_symbol(decl, ident, is_typedef ? NS_TYPEDEF : NS_SYMBOL);
+ delay_bind = false;
+ }
if (!is_typedef) {
+ if (!ctx.autotype && (ctx.storage_class & MOD_AUTO) &&
+ toplevel(block_scope))
+ sparse_error(
+ decl->pos,
+ "file-scope declaration of '%s' specifies 'auto'",
+ show_ident(decl->ident));
if (validate_decl)
validate_decl(decl);
@@ -3329,19 +3403,51 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
}
}
+ if (!is_typedef && decl->c23_auto &&
+ (!decl->ctype.base_type ||
+ decl->ctype.base_type->type != SYM_FN)) {
+ struct symbol *prev;
+ for (prev = decl->next_id; prev; prev = prev->next_id) {
+ if (prev->namespace != decl->namespace ||
+ prev->builtin)
+ continue;
+ if (prev->scope == decl->scope ||
+ (toplevel(decl->scope) &&
+ toplevel(prev->scope))) {
+ sparse_error(
+ decl->pos,
+ "underspecified declaration of '%s', which is already declared in this scope",
+ show_ident(decl->ident));
+ break;
+ }
+ }
+ }
+
if (ctx.autotype) {
const char *msg = NULL;
- if (decl->ctype.base_type != &autotype_ctype)
+ struct expression *init = decl->initializer;
+ while (init && init->type == EXPR_PREOP && init->op == '(')
+ init = init->unop;
+ if (is_typedef)
+ msg = "cannot be used with typedef";
+ else if (decl->ctype.base_type != &autotype_ctype)
msg = "on non-identifier";
else if (match_op(token, ','))
msg = "on declaration list";
else if (!decl->initializer)
msg = "without initializer";
- else if (decl->initializer->type == EXPR_SYMBOL &&
- decl->initializer->symbol == decl)
+ else if (decl->initializer->type == EXPR_INITIALIZER) {
+ msg = "requires a scalar initializer expression";
+ decl->initializer = NULL;
+ } else if (!ctx.has_auto && init &&
+ init->type == EXPR_SYMBOL &&
+ init->symbol == decl)
msg = "on self-init var";
if (msg) {
- sparse_error(decl->pos, "__auto_type %s", msg);
+ sparse_error(decl->pos, "%s %s",
+ ctx.has_auto ? "auto" :
+ "__auto_type",
+ msg);
decl->ctype.base_type = &bad_ctype;
}
}
@@ -3391,6 +3497,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
decl->ctype = ctx.ctype;
decl->ctype.modifiers |= mod;
decl->cleanup = ctx.cleanup;
+ decl->c23_auto = ctx.autotype && ctx.has_auto;
decl->endpos = token->pos;
if (!ident) {
sparse_error(token->pos, "expected identifier name in type definition");
diff --git a/symbol.c b/symbol.c
index a05e240cdfaa..b0bdf0b1122f 100644
--- a/symbol.c
+++ b/symbol.c
@@ -266,15 +266,68 @@ static struct symbol *examine_base_type(struct symbol *sym)
struct symbol *base_type;
if (sym->ctype.base_type == &autotype_ctype) {
- struct symbol *type = evaluate_expression(sym->initializer);
- if (!type)
+ struct symbol *type;
+ sym->ctype.base_type = &bad_ctype;
+ if (!sym->initializer || sym->initializer->type == EXPR_INITIALIZER) {
+ type = &bad_ctype;
+ } else {
+ if (sym->c23_auto)
+ sym->underspecified = 1;
+ type = evaluate_expression(sym->initializer);
+ if (sym->c23_auto)
+ sym->underspecified = 0;
+ }
+ if (!type || type == sym || type->ctype.base_type == &autotype_ctype)
type = &bad_ctype;
if (is_bitfield_type(type)) {
- warning(sym->pos, "__auto_type on bitfield");
+ if (!sym->c23_auto)
+ warning(sym->pos, "__auto_type on bitfield");
if (type->type == SYM_NODE)
type = type->ctype.base_type;
type = type->ctype.base_type;
}
+ if (type->type == SYM_NODE &&
+ type->ctype.base_type->type == SYM_ARRAY) {
+ struct symbol *array = type->ctype.base_type;
+ struct symbol *ptr = alloc_symbol(sym->pos, SYM_PTR);
+ ptr->ctype.base_type = array->ctype.base_type;
+ combine_address_space(sym->pos, &ptr->ctype.as, type->ctype.as);
+ combine_address_space(sym->pos, &ptr->ctype.as, array->ctype.as);
+ ptr->ctype.modifiers |= (type->ctype.modifiers | array->ctype.modifiers) & MOD_PTRINHERIT;
+ ptr->bit_size = bits_in_pointer;
+ ptr->ctype.alignment = pointer_alignment;
+ type = ptr;
+ } else if (type->type == SYM_ARRAY) {
+ struct symbol *ptr = alloc_symbol(sym->pos, SYM_PTR);
+ ptr->ctype.base_type = type->ctype.base_type;
+ combine_address_space(sym->pos, &ptr->ctype.as, type->ctype.as);
+ ptr->ctype.modifiers |= type->ctype.modifiers & MOD_PTRINHERIT;
+ ptr->bit_size = bits_in_pointer;
+ ptr->ctype.alignment = pointer_alignment;
+ type = ptr;
+ } else if (type->type == SYM_NODE &&
+ type->ctype.base_type->type == SYM_FN) {
+ struct symbol *ptr = alloc_symbol(sym->pos, SYM_PTR);
+ ptr->ctype.base_type = type->ctype.base_type;
+ ptr->bit_size = bits_in_pointer;
+ ptr->ctype.alignment = pointer_alignment;
+ type = ptr;
+ } else if (type->type == SYM_FN) {
+ struct symbol *ptr = alloc_symbol(sym->pos, SYM_PTR);
+ ptr->ctype.base_type = type;
+ ptr->bit_size = bits_in_pointer;
+ ptr->ctype.alignment = pointer_alignment;
+ type = ptr;
+ } else if (sym->c23_auto) {
+ /*
+ * C23 6.7.10p2: inferred type is the type of the
+ * assignment expression after lvalue, array-to-pointer,
+ * or function-to-pointer conversion (stripping top-level
+ * qualifiers and atomic).
+ */
+ while (type->type == SYM_NODE)
+ type = type->ctype.base_type;
+ }
sym->ctype.base_type = type;
}
diff --git a/symbol.h b/symbol.h
index acd381fe64fd..61ca70afe83b 100644
--- a/symbol.h
+++ b/symbol.h
@@ -115,6 +115,7 @@ struct decl_state {
unsigned char autotype;
unsigned char forced;
unsigned char packed;
+ unsigned char has_auto;
unsigned char has_alignas;
unsigned char designated_init;
unsigned char transparent_union;
@@ -201,6 +202,8 @@ struct symbol {
packed:1,
transparent_union:1;
unsigned int has_alignas : 1;
+ unsigned int underspecified : 1;
+ unsigned int c23_auto : 1;
int rank:3; // arithmetic's rank
struct expression *array_size;
struct ctype ctype;
diff --git a/validation/c23-auto-error.c b/validation/c23-auto-error.c
new file mode 100644
index 000000000000..b88ebd37d2d9
--- /dev/null
+++ b/validation/c23-auto-error.c
@@ -0,0 +1,68 @@
+auto no_init;
+auto arr[2] = { 0, 1 };
+auto foo(void)
+{
+}
+auto x = 1, y = 2;
+auto self = self;
+auto auto dup = 1;
+auto self_expr = self_expr + 1;
+auto self_sz = sizeof(self_sz);
+struct bad_s {
+ auto m;
+};
+void bad_param(auto p);
+typedef auto bad_td;
+auto;
+auto int bad_file_storage = 1;
+extern int already_in_scope;
+auto already_in_scope = 1;
+
+void block_errors(void)
+{
+ int shadow = 5;
+ {
+ auto shadow = shadow + 1;
+ }
+ int bad_sz = sizeof(auto);
+ int bad_cast = (auto)1;
+ _Atomic(auto) bad_atomic = 1;
+ auto braced = { 1 };
+ (void)bad_sz;
+ (void)bad_cast;
+ (void)bad_atomic;
+ (void)braced;
+}
+
+/*
+ * check-name: C23 auto error cases
+ * check-command: sparse -std=c23 $file
+ *
+ * check-error-start
+c23-auto-error.c:1:6: error: auto without initializer
+c23-auto-error.c:2:6: error: auto on non-identifier
+c23-auto-error.c:3:6: error: 'foo()' has auto return type
+c23-auto-error.c:6:6: error: auto on declaration list
+c23-auto-error.c:8:11: error: duplicate auto
+c23-auto-error.c:12:14: error: struct or union member 'm' cannot be declared auto
+c23-auto-error.c:14:16: error: parameter 'p' cannot be declared auto
+c23-auto-error.c:15:14: error: auto cannot be used with typedef
+c23-auto-error.c:16:5: error: auto in empty declaration
+c23-auto-error.c:17:10: error: file-scope declaration of 'bad_file_storage' specifies 'auto'
+c23-auto-error.c:19:6: error: underspecified declaration of 'already_in_scope', which is already declared in this scope
+c23-auto-error.c:27:29: error: 'auto' in type name
+c23-auto-error.c:28:25: error: 'auto' in type name
+c23-auto-error.c:29:16: error: Trying to use reserved word 'auto' as identifier
+c23-auto-error.c:29:23: error: Expected ; at end of declaration
+c23-auto-error.c:29:23: error: got bad_atomic
+c23-auto-error.c:30:14: error: auto requires a scalar initializer expression
+c23-auto-error.c:2:15: error: invalid initializer
+c23-auto-error.c:7:13: error: underspecified symbol 'self' used in its own initializer
+c23-auto-error.c:9:18: error: underspecified symbol 'self_expr' used in its own initializer
+c23-auto-error.c:10:23: error: underspecified symbol 'self_sz' used in its own initializer
+c23-auto-error.c:10:16: error: cannot size expression
+c23-auto-error.c:25:31: error: underspecified symbol 'shadow' used in its own initializer
+c23-auto-error.c:27:22: error: cannot size expression
+c23-auto-error.c:33:15: error: undefined identifier 'bad_atomic'
+ * check-error-end
+ */
diff --git a/validation/c23-auto.c b/validation/c23-auto.c
new file mode 100644
index 000000000000..f9c461d9bed7
--- /dev/null
+++ b/validation/c23-auto.c
@@ -0,0 +1,107 @@
+#ifdef __CHECKER__
+#define ASSERT_TYPE(expr, T) _Static_assert([typeof(expr)] == [T], "")
+#else
+#define ASSERT_TYPE(expr, T) \
+ _Static_assert(_Generic((typeof(expr) *)0, typeof(T) *: 1, default: 0), "")
+#endif
+
+struct s {
+ int a;
+};
+static void fn(void)
+{
+}
+
+static auto file_static = 42L;
+ASSERT_TYPE(file_static, long);
+
+static void test(void)
+{
+ auto i = 0;
+ ASSERT_TYPE(i, int);
+
+ auto l = 1L;
+ ASSERT_TYPE(l, long);
+
+ auto d = 1.0;
+ ASSERT_TYPE(d, double);
+
+ auto f = 1.0f;
+ ASSERT_TYPE(f, float);
+
+ auto p = &i;
+ ASSERT_TYPE(p, int *);
+
+ const auto ci = 42;
+ ASSERT_TYPE(ci, const int);
+
+ volatile auto vi = 1;
+ ASSERT_TYPE(vi, volatile int);
+
+ _Atomic auto ai = 2;
+ ASSERT_TYPE(ai, _Atomic int);
+
+ /* Top-level qualifiers and _Atomic are stripped by lvalue conversion */
+ auto stripped_c = ci;
+ ASSERT_TYPE(stripped_c, int);
+ stripped_c = 43;
+
+ auto stripped_v = vi;
+ ASSERT_TYPE(stripped_v, int);
+ stripped_v = 2;
+
+ auto stripped_a = ai;
+ ASSERT_TYPE(stripped_a, int);
+ stripped_a = 3;
+
+ /* Pointee qualifiers and decayed array element qualifiers are kept */
+ const int *cp = &ci;
+ auto p_to_const = cp;
+ ASSERT_TYPE(p_to_const, const int *);
+
+ int *const top_const_p = &i;
+ auto stripped_p = top_const_p;
+ ASSERT_TYPE(stripped_p, int *);
+ stripped_p = nullptr;
+
+ const int carr[2] = { 1, 2 };
+ auto decayed_carr = carr;
+ ASSERT_TYPE(decayed_carr, const int *);
+
+ static auto si = 100;
+ ASSERT_TYPE(si, int);
+
+ auto s = "hello";
+ ASSERT_TYPE(s, char *);
+
+ int arr[10];
+ auto a = arr;
+ ASSERT_TYPE(a, int *);
+
+ auto fp = fn;
+ ASSERT_TYPE(fp, void (*)(void));
+
+ struct s st = { 1 };
+ auto sv = st;
+ ASSERT_TYPE(sv, struct s);
+
+ const struct s cst = { 2 };
+ auto stripped_st = cst;
+ ASSERT_TYPE(stripped_st, struct s);
+ stripped_st.a = 3;
+
+ auto int normal = 1;
+ ASSERT_TYPE(normal, int);
+
+ int auto normal2 = 2;
+ ASSERT_TYPE(normal2, int);
+
+ for (auto idx = 0; idx < 1; idx++) {
+ ASSERT_TYPE(idx, int);
+ }
+}
+
+/*
+ * check-name: C23 auto type inference
+ * check-command: sparse -std=c23 $file
+ */
next prev parent reply other threads:[~2026-11-09 20:33 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 20:31 Bart Van Assche
2026-11-09 20:31 ` [PATCH 01/73] Makefile: Pass '--' to rm in clean target to handle dash-prefixed files Bart Van Assche
2026-11-09 20:31 ` [PATCH 02/73] sparse-llvm: Use LLVMCreateBuilderForModule() with LLVM 24 and later Bart Van Assche
2026-11-09 20:31 ` [PATCH 03/73] typeof_unqual: Strip qualifiers and address space from types and arrays Bart Van Assche
2026-11-09 20:31 ` [PATCH 04/73] bitfield: Pack consecutive _Bool bitfields into byte containers Bart Van Assche
2026-11-09 20:31 ` [PATCH 05/73] allocate: Harden slab allocation bounds, zeroing, and mmap checks Bart Van Assche
2026-11-09 20:31 ` [PATCH 06/73] tokenize: Support 4096-byte identifiers and fix escape bounds Bart Van Assche
2026-11-09 20:31 ` [PATCH 07/73] pre-process: Fix macro expansion and include directive handling Bart Van Assche
2026-11-09 20:31 ` [PATCH 08/73] options, lib: Harden warning buffers and command-line option parsing Bart Van Assche
2026-11-09 20:31 ` [PATCH 09/73] builtin: Fix atomic builtin type checking and object_size bounds Bart Van Assche
2026-11-09 20:31 ` [PATCH 10/73] parse, show-parse: Fix attribute propagation, enum overflow, and bounds Bart Van Assche
2026-11-09 20:31 ` [PATCH 11/73] target-openrisc: Set target_openrisc.mach to MACH_OPENRISC Bart Van Assche
2026-11-09 20:31 ` [PATCH 12/73] evaluate: Fix pointer arithmetic, incomplete types, and qualifiers Bart Van Assche
2026-11-09 20:31 ` [PATCH 13/73] expand: Fix static initializer folding and floating-point casts Bart Van Assche
2026-11-09 20:32 ` [PATCH 14/73] inline: Copy union cast types and VLA bounds when inlining Bart Van Assche
2026-11-09 20:32 ` [PATCH 15/73] linearize, flow: Fix asm operands, switch case bounds, and DSE Bart Van Assche
2026-11-09 20:32 ` [PATCH 16/73] memops, ssa: Walk parent insns in reverse and skip mixed-size SSA Bart Van Assche
2026-11-09 20:32 ` [PATCH 17/73] simplify: Prevent overflow on LLONG_MIN negation and fix simplifications Bart Van Assche
2026-11-09 20:32 ` [PATCH 18/73] sparse: Gate context failure warning on Wcontext and catch underflow Bart Van Assche
2026-11-09 20:32 ` [PATCH 19/73] ast-model: Return AST_N_COLUMNS and inspect child nodes lazily Bart Van Assche
2026-11-09 20:32 ` [PATCH 20/73] c2xml: Guard against recursive symbols and free xmlGetProp() string Bart Van Assche
2026-11-09 20:32 ` [PATCH 21/73] compile-i386: Fix buffer bounds, unsigned '<=' codegen, and null checks Bart Van Assche
2026-11-09 20:32 ` [PATCH 22/73] ctags: Fix line comparison order and handle SYM_RESTRICT and SYM_LABEL Bart Van Assche
2026-11-09 20:32 ` [PATCH 23/73] dissect: Unwrap array element type via base_type() Bart Van Assche
2026-11-09 20:32 ` [PATCH 24/73] example: Fix show_op() rotating buffer dimensions Bart Van Assche
2026-11-09 20:32 ` [PATCH 25/73] graph: Check PSEUDO_SYM before dereferencing insn->func->sym Bart Van Assche
2026-11-09 20:32 ` [PATCH 26/73] scheck: Fix slice() upper bit index calculation Bart Van Assche
2026-11-09 20:32 ` [PATCH 27/73] sparse-llvm: Support arbitrary struct member counts and fix operand types Bart Van Assche
2026-11-09 20:32 ` [PATCH 28/73] inline: Duplicate generic expressions instead of evaluating them Bart Van Assche
2026-11-09 20:32 ` [PATCH 29/73] lib: Avoid mutating fmt before va_start() in warning() Bart Van Assche
2026-11-09 20:32 ` [PATCH 30/73] cse, canon: Cast pointers to uintptr_t before relational comparison Bart Van Assche
2026-11-09 20:32 ` [PATCH 31/73] context: Add "conditional context increment" model Bart Van Assche
2026-11-09 20:32 ` [PATCH 32/73] expand: Simplify signed constants early Bart Van Assche
2026-11-09 20:32 ` [PATCH 33/73] bitwise: Allow all-bits-set as a restricted value Bart Van Assche
2026-11-09 20:32 ` [PATCH 34/73] bitwise: Allow restricted ordered compares with unrestricted values Bart Van Assche
2026-11-09 20:32 ` [PATCH 35/73] bitwise: Keep unrestricted values unrestricted after a cast Bart Van Assche
2026-11-09 20:32 ` [PATCH 36/73] bitwise: Don't remove MOD_SPECIFIER from 'bitwise' types Bart Van Assche
2026-11-09 20:32 ` [PATCH 37/73] bitwise: Allow both regular casts and forced casts for restricted values Bart Van Assche
2026-11-09 20:32 ` [PATCH 38/73] clang-format: Add .clang-format configuration file Bart Van Assche
2026-11-09 20:32 ` [PATCH 39/73] options: Add support for -std=c23, -std=c2x and -std=gnu23 Bart Van Assche
2026-11-09 20:32 ` [PATCH 40/73] preprocessor: Add support for #elifdef and #elifndef Bart Van Assche
2026-11-09 20:32 ` [PATCH 41/73] preprocessor: Add support for __has_include and __has_include_next Bart Van Assche
2026-11-09 20:32 ` [PATCH 42/73] c23: Add support for static_assert, alignas, alignof, thread_local Bart Van Assche
2026-11-09 20:32 ` [PATCH 43/73] c23: Add support for bool, true, and false keywords Bart Van Assche
2026-11-09 20:32 ` [PATCH 44/73] c23: Add support for nullptr and nullptr_t Bart Van Assche
2026-11-09 20:32 ` [PATCH 45/73] c23: Add support for digit separators in numeric literals Bart Van Assche
2026-11-09 20:32 ` [PATCH 46/73] c23: Support unnamed parameters in function definitions Bart Van Assche
2026-11-09 20:32 ` [PATCH 47/73] c23: Support variadic functions without named parameters Bart Van Assche
2026-11-09 20:32 ` [PATCH 48/73] c23: Support labels before declarations and at block ends Bart Van Assche
2026-11-09 20:32 ` Bart Van Assche [this message]
2026-11-09 20:32 ` [PATCH 50/73] c23: Support constexpr object specifier Bart Van Assche
2026-11-09 20:32 ` [PATCH 51/73] c23: Support enumerations with fixed underlying types Bart Van Assche
2026-11-09 20:32 ` [PATCH 52/73] c23: Support standard [[]] attribute syntax Bart Van Assche
2026-11-09 20:32 ` [PATCH 53/73] preprocessor: Add support for __has_c_attribute Bart Van Assche
2026-11-09 20:32 ` [PATCH 54/73] c23: Support empty initializer braces {} Bart Van Assche
2026-11-09 20:32 ` [PATCH 55/73] preprocessor: Add support for __has_embed Bart Van Assche
2026-11-09 20:32 ` [PATCH 56/73] preprocessor: Add support for #embed directive Bart Van Assche
2026-11-09 20:32 ` [PATCH 57/73] c23: Add support for u8 character constants and string literals Bart Van Assche
2026-11-09 20:32 ` [PATCH 58/73] preprocessor: Add support for __VA_OPT__ Bart Van Assche
2026-11-09 20:32 ` [PATCH 59/73] c23: Treat empty parameter list () as (void) and reject K&R functions Bart Van Assche
2026-11-09 20:32 ` [PATCH 60/73] c23: Support storage-class specifiers in compound literals Bart Van Assche
2026-11-09 20:32 ` [PATCH 61/73] c23: Add support for _BitInt(N) Bart Van Assche
2026-11-09 20:32 ` [PATCH 62/73] enum: Support machine mode attributes on enumeration types Bart Van Assche
2026-11-09 20:32 ` [PATCH 63/73] enum: Support __attribute__((packed)) " Bart Van Assche
2026-11-09 20:32 ` [PATCH 64/73] expand: Ignore top-level non-array address space in compare_types() Bart Van Assche
2026-11-09 20:32 ` [PATCH 65/73] builtin: Support __builtin_infer_alloc_token() as a size_t ICE Bart Van Assche
2026-11-09 20:32 ` [PATCH 66/73] builtin: Add support for Linux kernel compiler builtins Bart Van Assche
2026-11-09 20:32 ` [PATCH 67/73] builtin: Add support for __builtin_has_attribute() Bart Van Assche
2026-11-09 20:32 ` [PATCH 68/73] cleanup: Support __attribute__((cleanup(...))) in linearize and -Wcontext Bart Van Assche
2026-11-09 20:32 ` [PATCH 69/73] builtin: Do not evaluate __builtin_clz(0) and __builtin_ctz(0) Bart Van Assche
2026-11-09 20:32 ` [PATCH 70/73] pre-process: Support long token and string expansions dynamically Bart Van Assche
2026-11-09 20:32 ` [PATCH 71/73] x86: Undefine conflicting bitness macros when parsing -m flags Bart Van Assche
2026-11-09 20:32 ` [PATCH 72/73] evaluate: Accept conditional expressions with only one void side Bart Van Assche
2026-11-09 20:32 ` [PATCH 73/73] ci: Add Linux kernel GitHub Actions workflow and build script Bart Van Assche
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109203259.362845-50-bvanassche@acm.org \
--to=bvanassche@acm.org \
--cc=linux-sparse@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox