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 27/73] sparse-llvm: Support arbitrary struct member counts and fix operand types
Date: Mon,  9 Nov 2026 12:32:13 -0800	[thread overview]
Message-ID: <20261109203259.362845-28-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>

Fix LLVM IR generation crashes and limits in sparse-llvm.c:
- Dynamically allocate elem_types in sym_struct_type() instead of asserting
  at 64 members, and handle zero-sized array element types in
  sym_array_type().
- Pass instruction operand types instead of NULL to pseudo_to_value() in
  output_op_compare(), output_op_cbr(), and output_op_sel().
- Read val->label_symbol instead of val->symbol for EXPR_LABEL in
  output_op_setval().
- Add a regression test in validation/backend/struct-large-members.c.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 sparse-llvm.c                             | 23 +++----
 validation/backend/struct-large-members.c | 83 +++++++++++++++++++++++
 2 files changed, 92 insertions(+), 14 deletions(-)
 create mode 100644 validation/backend/struct-large-members.c

diff --git a/sparse-llvm.c b/sparse-llvm.c
index c422a13ce2a8..8f37bde1b98d 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -86,21 +86,17 @@ static LLVMTypeRef sym_array_type(struct symbol *sym)
 	struct symbol *base_type;
 
 	base_type = sym->ctype.base_type;
-	/* empty struct is undefined [6.7.2.1(8)] */
-	assert(base_type->bit_size > 0);
-
 	elem_type = symbol_type(base_type);
 	if (!elem_type)
 		return NULL;
 
-	return LLVMArrayType(elem_type, sym->bit_size / base_type->bit_size);
+	return LLVMArrayType(elem_type, base_type->bit_size > 0 ? sym->bit_size / base_type->bit_size : 0);
 }
 
-#define MAX_STRUCT_MEMBERS 64
-
 static LLVMTypeRef sym_struct_type(struct symbol *sym)
 {
-	LLVMTypeRef elem_types[MAX_STRUCT_MEMBERS];
+	unsigned n_memb = symbol_list_size(sym->symbol_list);
+	LLVMTypeRef *elem_types = calloc(n_memb, sizeof(LLVMTypeRef));
 	struct symbol *member;
 	char buffer[256];
 	LLVMTypeRef ret;
@@ -114,14 +110,13 @@ static LLVMTypeRef sym_struct_type(struct symbol *sym)
 	FOR_EACH_PTR(sym->symbol_list, member) {
 		LLVMTypeRef member_type;
 
-		assert(nr < MAX_STRUCT_MEMBERS);
-
 		member_type = symbol_type(member);
 
 		elem_types[nr++] = member_type; 
 	} END_FOR_EACH_PTR(member);
 
 	LLVMStructSetBody(ret, elem_types, nr, 0 /* packed? */); 
+	free(elem_types);
 	return ret;
 }
 
@@ -663,11 +658,11 @@ static void output_op_compare(struct function *fn, struct instruction *insn)
 	LLVMValueRef lhs, rhs, target;
 	char target_name[64];
 
-	lhs = pseudo_to_value(fn, NULL, insn->src1);
+	lhs = pseudo_to_value(fn, insn->itype, insn->src1);
 	if (insn->src2->type == PSEUDO_VAL)
 		rhs = constant_value(insn->src2->value, LLVMTypeOf(lhs));
 	else
-		rhs = pseudo_to_value(fn, NULL, insn->src2);
+		rhs = pseudo_to_value(fn, insn->itype, insn->src2);
 	if (!rhs)
 		rhs = LLVMGetUndef(symbol_type(insn->type));
 
@@ -785,7 +780,7 @@ static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
 static void output_op_cbr(struct function *fn, struct instruction *br)
 {
 	LLVMValueRef cond = bool_value(fn,
-			pseudo_to_value(fn, NULL, br->cond));
+			pseudo_to_value(fn, br->type ? br->type : &int_ctype, br->cond));
 
 	LLVMBuildCondBr(fn->builder, cond,
 			br->bb_true->priv,
@@ -802,7 +797,7 @@ static void output_op_sel(struct function *fn, struct instruction *insn)
 	LLVMValueRef target, src1, src2, src3;
 	char name[MAX_PSEUDO_NAME];
 
-	src1 = bool_value(fn, pseudo_to_value(fn, NULL, insn->src1));
+	src1 = bool_value(fn, pseudo_to_value(fn, insn->itype ? insn->itype : insn->type, insn->src1));
 	src2 = get_operand(fn, insn->type, insn->src2);
 	src3 = get_operand(fn, insn->type, insn->src3);
 
@@ -1001,7 +996,7 @@ static void output_op_setval(struct function *fn, struct instruction *insn)
 
 	switch (val->type) {
 	case EXPR_LABEL:
-		target = LLVMBlockAddress(fn->fn, val->symbol->bb_target->priv);
+		target = LLVMBlockAddress(fn->fn, val->label_symbol->bb_target->priv);
 		break;
 	default:
 		assert(0);
diff --git a/validation/backend/struct-large-members.c b/validation/backend/struct-large-members.c
new file mode 100644
index 000000000000..65f382194d5d
--- /dev/null
+++ b/validation/backend/struct-large-members.c
@@ -0,0 +1,83 @@
+struct big_struct {
+	int f0;
+	int f1;
+	int f2;
+	int f3;
+	int f4;
+	int f5;
+	int f6;
+	int f7;
+	int f8;
+	int f9;
+	int f10;
+	int f11;
+	int f12;
+	int f13;
+	int f14;
+	int f15;
+	int f16;
+	int f17;
+	int f18;
+	int f19;
+	int f20;
+	int f21;
+	int f22;
+	int f23;
+	int f24;
+	int f25;
+	int f26;
+	int f27;
+	int f28;
+	int f29;
+	int f30;
+	int f31;
+	int f32;
+	int f33;
+	int f34;
+	int f35;
+	int f36;
+	int f37;
+	int f38;
+	int f39;
+	int f40;
+	int f41;
+	int f42;
+	int f43;
+	int f44;
+	int f45;
+	int f46;
+	int f47;
+	int f48;
+	int f49;
+	int f50;
+	int f51;
+	int f52;
+	int f53;
+	int f54;
+	int f55;
+	int f56;
+	int f57;
+	int f58;
+	int f59;
+	int f60;
+	int f61;
+	int f62;
+	int f63;
+	int f64;
+	int f65;
+	int f66;
+	int f67;
+	int f68;
+	int f69;
+};
+
+static struct big_struct s;
+static int get_f69(void)
+{
+	return s.f69;
+}
+
+/*
+ * check-name: struct-large-members
+ * check-command: sparsec -c $file -o tmp.o
+ */

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