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 09/73] builtin: Fix atomic builtin type checking and object_size bounds
Date: Mon,  9 Nov 2026 12:31:55 -0800	[thread overview]
Message-ID: <20261109203259.362845-10-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>

Fix builtin argument evaluation and __builtin_object_size() expansion in
builtin.c:
- Initialize sym upfront in eval_args() before reporting argument count
  errors.
- Accept integer, enum, pointer, and restricted bitwise types in
  eval_atomic_common() while preserving per-parameter const and volatile
  pointer qualifiers via make_atomic_ptr_type().
- Bound pointer-chasing hops, unwrap parenthesized expressions, guard
  null symbols, and clamp offset subtraction in expand_object_size().
- Add regression tests in validation/atomic-builtins-types.c,
  validation/atomic-builtins-const.c, and
  validation/builtin-object-size-cycle.c.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 builtin.c                              | 112 +++++++++++++++++--------
 symbol.c                               |   3 +
 symbol.h                               |   1 +
 validation/atomic-builtins-const.c     |  67 +++++++++++++++
 validation/atomic-builtins-types.c     |  47 +++++++++++
 validation/builtin-object-size-cycle.c |  44 ++++++++++
 6 files changed, 239 insertions(+), 35 deletions(-)
 create mode 100644 validation/atomic-builtins-const.c
 create mode 100644 validation/atomic-builtins-types.c
 create mode 100644 validation/builtin-object-size-cycle.c

diff --git a/builtin.c b/builtin.c
index 1f3568bbad47..78a971ce4bb5 100644
--- a/builtin.c
+++ b/builtin.c
@@ -68,7 +68,7 @@ static int evaluate_pure_unop(struct expression *expr)
 static int eval_args(struct expression *expr, int n)
 {
 	struct expression *arg;
-	struct symbol *sym;
+	struct symbol *sym = expr->fn->ctype;
 	const char *msg;
 	int rc = 1;
 
@@ -87,7 +87,6 @@ static int eval_args(struct expression *expr, int n)
 	return rc;
 
 error:
-	sym = expr->fn->ctype;
 	expression_error(expr, "%s for %s", msg, show_ident(sym->ident));
 	return 0;
 }
@@ -454,47 +453,78 @@ struct symbol_op generic_int_op = {
 };
 
 
