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 48/73] c23: Support labels before declarations and at block ends
Date: Mon,  9 Nov 2026 12:32:34 -0800	[thread overview]
Message-ID: <20261109203259.362845-49-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>

Allow named, case, and default labels (including chained labels) to
precede declarations and closing '}' braces inside compound statements
per ISO C23 6.8.1 and 6.8.2:
- Handle label chains at the block-item level in statement_list() by
  attaching a synthesized empty statement when a label precedes a
  declaration, static_assert, or '}', and emit pedantic warnings in
  pre-C23 modes.
- Keep substatements of selection and iteration statements restricted to
  true statements in statement() so invalid forms such as
  'if (c) int x = 1;' and '{ if (c) lbl: }' are rejected cleanly.
- Recognize labels whose identifier shadows an outer typedef name.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 parse.c                          | 206 ++++++++++++++++++++++---------
 validation/c23-labels-error.c    |  48 +++++++
 validation/c23-labels-gnu.c      |  15 +++
 validation/c23-labels-pedantic.c |  15 +++
 validation/c23-labels.c          |  67 ++++++++++
 5 files changed, 296 insertions(+), 55 deletions(-)
 create mode 100644 validation/c23-labels-error.c
 create mode 100644 validation/c23-labels-gnu.c
 create mode 100644 validation/c23-labels-pedantic.c
 create mode 100644 validation/c23-labels.c

diff --git a/parse.c b/parse.c
index 78ad5f09e2ad..1e91825f8d38 100644
--- a/parse.c
+++ b/parse.c
@@ -62,8 +62,6 @@ static declarator_t autotype_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);
 static struct token *parse_loop_iterator(struct token *token, struct statement *stmt);
-static struct token *parse_default_statement(struct token *token, struct statement *stmt);
-static struct token *parse_case_statement(struct token *token, struct statement *stmt);
 static struct token *parse_switch_statement(struct token *token, struct statement *stmt);
 static struct token *parse_for_statement(struct token *token, struct statement *stmt);
 static struct token *parse_while_statement(struct token *token, struct statement *stmt);
