Linux SPARSE checker discussions
 help / color / mirror / Atom feed
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 72/73] evaluate: Accept conditional expressions with only one void side
Date: Mon,  9 Nov 2026 12:32:58 -0800	[thread overview]
Message-ID: <20261109203259.362845-73-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>

Accept conditional expressions in which exactly one of the second and
third operands has complete type void as a GNU extension matching GCC
and Clang: give the expression type void, evaluate the non-void operand
only for its side effects, warn only under -Wpedantic, and avoid
emitting zero-sized phi nodes in linearize_conditional().

Support Linux kernel macros such as STA_ASSIGN in net/mac80211/trace.h
and nfs_errorf() in fs/nfs/internal.h without false "incompatible types
in conditional expression" errors while continuing to diagnose uses of
the void result value.

Update validation/cond-err-expand.c and add validation/cond-one-void.c
and validation/cond-one-void-pedantic.c.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 evaluate.c                          | 113 ++++++++++++++++++----------
 expand.c                            |  17 ++++-
 linearize.c                         |  19 +++++
 validation/cond-err-expand.c        |   9 ---
 validation/cond-one-void-pedantic.c |  39 ++++++++++
 validation/cond-one-void.c          |  47 ++++++++++++
 validation/linear/cond-one-void.c   |  24 ++++++
 7 files changed, 217 insertions(+), 51 deletions(-)
 create mode 100644 validation/cond-one-void-pedantic.c
 create mode 100644 validation/cond-one-void.c
 create mode 100644 validation/linear/cond-one-void.c

diff --git a/evaluate.c b/evaluate.c
index 6e1be32f929f..927c4f35d831 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1421,6 +1421,37 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr)
 
 	lclass = classify_type(ltype, &ltype);
 	rclass = classify_type(rtype, &rtype);
+
+	/*
+	 * GNU extension supported by gcc and clang: if exactly one of the
+	 * second and third operands has type void, the result has type void
+	 * and the other operand is only evaluated for its side effects.
+	 * ISO C forbids this [6.5.15(3)].
+	 */
+	if ((ltype == &void_ctype) != (rtype == &void_ctype)) {
+		struct symbol *other_type = (ltype == &void_ctype) ? rtype : ltype;
+
+		if (!valid_type(other_type)) {
+			expr->flags = CEF_NONE;
+			expr->ctype = &bad_ctype;
+			return NULL;
+		}
+		if (other_type == &incomplete_ctype || other_type->bit_size < 0 ||
+		    ((other_type->type == SYM_STRUCT || other_type->type == SYM_UNION) &&
+		     !other_type->defined)) {
+			expression_error(expr, "expression has incomplete type '%s'",
+					 show_typename(other_type));
+			return NULL;
+		}
+		if (Wpedantic)
+			warning(expr->pos, "ISO C forbids conditional expression with only one void side");
+		if (expr->cond_true)
+			*cond = cast_to(*cond, &void_ctype);
+		expr->cond_false = cast_to(expr->cond_false, &void_ctype);
+		ctype = &void_ctype;
+		goto out;
+	}
+
 	if (lclass & rclass & TYPE_NUM) {
 		ctype = usual_conversions('?', *cond, expr->cond_false,
 					  lclass, rclass, ltype, rtype);
@@ -3127,7 +3158,8 @@ static void check_constexpr_scalar_init(struct expression *orig,
 		}
 		tmp = *orig;
 		if (!is_null_pointer_constant(&tmp) &&
-		    !(((sclass & TYPE_PTR) || is_nullptr_type(stype)) && is_zero_constant(&tmp)))
+		    !(((sclass & TYPE_PTR) || is_nullptr_type(stype)) &&
+		      is_zero_constant(&tmp)))
 			sparse_error(orig->pos,
 				     "constexpr pointer initializer is not null");
 		return;
