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 37/73] bitwise: Allow both regular casts and forced casts for restricted values
Date: Mon, 9 Nov 2026 12:32:23 -0800 [thread overview]
Message-ID: <20261109203259.362845-38-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Allow EXPR_FORCE_CAST as well as EXPR_CAST in restricted_value() when
checking whether an expression is a cast of 0 or ~0.
Support restricted constants defined with '__force' in kernel headers
(for example, '#define EPOLLIN (__force __poll_t)0x00000001') by
recognizing both forced and unforced casts of 0 and ~0 in
restricted_value().
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[ bvanassche: Rewrite commit message in imperative mood, fix typo, unwrap
EXPR_FORCE_CAST in restricted_value(), and extend
validation/bitwise-all-bits-and-casts.c ]
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
evaluate.c | 4 +--
validation/bitwise-all-bits-and-casts.c | 46 +++++++++++++++++++++++--
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/evaluate.c b/evaluate.c
index b84eedbe4d33..ec02e5bbc4fe 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -443,7 +443,7 @@ static bool is_unsigned_restricted_or_int(struct symbol *sym)
static int restricted_value(struct expression *v, struct symbol *type)
{
- if (v->type == EXPR_CAST) {
+ if (v->type == EXPR_CAST || v->type == EXPR_FORCE_CAST) {
struct symbol *ctype;
int cclass = classify_type(v->ctype, &ctype);
struct expression *leaf = v->cast_expression;
@@ -452,7 +452,7 @@ static int restricted_value(struct expression *v, struct symbol *type)
return 1;
if (restricted_value(v->cast_expression, ctype))
return 1;
- while (leaf && leaf->type == EXPR_CAST)
+ while (leaf && (leaf->type == EXPR_CAST || leaf->type == EXPR_FORCE_CAST))
leaf = leaf->cast_expression;
if (leaf && leaf->type == EXPR_VALUE && leaf->value == 0)
return 0;
diff --git a/validation/bitwise-all-bits-and-casts.c b/validation/bitwise-all-bits-and-casts.c
index 01c8d84fcd67..ae0be1269ec4 100644
--- a/validation/bitwise-all-bits-and-casts.c
+++ b/validation/bitwise-all-bits-and-casts.c
@@ -1,6 +1,9 @@
+#define __force __attribute__((force))
+
typedef unsigned long long __attribute__((bitwise)) be64;
typedef unsigned int __attribute__((bitwise)) be32;
typedef unsigned short __attribute__((bitwise)) be16;
+typedef signed int __attribute__((bitwise)) sbe32;
static be32 test_all_bits(void)
{
@@ -11,9 +14,11 @@ static be32 test_all_bits(void)
be32 e = +0;
be32 f = -0;
be32 g = (be32)0;
+ be32 h = (__force be32)0;
be32 i = (be32)~0;
+ be32 j = (__force be32)~0;
- return a | b | c | d | e | f | g | i;
+ return a | b | c | d | e | f | g | h | i | j;
}
static be64 test_all_bits_64(void)
@@ -22,18 +27,22 @@ static be64 test_all_bits_64(void)
be64 b = ~0ULL;
be64 c = -1;
be64 d = (be64)0;
+ be64 e = (__force be64)0;
be64 f = (be64)~0;
+ be64 g = (__force be64)~0;
- return a | b | c | d | f;
+ return a | b | c | d | e | f | g;
}
static be16 test_cross_cast_zero(void)
{
be16 k = (be32)0;
+ be16 l = (__force be32)0;
be16 m = (be32)~0;
+ be16 n = (__force be32)~0;
be16 o = (unsigned short)~0;
- return k | m | o;
+ return k | l | m | n | o;
}
static int test_ordered_compare(be32 x, be16 y)
@@ -54,7 +63,38 @@ static int test_ordered_compare(be32 x, be16 y)
return res;
}
+static void test_bad_narrow_and_signed(sbe32 sx)
+{
+ be64 bad_u32 = ~0U;
+ be32 bad_u16 = (unsigned short)~0;
+ be32 bad_c16 = (be16)~0;
+ be32 bad_f16 = (__force be16)~0;
+ int bad_ord = (sx > 0);
+
+ (void)bad_u32;
+ (void)bad_u16;
+ (void)bad_c16;
+ (void)bad_f16;
+ (void)bad_ord;
+}
+
/*
* check-name: bitwise-all-bits-and-casts
* check-command: sparse -Wbitwise $file
+ *
+ * check-error-start
+bitwise-all-bits-and-casts.c:68:24: warning: incorrect type in initializer (different base types)
+bitwise-all-bits-and-casts.c:68:24: expected restricted be64 [usertype] bad_u32
+bitwise-all-bits-and-casts.c:68:24: got unsigned int
+bitwise-all-bits-and-casts.c:69:25: warning: incorrect type in initializer (different base types)
+bitwise-all-bits-and-casts.c:69:25: expected restricted be32 [usertype] bad_u16
+bitwise-all-bits-and-casts.c:69:25: got unsigned short
+bitwise-all-bits-and-casts.c:70:25: warning: incorrect type in initializer (different base types)
+bitwise-all-bits-and-casts.c:70:25: expected restricted be32 [usertype] bad_c16
+bitwise-all-bits-and-casts.c:70:25: got restricted be16 [usertype]
+bitwise-all-bits-and-casts.c:71:25: warning: incorrect type in initializer (different base types)
+bitwise-all-bits-and-casts.c:71:25: expected restricted be32 [usertype] bad_f16
+bitwise-all-bits-and-casts.c:71:25: got restricted be16 [usertype]
+bitwise-all-bits-and-casts.c:72:24: warning: restricted sbe32 degrades to integer
+ * check-error-end
*/
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 ` Bart Van Assche [this message]
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-38-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