+static struct symbol *make_atomic_ptr_type(struct position pos,
+					   struct symbol *target,
+					   unsigned long mods,
+					   struct ident *as)
+{
+	struct symbol *ptr = alloc_symbol(pos, SYM_PTR);
+	ptr->ctype.base_type = target;
+	ptr->ctype.modifiers = mods;
+	ptr->ctype.as = as;
+	ptr->bit_size = bits_in_pointer;
+	ptr->ctype.alignment = pointer_alignment;
+	return ptr;
+}
+
 static int eval_atomic_common(struct expression *expr)
 {
 	struct symbol *fntype = expr->fn->ctype->ctype.base_type;
 	struct symbol_list *types = NULL;
 	struct symbol *ctype = NULL;
+	struct symbol *valtype = NULL;
+	struct symbol *aptr = NULL;
 	struct symbol *t;
 	struct expression *arg;
 	int n = 0;
 
 	// The number of arguments has already be verified.
-	// The first arg must be a pointer to an integral type.
+	// The first arg must be a pointer to an integral or pointer type.
 	PREPARE_PTR_LIST(fntype->arguments, t);
 	FOR_EACH_PTR(expr->args, arg) {
-		struct symbol *ptrtype = NULL;
-
 		if (++n == 1) {
-			t = arg->ctype;
-			if (!t)
+			struct symbol *proto_ptr = t ? t->ctype.base_type : NULL;
+			unsigned long proto_mods = MOD_VOLATILE;
+			if (proto_ptr && proto_ptr->ctype.base_type)
+				proto_mods = proto_ptr->ctype.base_type->ctype.modifiers;
+			aptr = arg->ctype;
+			if (!aptr)
 				return 0;
-			if (t->type == SYM_NODE)
-				t = t->ctype.base_type;
-			if (!t)
+			if (aptr->type == SYM_NODE)
+				aptr = aptr->ctype.base_type;
+			if (!aptr)
 				return 0;
-			if (t->type != SYM_PTR)
+			if (aptr->type != SYM_PTR)
 				goto err;
-			ptrtype = t;
-			t = t->ctype.base_type;
-			if (!t)
+			ctype = examine_pointer_target(aptr);
+			if (!ctype)
 				return 0;
-			if (t->type == SYM_NODE)
-				t = t->ctype.base_type;
-			if (!t)
-				return 0;
-			if (t->type != SYM_PTR && t->ctype.base_type != &int_type)
+			if (ctype->type != SYM_PTR && ctype->ctype.base_type != &int_type &&
+			    !is_int_type(ctype) && !is_restricted_type(ctype))
 				goto err;
-			ctype = t;
-			t = ptrtype;
+			valtype = ctype;
+			if (aptr->ctype.modifiers & MOD_NOCAST) {
+				struct symbol *node = alloc_symbol(arg->pos, SYM_NODE);
+				*node = *ctype;
+				node->type = SYM_NODE;
+				node->ctype.base_type = ctype;
+				node->ctype.modifiers |= MOD_NOCAST;
+				valtype = node;
+			}
+			t = make_atomic_ptr_type(
+				arg->pos, ctype,
+				proto_mods | (aptr->ctype.modifiers & (MOD_ATOMIC | MOD_NOCAST | MOD_NODEREF)),
+				aptr->ctype.as);
+		} else if (!t) {
+			break;
 		} else if (is_dynamic_type(t)) {
-			t = ctype;
-		} else if (t == &ptr_ctype) {
-			t = ptrtype;
+			t = valtype;
+		} else if (t == &ptr_ctype || t->ctype.base_type == &ptr_ctype) {
+			t = make_atomic_ptr_type(arg->pos, ctype,
+						 aptr->ctype.modifiers & MOD_NOCAST, NULL);
+		} else if (t == &const_ptr_ctype || t->ctype.base_type == &const_ptr_ctype) {
+			t = make_atomic_ptr_type(arg->pos, ctype,
+						 MOD_CONST | (aptr->ctype.modifiers & MOD_NOCAST), NULL);
 		}
 		add_ptr_list(&types, t);
 		NEXT_PTR_LIST(t);
@@ -502,7 +532,7 @@ static int eval_atomic_common(struct expression *expr)
 	FINISH_PTR_LIST(t);
 
 	if (!expr->ctype)	// set the return type, if needed
-		expr->ctype = ctype;
+		expr->ctype = valtype;
 	return evaluate_arguments(types, expr->args);
 
 err:
@@ -528,8 +558,13 @@ static int expand_object_size(struct expression *expr, int cost)
 	struct expression *arg = first_expression(expr->args);
 	int type = get_expression_value_silent(ptr_list_nth(expr->args, 1));
 	unsigned long val = -1, off = 0;
+	int hops = 0;
 
 	while (arg) {
+		if (++hops > 64) {
+			val = -1;
+			break;
+		}
 		switch (arg->type) {
 		case EXPR_IMPLIED_CAST:
 		case EXPR_CAST:
@@ -544,15 +579,20 @@ static int expand_object_size(struct expression *expr, int cost)
 			arg = arg->left;
 			continue;
 		case EXPR_PREOP:
+			if (arg->op == '(') {
+				arg = arg->unop;
+				continue;
+			}
 			// a deref is just intermediate variable
 			// and so the offset needs to be zeroed.
 			if (arg->op == '*') {
 				struct expression *parent = arg;
 				arg = arg->unop;
-				off = 0;
+				if (!arg)
+					break;
 				switch (arg->type) {
 				case EXPR_SYMBOL:
-					arg = arg->symbol->initializer;
+					arg = arg->symbol ? arg->symbol->initializer : NULL;
 					if (arg == parent) {
 						// stop at self-initialized vars
 						// and do not expand them.
@@ -562,6 +602,7 @@ static int expand_object_size(struct expression *expr, int cost)
 					}
 					continue;
 				default:
+					off = 0;
 					break;
 				}
 			}
@@ -584,7 +625,7 @@ static int expand_object_size(struct expression *expr, int cost)
 	else if (type & 1)
 		return UNSAFE;
 	else
-		val -= off;
+		val = (off > val) ? 0 : val - off;
 
 	expr->flags |= CEF_SET_ICE;
 	expr->type = EXPR_VALUE;
@@ -678,13 +719,14 @@ static const struct builtin_fn builtins_common[] = {
 #define size_t_ctype	&size_t_alias
 #define va_list_ctype	&ptr_ctype
 #define vol_ptr		&volatile_ptr_ctype
+#define cv_ptr		&const_volatile_ptr_ctype
 	{ "__atomic_add_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
-	{ "__atomic_always_lock_free", &bool_ctype, 0, { size_t_ctype, vol_ptr }},
+	{ "__atomic_always_lock_free", &bool_ctype, 0, { size_t_ctype, cv_ptr }},
 	{ "__atomic_and_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_clear", &void_ctype, 0, { &volatile_bool_ptr_ctype, &int_ctype }},
-	{ "__atomic_compare_exchange", &bool_ctype, 0, { vol_ptr, &ptr_ctype, &ptr_ctype, &bool_ctype, &int_ctype, &int_ctype }, .op = &atomic_op },
+	{ "__atomic_compare_exchange", &bool_ctype, 0, { vol_ptr, &ptr_ctype, &const_ptr_ctype, &bool_ctype, &int_ctype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_compare_exchange_n", &bool_ctype, 0, { vol_ptr, &ptr_ctype, &dyntype, &bool_ctype, &int_ctype, &int_ctype }, .op = &atomic_op },
-	{ "__atomic_exchange", &void_ctype, 0, { vol_ptr, &ptr_ctype, &ptr_ctype, &int_ctype }, .op = &atomic_op },
+	{ "__atomic_exchange", &void_ctype, 0, { vol_ptr, &const_ptr_ctype, &ptr_ctype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_exchange_n", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_fetch_add", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_fetch_and", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
@@ -692,13 +734,13 @@ static const struct builtin_fn builtins_common[] = {
 	{ "__atomic_fetch_or",  NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_fetch_sub", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_fetch_xor", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
-	{ "__atomic_is_lock_free", &bool_ctype, 0, { size_t_ctype, vol_ptr }},
-	{ "__atomic_load", &void_ctype, 0, { vol_ptr, &ptr_ctype, &int_ctype }, .op = &atomic_op },
-	{ "__atomic_load_n", NULL, 0, { vol_ptr, &int_ctype }, .op = &atomic_op },
+	{ "__atomic_is_lock_free", &bool_ctype, 0, { size_t_ctype, cv_ptr }},
+	{ "__atomic_load", &void_ctype, 0, { cv_ptr, &ptr_ctype, &int_ctype }, .op = &atomic_op },
+	{ "__atomic_load_n", NULL, 0, { cv_ptr, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_nand_fetch",NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_or_fetch",  NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_signal_fence", &void_ctype, 0, { &int_ctype }},
-	{ "__atomic_store", &void_ctype, 0, { vol_ptr, &ptr_ctype, &int_ctype }, .op = &atomic_op },
+	{ "__atomic_store", &void_ctype, 0, { vol_ptr, &const_ptr_ctype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_store_n", &void_ctype, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_sub_fetch", NULL, 0, { vol_ptr, &dyntype, &int_ctype }, .op = &atomic_op },
 	{ "__atomic_test_and_set", &bool_ctype, 0, { vol_ptr, &int_ctype }},
diff --git a/symbol.c b/symbol.c
index feaaed3b8a2d..abf3a198acc8 100644
--- a/symbol.c
+++ b/symbol.c
@@ -883,6 +883,7 @@ struct symbol	const_void_ctype, const_char_ctype;
 struct symbol	const_ptr_ctype, const_string_ctype;
 struct symbol	const_wchar_ctype, const_wstring_ctype;
 struct symbol	volatile_void_ctype, volatile_ptr_ctype;
+struct symbol	const_volatile_void_ctype, const_volatile_ptr_ctype;
 struct symbol	volatile_bool_ctype, volatile_bool_ptr_ctype;
 
 struct symbol	zero_int;
@@ -990,6 +991,8 @@ static const struct ctype_declare {
 	{ &const_wchar_ctype,  T_CONST(&int_ctype, NULL, NULL) },
 	{ &volatile_void_ctype,T_NODE(MOD_VOLATILE, &void_ctype, NULL, NULL) },
 	{ &volatile_ptr_ctype, T_PTR(&volatile_void_ctype) },
+	{ &const_volatile_void_ctype, T_NODE(MOD_CONST | MOD_VOLATILE, &void_ctype, NULL, NULL) },
+	{ &const_volatile_ptr_ctype, T_PTR(&const_volatile_void_ctype) },
 	{ &volatile_bool_ctype,T_NODE(MOD_VOLATILE, &bool_ctype, NULL, NULL) },
 	{ &volatile_bool_ptr_ctype, T_PTR(&volatile_bool_ctype) },
 	{ NULL, }
diff --git a/symbol.h b/symbol.h
index bd163450628b..9d657fbba260 100644
--- a/symbol.h
+++ b/symbol.h
@@ -316,6 +316,7 @@ extern struct symbol	const_void_ctype, const_char_ctype;
 extern struct symbol	const_ptr_ctype, const_string_ctype;
 extern struct symbol	const_wchar_ctype, const_wstring_ctype;
 extern struct symbol	volatile_void_ctype, volatile_ptr_ctype;
+extern struct symbol	const_volatile_void_ctype, const_volatile_ptr_ctype;
 extern struct symbol	volatile_bool_ctype, volatile_bool_ptr_ctype;
 
 /* Special internal symbols */
diff --git a/validation/atomic-builtins-const.c b/validation/atomic-builtins-const.c
new file mode 100644
index 000000000000..cce40c18cc5e
--- /dev/null
+++ b/validation/atomic-builtins-const.c
@@ -0,0 +1,67 @@
+static void test_atomic_const_writes(const int *cptr, int *ptr,
+				     int *exp, int *out,
+				     const _Bool *cflag)
+{
+	int val = 1;
+
+	__atomic_store(cptr, &val, 0);
+	__atomic_store_n(cptr, val, 0);
+	__atomic_load(ptr, cptr, 0);
+	__atomic_exchange(cptr, &val, out, 0);
+	__atomic_exchange(ptr, &val, cptr, 0);
+	(void)__atomic_exchange_n(cptr, val, 0);
+	(void)__atomic_compare_exchange(cptr, exp, &val, 0, 0, 0);
+	(void)__atomic_compare_exchange(ptr, cptr, &val, 0, 0, 0);
+	(void)__atomic_compare_exchange_n(cptr, exp, val, 0, 0, 0);
+	(void)__atomic_compare_exchange_n(ptr, cptr, val, 0, 0, 0);
+	(void)__atomic_fetch_add(cptr, 1, 0);
+	(void)__atomic_test_and_set(cflag, 0);
+	__atomic_clear(cflag, 0);
+}
+
+/*
+ * check-name: atomic-builtins-const
+ * check-command: sparse $file
+ *
+ * check-error-start
+atomic-builtins-const.c:7:24: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:7:24:    expected int volatile *
+atomic-builtins-const.c:7:24:    got int const *cptr
+atomic-builtins-const.c:8:26: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:8:26:    expected int volatile *
+atomic-builtins-const.c:8:26:    got int const *cptr
+atomic-builtins-const.c:9:28: warning: incorrect type in argument 2 (different modifiers)
+atomic-builtins-const.c:9:28:    expected int *
+atomic-builtins-const.c:9:28:    got int const *cptr
+atomic-builtins-const.c:10:27: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:10:27:    expected int volatile *
+atomic-builtins-const.c:10:27:    got int const *cptr
+atomic-builtins-const.c:11:38: warning: incorrect type in argument 3 (different modifiers)
+atomic-builtins-const.c:11:38:    expected int *
+atomic-builtins-const.c:11:38:    got int const *cptr
+atomic-builtins-const.c:12:35: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:12:35:    expected int volatile *
+atomic-builtins-const.c:12:35:    got int const *cptr
+atomic-builtins-const.c:13:41: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:13:41:    expected int volatile *
+atomic-builtins-const.c:13:41:    got int const *cptr
+atomic-builtins-const.c:14:46: warning: incorrect type in argument 2 (different modifiers)
+atomic-builtins-const.c:14:46:    expected int *
+atomic-builtins-const.c:14:46:    got int const *cptr
+atomic-builtins-const.c:15:43: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:15:43:    expected int volatile *
+atomic-builtins-const.c:15:43:    got int const *cptr
+atomic-builtins-const.c:16:48: warning: incorrect type in argument 2 (different modifiers)
+atomic-builtins-const.c:16:48:    expected int *
+atomic-builtins-const.c:16:48:    got int const *cptr
+atomic-builtins-const.c:17:34: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:17:34:    expected int volatile *
+atomic-builtins-const.c:17:34:    got int const *cptr
+atomic-builtins-const.c:18:37: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:18:37:    expected void volatile *
+atomic-builtins-const.c:18:37:    got bool const *cflag
+atomic-builtins-const.c:19:24: warning: incorrect type in argument 1 (different modifiers)
+atomic-builtins-const.c:19:24:    expected bool volatile *
+atomic-builtins-const.c:19:24:    got bool const *cflag
+ * check-error-end
+ */
diff --git a/validation/atomic-builtins-types.c b/validation/atomic-builtins-types.c
new file mode 100644
index 000000000000..5f163e5e60f8
--- /dev/null
+++ b/validation/atomic-builtins-types.c
@@ -0,0 +1,47 @@
+typedef unsigned int __attribute__((bitwise)) be32;
+enum E { E_ZERO, E_ONE, E_TWO };
+
+static be32 test_atomic_restricted(be32 *ptr, be32 val, be32 *expected)
+{
+	__atomic_store_n(ptr, val, 0);
+	be32 old = __atomic_exchange_n(ptr, val, 0);
+	_Bool ok = __atomic_compare_exchange_n(ptr, expected, val, 0, 0, 0);
+	(void)ok;
+	return old;
+}
+
+static enum E test_atomic_enum(enum E *ptr, enum E val)
+{
+	__atomic_store_n(ptr, val, 0);
+	return __atomic_load_n(ptr, 0);
+}
+
+static int test_atomic_const_reads(int *ptr, const int *cptr,
+				   volatile int *vptr,
+				   const volatile int *cvptr,
+				   int *expected, int *out,
+				   volatile _Bool *vflag)
+{
+	int v = __atomic_load_n(cptr, 0);
+	v += __atomic_load_n(cvptr, 0);
+
+	__atomic_load(cptr, out, 0);
+	__atomic_load(cvptr, out, 0);
+	__atomic_store(ptr, cptr, 0);
+	__atomic_exchange(ptr, cptr, out, 0);
+	(void)__atomic_compare_exchange(ptr, expected, cptr, 0, 0, 0);
+
+	__atomic_store_n(vptr, v, 0);
+	v += __atomic_fetch_add(vptr, 1, 0);
+	(void)__atomic_test_and_set(vflag, 0);
+	__atomic_clear(vflag, 0);
+
+	v += __atomic_always_lock_free(sizeof(*cvptr), cvptr);
+	v += __atomic_is_lock_free(sizeof(*cvptr), cvptr);
+	return v;
+}
+
+/*
+ * check-name: atomic-builtins-types
+ * check-command: sparse -Wbitwise $file
+ */
diff --git a/validation/builtin-object-size-cycle.c b/validation/builtin-object-size-cycle.c
new file mode 100644
index 000000000000..38e2a9786e9a
--- /dev/null
+++ b/validation/builtin-object-size-cycle.c
@@ -0,0 +1,44 @@
+static void *p2;
+static void *p1 = &p2;
+static void *p2 = &p1;
+
+static unsigned long test_static_max(void)
+{
+	return __builtin_object_size(*(void **)p1, 0);
+}
+
+static unsigned long test_static_min(void)
+{
+	return __builtin_object_size(*(void **)p1, 2);
+}
+
+/*
+ * Self-referential local pointer definitions (SSA/def cycle through OP_ADD
+ * and cast) that traverse expand_object_size()'s visited >= 64 cycle guard.
+ */
+static unsigned long test_self_add_max(void)
+{
+	char *p = p + 1;
+	return __builtin_object_size(p, 0);
+}
+
+static unsigned long test_self_add_min(void)
+{
+	char *p = p + 1;
+	return __builtin_object_size(p, 2);
+}
+
+static unsigned long test_self_cast_max(void)
+{
+	void *q = (void *)q;
+	return __builtin_object_size(q, 0);
+}
+
+/*
+ * check-name: builtin-object-size-cycle
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-contains: ret\\..*\\$-1
+ * check-output-contains: ret\\..*\\$0
+ */

  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 ` Bart Van Assche [this message]
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 ` [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-10-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