@@ -315,11 +313,9 @@ static struct symbol_op loop_iter_op = {
 };
 
 static struct symbol_op default_op = {
-	.statement = parse_default_statement,
 };
 
 static struct symbol_op case_op = {
-	.statement = parse_case_statement,
 };
 
 static struct symbol_op switch_op = {
@@ -2518,32 +2514,6 @@ static struct token *parse_if_statement(struct token *token, struct statement *s
 	return statement(token->next, &stmt->if_false);
 }
 
-static inline struct token *case_statement(struct token *token, struct statement *stmt)
-{
-	stmt->type = STMT_CASE;
-	token = expect(token, ':', "after default/case");
-	add_case_statement(stmt);
-	if (match_op(token, '}')) {
-		warning(token->pos, "statement expected after case label");
-		stmt->case_statement = alloc_statement(token->pos, STMT_NONE);
-		return token;
-	}
-	return statement(token, &stmt->case_statement);
-}
-
-static struct token *parse_case_statement(struct token *token, struct statement *stmt)
-{
-	token = parse_expression(token->next, &stmt->case_expression);
-	if (match_op(token, SPECIAL_ELLIPSIS))
-		token = parse_expression(token->next, &stmt->case_to);
-	return case_statement(token, stmt);
-}
-
-static struct token *parse_default_statement(struct token *token, struct statement *stmt)
-{
-	return case_statement(token->next, stmt);
-}
-
 static struct token *parse_loop_iterator(struct token *token, struct statement *stmt)
 {
 	struct symbol *target = lookup_symbol(token->ident, NS_ITERATOR);
@@ -2646,46 +2616,129 @@ static struct token *handle_label_attributes(struct token *token, struct symbol
 	return token;
 }
 
+static bool is_label_token(struct token *token)
+{
+	struct token *p = token;
+	struct symbol *s;
+
+	if (token_type(p) != TOKEN_IDENT)
+		return false;
+	if (p->ident == &case_ident || p->ident == &default_ident)
+		return true;
+	s = lookup_keyword(p->ident, NS_KEYWORD);
+	if (s && s->op->statement)
+		return false;
+	if (p->ident->reserved)
+		return false;
+	return match_op(p->next, ':');
+}
+
+static struct token *parse_one_label(struct token *token,
+				     struct statement **stmtp,
+				     bool *is_case)
+{
+	struct decl_state attr_state = { };
+	struct statement *stmt;
+
+	*stmtp = NULL;
+	*is_case = false;
+
+	if (token->ident == &case_ident) {
+		stmt = alloc_statement(token->pos, STMT_CASE);
+		token = parse_expression(token->next, &stmt->case_expression);
+		if (match_op(token, SPECIAL_ELLIPSIS))
+			token = parse_expression(token->next, &stmt->case_to);
+		token = expect(token, ':', "after default/case");
+		add_case_statement(stmt);
+		*stmtp = stmt;
+		*is_case = true;
+		return token;
+	}
+	if (token->ident == &default_ident) {
+		stmt = alloc_statement(token->pos, STMT_CASE);
+		token = expect(token->next, ':', "after default/case");
+		add_case_statement(stmt);
+		*stmtp = stmt;
+		*is_case = true;
+		return token;
+	}
+
+	{
+		struct position pos = token->pos;
+		struct symbol *s = label_symbol(token, 0);
+		s->label_modifiers |= attr_state.ctype.modifiers;
+		token = handle_label_attributes(token->next->next, s);
+		if (s->stmt) {
+			sparse_error(pos, "label '%s' redefined",
+				     show_ident(s->ident));
+			return token;
+		}
+		stmt = alloc_statement(pos, STMT_LABEL);
+		stmt->label_identifier = s;
+		stmt->label_scope = label_scope;
+		if (s->label_scope) {
+			if (!is_in_scope(label_scope, s->label_scope))
+				warn_label_usage(stmt->pos, s->label_pos,
+						 s->ident);
+		}
+		s->stmt = stmt;
+		*stmtp = stmt;
+		return token;
+	}
+}
+
 static struct token *statement(struct token *token, struct statement **tree)
 {
 	struct statement *stmt = alloc_statement(token->pos, STMT_NONE);
 
+	if (is_label_token(token)) {
+		struct statement *lbl = NULL;
+		bool is_case = false;
+
+		token = parse_one_label(token, &lbl, &is_case);
+		if (!lbl)
+			return statement(token, tree);
+		*tree = lbl;
+		tree = is_case ? &lbl->case_statement : &lbl->label_statement;
+		if (match_op(token, '}')) {
+			sparse_error(token->pos,
+				     is_case ? "statement expected after case label" :
+					       "statement expected after label");
+			*tree = alloc_statement(token->pos, STMT_NONE);
+			return token;
+		}
+		return statement(token, tree);
+	}
+
 	*tree = stmt;
 	if (token_type(token) == TOKEN_IDENT) {
 		struct symbol *s = lookup_keyword(token->ident, NS_KEYWORD);
 		if (s && s->op->statement)
 			return s->op->statement(token, stmt);
-
-		if (match_op(token->next, ':')) {
-			struct symbol *s = label_symbol(token, 0);
-			token = handle_label_attributes(token->next->next, s);
-			if (s->stmt) {
-				sparse_error(stmt->pos, "label '%s' redefined", show_ident(s->ident));
-				// skip the label to avoid multiple definitions
-				return statement(token, tree);
-			}
-			stmt->type = STMT_LABEL;
-			stmt->label_identifier = s;
-			stmt->label_scope = label_scope;
-			if (s->label_scope) {
-				if (!is_in_scope(label_scope, s->label_scope))
-					warn_label_usage(stmt->pos, s->label_pos, s->ident);
-			}
-			s->stmt = stmt;
-			if (match_op(token, '}')) {
-				warning(token->pos, "statement expected after label");
-				stmt->label_statement = alloc_statement(token->pos, STMT_NONE);
-				return token;
-			}
-			return statement(token, &stmt->label_statement);
-		}
 	}
 
 	if (match_op(token, '{')) {
 		token = compound_statement(token->next, stmt);
 		return expect(token, '}', "at end of compound statement");
 	}
-			
+
+	if (match_ident(token, &_Static_assert_ident) ||
+	    (standard >= STANDARD_C23 &&
+	     match_ident(token, &static_assert_ident))) {
+		sparse_error(token->pos, "declaration is not a statement");
+		stmt->type = STMT_NONE;
+		return parse_static_assert(token, NULL);
+	}
+
+	if (lookup_type(token)) {
+		sparse_error(token->pos, "declaration is not a statement");
+		stmt->type = STMT_DECLARATION;
+		start_block_scope();
+		token = external_declaration(token, &stmt->declaration, NULL);
+		end_block_scope();
+		return token;
+	}
+
 	stmt->type = STMT_EXPRESSION;
 	return expression_statement(token, &stmt->expression);
 }
@@ -2714,6 +2767,49 @@ static struct token * statement_list(struct token *token, struct statement_list
 		token = label_statement(token->next);
 	for (;;) {
 		struct statement * stmt;
+		struct statement *label_head = NULL;
+		struct statement **label_tail = &label_head;
+		bool last_is_case = false;
+
+		while (is_label_token(token)) {
+			struct statement *lbl = NULL;
+			bool is_case = false;
+
+			token = parse_one_label(token, &lbl, &is_case);
+			if (!lbl)
+				continue;
+			*label_tail = lbl;
+			label_tail = is_case ? &lbl->case_statement :
+					       &lbl->label_statement;
+			last_is_case = is_case;
+		}
+		if (label_head) {
+			if (eof_token(token) || match_op(token, '}')) {
+				if (standard < STANDARD_C23)
+					warning(token->pos,
+						last_is_case ? "statement expected after case label" :
+							       "statement expected after label");
+				*label_tail = alloc_statement(token->pos, STMT_NONE);
+				add_statement(list, label_head);
+				break;
+			}
+			if (match_ident(token, &_Static_assert_ident) ||
+			    (standard >= STANDARD_C23 &&
+			     match_ident(token, &static_assert_ident)) ||
+			    lookup_type(token)) {
+				if (standard < STANDARD_C23 && Wpedantic)
+					warning(token->pos,
+						"a label can only be part of a statement and a declaration is not a statement");
+				*label_tail = alloc_statement(token->pos, STMT_NONE);
+				add_statement(list, label_head);
+			} else {
+				seen_statement = Wdeclarationafterstatement;
+				token = statement(token, label_tail);
+				add_statement(list, label_head);
+				continue;
+			}
+		}
+
 		if (eof_token(token))
 			break;
 		if (match_op(token, '}'))
diff --git a/validation/c23-labels-error.c b/validation/c23-labels-error.c
new file mode 100644
index 000000000000..55ee5bfd5b47
--- /dev/null
+++ b/validation/c23-labels-error.c
@@ -0,0 +1,48 @@
+static void test_dup(void)
+{
+dup:
+	;
+dup:
+	;
+}
+
+static void test_if_decl(int c)
+{
+	if (c)
+		int x = 1;
+}
+
+static void test_if_label_decl(int c)
+{
+	if (c)
+	lbl1:
+		int y = 2;
+}
+
+static void test_if_label_end(int c)
+{
+	if (c)
+	lbl2:
+}
+
+static void test_outside_switch(void)
+{
+	case 1:
+		;
+	default:
+		;
+}
+
+/*
+ * check-name: c23-labels-error
+ * check-command: sparse -std=c23 -Wno-decl $file
+ *
+ * check-error-start
+c23-labels-error.c:5:1: error: label 'dup' redefined
+c23-labels-error.c:12:17: error: declaration is not a statement
+c23-labels-error.c:19:17: error: declaration is not a statement
+c23-labels-error.c:26:1: error: statement expected after label
+c23-labels-error.c:30:9: error: not in switch scope
+c23-labels-error.c:32:9: error: not in switch scope
+ * check-error-end
+ */
diff --git a/validation/c23-labels-gnu.c b/validation/c23-labels-gnu.c
new file mode 100644
index 000000000000..15dcb20be1d8
--- /dev/null
+++ b/validation/c23-labels-gnu.c
@@ -0,0 +1,15 @@
+static int test_gnu_case_range(int c)
+{
+	switch (c) {
+	case 1 ... 5:
+		int a = 3;
+		return a;
+	case 6 ... 9:
+	}
+	return 0;
+}
+
+/*
+ * check-name: c23-labels-gnu
+ * check-command: sparse -std=gnu23 -Wno-decl $file
+ */
diff --git a/validation/c23-labels-pedantic.c b/validation/c23-labels-pedantic.c
new file mode 100644
index 000000000000..6048f2e48e96
--- /dev/null
+++ b/validation/c23-labels-pedantic.c
@@ -0,0 +1,15 @@
+static void test_label_decl(void)
+{
+	goto lbl;
+lbl:
+	int x = 42;
+}
+
+/*
+ * check-name: c23-labels-pedantic
+ * check-command: sparse -std=c11 -pedantic -Wno-decl $file
+ *
+ * check-error-start
+c23-labels-pedantic.c:5:9: warning: a label can only be part of a statement and a declaration is not a statement
+ * check-error-end
+ */
diff --git a/validation/c23-labels.c b/validation/c23-labels.c
new file mode 100644
index 000000000000..b4d90edbe666
--- /dev/null
+++ b/validation/c23-labels.c
@@ -0,0 +1,67 @@
+typedef int T_shadow;
+
+static int test_label_decl(void)
+{
+	goto lbl;
+lbl:
+lbl_chain:
+	int x = 42;
+	if (!x)
+		goto lbl_chain;
+	return x;
+}
+
+static int test_case_decl(int c)
+{
+	switch (c) {
+	case 1:
+		int a = 10;
+		return a;
+	default:
+		int b = 20;
+		return b;
+	}
+}
+
+static void test_label_end(int c)
+{
+	if (c == 1)
+		goto end1;
+	if (c == 2)
+		goto end2;
+end1:
+end2:
+}
+
+static void test_case_end(int c)
+{
+	switch (c) {
+	case 0:
+	case 1:
+	}
+	switch (c) {
+	default:
+	}
+}
+
+static void test_label_static_assert(void)
+{
+	goto lbl2;
+lbl2:
+	static_assert(1, "");
+}
+
+static int test_typedef_shadow_label(int c)
+{
+	if (c)
+		goto T_shadow;
+	return 0;
+T_shadow:
+	int v = 1;
+	return v;
+}
+
+/*
+ * check-name: c23-labels
+ * check-command: sparse -std=c23 -pedantic -Wno-decl $file
+ */

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