@@ -3309,7 +3341,6 @@ static int handle_initializer(struct expression **ep, int nested,
 		struct expression orig;
 
 		e = handle_scalar(e, nested, class, ctype);
-
 		if (!e)
 			return 0;
 		*ep = e;
@@ -3323,11 +3354,11 @@ static int handle_initializer(struct expression **ep, int nested,
 		 * shall be constant expressions or a string literal [6.7.8(4)].
 		 */
 		mods |= ctype->ctype.modifiers;
-		if (mods & MOD_CONSTEXPR)
+		if (mods & MOD_CONSTEXPR) {
 			check_constexpr_scalar_init(&orig, ctype);
-		else if ((mods & (MOD_TOPLEVEL | MOD_STATIC | MOD_TLS)) &&
-			 valid_type(ctype->ctype.base_type) &&
-			 !(e->flags & (CEF_ACE | CEF_ADDR))) {
+		} else if ((mods & (MOD_TOPLEVEL | MOD_STATIC | MOD_TLS)) &&
+			   valid_type(ctype->ctype.base_type) &&
+			   !(e->flags & (CEF_ACE | CEF_ADDR))) {
 			if (standard >= STANDARD_C23)
 				sparse_error(e->pos, "non-constant initializer for static object");
 			else if (Wconstexpr_not_const)
@@ -4187,6 +4218,41 @@ void check_duplicates(struct symbol *sym)
 	}
 }
 
+static void evaluate_cleanup(struct symbol *sym)
+{
+	struct expression *var_expr, *addr_expr, *fn_expr, *call;
+
+	if (!sym->cleanup || sym->cleanup->type != EXPR_SYMBOL)
+		return;
+
+	if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC | MOD_EXTERN)) {
+		sparse_error(sym->pos, "cleanup attribute may only be applied to local variables");
+		sym->cleanup = NULL;
+		return;
+	}
+
+	var_expr = alloc_expression(sym->pos, EXPR_SYMBOL);
+	var_expr->symbol = sym;
+	var_expr->symbol_name = sym->ident;
+	evaluate_expression(var_expr);
+
+	addr_expr = alloc_expression(sym->pos, EXPR_PREOP);
+	addr_expr->op = '&';
+	addr_expr->unop = var_expr;
+	evaluate_expression(addr_expr);
+
+	fn_expr = alloc_expression(sym->cleanup->pos, EXPR_SYMBOL);
+	fn_expr->symbol = sym->cleanup->symbol;
+	fn_expr->symbol_name = sym->cleanup->symbol_name;
+
+	call = alloc_expression(sym->pos, EXPR_CALL);
+	call->fn = fn_expr;
+	add_expression(&call->args, addr_expr);
+	evaluate_call(call);
+
+	sym->cleanup = call;
+}
+
 static bool check_constexpr_vm_type(struct symbol *type)
 {
 	while (type) {
@@ -4236,41 +4302,6 @@ static bool has_invalid_constexpr_qualifiers(struct symbol *type)
 	return false;
 }
 
-static void evaluate_cleanup(struct symbol *sym)
-{
-	struct expression *var_expr, *addr_expr, *fn_expr, *call;
-
-	if (!sym->cleanup || sym->cleanup->type != EXPR_SYMBOL)
-		return;
-
-	if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC | MOD_EXTERN)) {
-		sparse_error(sym->pos, "cleanup attribute may only be applied to local variables");
-		sym->cleanup = NULL;
-		return;
-	}
-
-	var_expr = alloc_expression(sym->pos, EXPR_SYMBOL);
-	var_expr->symbol = sym;
-	var_expr->symbol_name = sym->ident;
-	evaluate_expression(var_expr);
-
-	addr_expr = alloc_expression(sym->pos, EXPR_PREOP);
-	addr_expr->op = '&';
-	addr_expr->unop = var_expr;
-	evaluate_expression(addr_expr);
-
-	fn_expr = alloc_expression(sym->cleanup->pos, EXPR_SYMBOL);
-	fn_expr->symbol = sym->cleanup->symbol;
-	fn_expr->symbol_name = sym->cleanup->symbol_name;
-
-	call = alloc_expression(sym->pos, EXPR_CALL);
-	call->fn = fn_expr;
-	add_expression(&call->args, addr_expr);
-	evaluate_call(call);
-
-	sym->cleanup = call;
-}
-
 static struct symbol *evaluate_symbol(struct symbol *sym)
 {
 	struct symbol *base_type;
diff --git a/expand.c b/expand.c
index 5c3777ff3a23..1888effa4e37 100644
--- a/expand.c
+++ b/expand.c
@@ -850,6 +850,7 @@ static int expand_conditional(struct expression *expr)
 
 	cond_cost = expand_expression(cond);
 	if (cond->type == EXPR_VALUE) {
+		struct symbol *ctype = expr->ctype;
 		unsigned flags = expr->flags;
 		if (!cond->value && !cond->value_hi)
 			valt = valf;
@@ -860,13 +861,27 @@ static int expand_conditional(struct expression *expr)
 		expr->flags = flags;
 		if (expr->type == EXPR_VALUE)
 			expr->taint |= cond->taint;
+		if (ctype == &void_ctype && expr->ctype != &void_ctype) {
+			if (expr->type == EXPR_VALUE || expr->type == EXPR_FVALUE) {
+				expr->type = EXPR_VALUE;
+				expr->value = 0;
+				expr->ctype = &void_ctype;
+			} else {
+				struct expression *sub = alloc_expression(expr->pos, expr->type);
+				*sub = *expr;
+				expr->type = EXPR_CAST;
+				expr->ctype = &void_ctype;
+				expr->cast_type = &void_ctype;
+				expr->cast_expression = sub;
+			}
+		}
 		return cost;
 	}
 
 	cost = expand_expression(valt);
 	cost += expand_expression(valf);
 
-	if (cost < SELECT_COST) {
+	if (expr->ctype != &void_ctype && cost < SELECT_COST) {
 		expr->type = EXPR_SELECT;
 		cost -= BRANCH_COST - 1;
 	}
diff --git a/linearize.c b/linearize.c
index 9d36415551d6..9dc2fecfe731 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1699,6 +1699,14 @@ static pseudo_t linearize_short_conditional(struct entrypoint *ep, struct expres
 	bb_false = alloc_basic_block(ep, expr_false->pos);
 	merge = alloc_basic_block(ep, expr->pos);
 
+	if (expr->ctype == &void_ctype || type_size(expr->ctype) <= 0) {
+		linearize_cond_branch(ep, cond, merge, bb_false);
+		set_activeblock(ep, bb_false);
+		linearize_expression(ep, expr_false);
+		set_activeblock(ep, merge);
+		return VOID;
+	}
+
 	src1 = linearize_expression(ep, cond);
 	phi1 = alloc_phi(ep->active, src1, expr->ctype);
 	add_branch(ep, src1, merge, bb_false);
@@ -1728,6 +1736,17 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
 
 	linearize_cond_branch(ep, cond, bb_true, bb_false);
 
+	if (expr->ctype == &void_ctype || type_size(expr->ctype) <= 0) {
+		set_activeblock(ep, bb_true);
+		linearize_expression(ep, expr_true);
+		add_goto(ep, merge);
+
+		set_activeblock(ep, bb_false);
+		linearize_expression(ep, expr_false);
+		set_activeblock(ep, merge);
+		return VOID;
+	}
+
 	set_activeblock(ep, bb_true);
 	src1 = linearize_expression(ep, expr_true);
 	phi1 = alloc_phi(ep->active, src1, expr->ctype);
diff --git a/validation/cond-err-expand.c b/validation/cond-err-expand.c
index b52624bc9de5..f24235a22e68 100644
--- a/validation/cond-err-expand.c
+++ b/validation/cond-err-expand.c
@@ -17,15 +17,6 @@ void bar(void)
  * check-name: cond-err-expand.c
  * check-command: test-linearize -Wno-decl $file
  *
- * check-error-start
-cond-err-expand.c:8:11: error: incompatible types in conditional expression (different base types):
-cond-err-expand.c:8:11:    int
-cond-err-expand.c:8:11:    void
-cond-err-expand.c:13:11: error: incompatible types in conditional expression (different base types):
-cond-err-expand.c:13:11:    void
-cond-err-expand.c:13:11:    int
- * check-error-end
- *
  * check-output-ignore
  * check-output-excludes: call.* __builtin_constant_p
  */
diff --git a/validation/cond-one-void-pedantic.c b/validation/cond-one-void-pedantic.c
new file mode 100644
index 000000000000..f91254f52c04
--- /dev/null
+++ b/validation/cond-one-void-pedantic.c
@@ -0,0 +1,39 @@
+void *f(void);
+void g(void);
+int h(void);
+extern void *p;
+
+static void test(int c)
+{
+	c ? f() : g();
+	c ? g() : h();
+	c ? 1 : g();
+	c ? p : g();
+	p ?: g();
+	c ? g() : (void)0;		// both sides void: always OK
+	(void)(c ? h() : g());
+}
+
+static int use_value(int c)
+{
+	int x = c ? h() : g();		// KO: void value used
+	return x;
+}
+
+/*
+ * check-name: cond-one-void-pedantic
+ * check-command: sparse -Wpedantic $file
+ *
+ * check-error-start
+cond-one-void-pedantic.c:8:11: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:9:11: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:10:11: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:11:11: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:12:11: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:14:18: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:19:19: warning: ISO C forbids conditional expression with only one void side
+cond-one-void-pedantic.c:19:19: warning: incorrect type in initializer (different base types)
+cond-one-void-pedantic.c:19:19:    expected int x
+cond-one-void-pedantic.c:19:19:    got void
+ * check-error-end
+ */
diff --git a/validation/cond-one-void.c b/validation/cond-one-void.c
new file mode 100644
index 000000000000..6034dbb218a9
--- /dev/null
+++ b/validation/cond-one-void.c
@@ -0,0 +1,47 @@
+void *f(void);
+void g(void);
+int h(void);
+extern void *p;
+
+static void test(int c)
+{
+	c ? f() : g();
+	c ? g() : h();
+	c ? 1 : g();
+	c ? p : g();
+	p ?: g();
+	1 ?: g();
+	0 ?: g();
+	c ? g() : (void)0;		// both sides void: always OK
+	(void)(c ? h() : g());
+}
+
+struct empty {};
+struct incomplete;
+extern struct empty emp;
+extern struct incomplete inc;
+
+static int use_value(int c)
+{
+	int x = c ? h() : g();		// KO: void value used
+	int y = 1 ?: g();		// KO: void value used
+	c ? (void)0 : emp;		// OK: complete empty struct
+	c ? (void)0 : inc;		// KO: incomplete type
+	return x + y;
+}
+
+/*
+ * check-name: cond-one-void
+ * check-description: Like gcc and clang, accept conditional expressions
+ *	with only one void side and give these type void.
+ *
+ * check-error-start
+cond-one-void.c:26:19: warning: incorrect type in initializer (different base types)
+cond-one-void.c:26:19:    expected int x
+cond-one-void.c:26:19:    got void
+cond-one-void.c:27:19: warning: incorrect type in initializer (different base types)
+cond-one-void.c:27:19:    expected int y
+cond-one-void.c:27:19:    got void
+cond-one-void.c:29:11: error: expression has incomplete type 'struct incomplete'
+ * check-error-end
+ */
diff --git a/validation/linear/cond-one-void.c b/validation/linear/cond-one-void.c
new file mode 100644
index 000000000000..6c962809736f
--- /dev/null
+++ b/validation/linear/cond-one-void.c
@@ -0,0 +1,24 @@
+void *f(void);
+void g(void);
+int h(void);
+
+void test_cond_void_ir(int c, void *p)
+{
+	c ? f() : g();
+	c ? g() : h();
+	c ? 1 : g();
+	p ?: g();
+	1 ?: g();
+	0 ?: g();
+}
+
+/*
+ * check-name: cond-one-void-linearize
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: VOID
+ * check-output-excludes: phi\\.
+ * check-output-excludes: phisrc\\.
+ * check-output-excludes: select\\.
+ */

  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 ` [PATCH 49/73] c23: Support auto type inference Bart Van Assche
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 ` Bart Van Assche [this message]
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-73-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