* [PATCH v2 1/2] kconfig: add prop_err function to simplify property error handling
2026-10-14 13:40 [PATCH v2 0/2] kconfig: error on reverse range Julian Braha
@ 2026-10-14 13:40 ` Julian Braha
2026-10-14 13:40 ` [PATCH v2 2/2] kconfig: error on reverse range Julian Braha
1 sibling, 0 replies; 3+ messages in thread
From: Julian Braha @ 2026-10-14 13:40 UTC (permalink / raw)
To: nathan, nsc
Cc: n.schier, grahamr, rdunlap, nico, linux-kbuild, linux-kernel,
Julian Braha
As suggested by Nicolas while reviewing another Kconfig property error [1],
we can add a prop_err() function to simplify the tracking and display of
Kconfig property errors.
Note that the formatting of the warning printing is changed slightly
(adding a space) to better match the formatting used by gcc. This causes
a change to the expected test output for the existing warnings that call
prop_warn() and menu_warn().
Link: https://lore.kernel.org/all/20260917-proficient-swift-of-masquerade-0ff7ce@l-nschier-aarch64/ [1]
Assisted-by: LLM
Suggested-by: Nicolas Schier <n.schier@fritz.com>
Signed-off-by: Julian Braha <julianbraha@gmail.com>
---
Changes since v1:
- adjust warning and error printing to match gcc (Nicolas)
Link to v1:
https://lore.kernel.org/linux-kbuild/20260922163749.2031594-1-julianbraha@gmail.com/
---
| 27 ++++++++++++-------
.../tests/err_transitional/expected_stderr | 2 +-
2 files changed, 18 insertions(+), 11 deletions(-)
--git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index bda3e2650216..db5ba57125c5 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -43,7 +43,7 @@ void menu_warn(const struct menu *menu, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d:warning: ", menu->filename, menu->lineno);
+ fprintf(stderr, "%s:%d: warning: ", menu->filename, menu->lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -53,7 +53,17 @@ static void prop_warn(const struct property *prop, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d:warning: ", prop->filename, prop->lineno);
+ fprintf(stderr, "%s:%d: warning: ", prop->filename, prop->lineno);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
+
+static void prop_err(const struct property *prop, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(stderr, "%s:%d: error: ", prop->filename, prop->lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -246,18 +256,15 @@ static int menu_validate_number(struct symbol *sym, struct symbol *sym2,
if (sym2->type != S_UNKNOWN ||
!sym_string_valid(sym, sym2->name)) {
- fprintf(stderr, "%s:%d: error: '%s' is an invalid value for '%s'\n",
- prop->filename, prop->lineno, sym2->name,
- sym_type_name(sym->type));
+ prop_err(prop, "'%s' is an invalid value for '%s'",
+ sym2->name, sym_type_name(sym->type));
return 1;
}
if (!sym_string_check_bounds(sym, sym2->name)) {
- fprintf(stderr,
- "%s:%d: error: %s constant '%s' is outside the 64-bit %s bounds\n",
- prop->filename, prop->lineno, sym_type_name(sym->type),
- sym2->name, sym->type == S_INT ? "signed" : "unsigned");
-
+ prop_err(prop, "%s constant '%s' is outside the 64-bit %s bounds",
+ sym_type_name(sym->type), sym2->name,
+ sym->type == S_INT ? "signed" : "unsigned");
return 1;
}
diff --git a/scripts/kconfig/tests/err_transitional/expected_stderr b/scripts/kconfig/tests/err_transitional/expected_stderr
index b52db4f680f4..ba317850c043 100644
--- a/scripts/kconfig/tests/err_transitional/expected_stderr
+++ b/scripts/kconfig/tests/err_transitional/expected_stderr
@@ -1,4 +1,4 @@
-Kconfig:46:warning: config symbol defined without type
+Kconfig:46: warning: config symbol defined without type
Kconfig:7: error: transitional symbols can only have help sections
Kconfig:14: error: transitional symbols can only have help sections
Kconfig:21: error: transitional symbols can only have help sections
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2 2/2] kconfig: error on reverse range
2026-10-14 13:40 [PATCH v2 0/2] kconfig: error on reverse range Julian Braha
2026-10-14 13:40 ` [PATCH v2 1/2] kconfig: add prop_err function to simplify property error handling Julian Braha
@ 2026-10-14 13:40 ` Julian Braha
1 sibling, 0 replies; 3+ messages in thread
From: Julian Braha @ 2026-10-14 13:40 UTC (permalink / raw)
To: nathan, nsc
Cc: n.schier, grahamr, rdunlap, nico, linux-kbuild, linux-kernel,
Julian Braha
As discussed on kconfirm v4 [1], it was decided to move checks directly
into the kconfig interpreter once there are no findings from kconfirm.
This "reverse range" currently has no findings across the tree, so let's
add the check.
Currently, if a reverse range is attempted, such as:
config EXAMPLE
int "Reverse range example"
range 2 1
then the value of the option defaults to its "lower" limit of 2. If the
option is visible in the frontend, then the user gets trapped in the value
selection interface, since there is no value that is actually valid for
the user to set.
Note that this only checks ranges that use constant values. Statically
checking ranges using symbols would require SAT solving, or similar.
In the future, the code should be refactored to store range values as
numerics so we can avoid calling strtoll() and strtoull() multiple times.
Link: https://lore.kernel.org/all/20260904220559.GB2787252@ax162/ [1]
Assisted-by: LLM
Signed-off-by: Julian Braha <julianbraha@gmail.com>
---
Changes since v1:
- fix typo in commit message: where -> there (Nicolas)
- handle case with multiple (conditional) ranges (sashiko)
Link to v1:
https://lore.kernel.org/linux-kbuild/20260922163749.2031594-1-julianbraha@gmail.com/
---
| 22 +++-
.../tests/err_num_reverse_range/Kconfig | 111 ++++++++++++++++++
.../tests/err_num_reverse_range/__init__.py | 8 ++
.../err_num_reverse_range/expected_stderr | 11 ++
4 files changed, 148 insertions(+), 4 deletions(-)
create mode 100644 scripts/kconfig/tests/err_num_reverse_range/Kconfig
create mode 100644 scripts/kconfig/tests/err_num_reverse_range/__init__.py
create mode 100644 scripts/kconfig/tests/err_num_reverse_range/expected_stderr
--git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index db5ba57125c5..1a3ad09a92d2 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -274,9 +274,9 @@ static int menu_validate_number(struct symbol *sym, struct symbol *sym2,
static int sym_check_prop(struct symbol *sym)
{
struct property *prop;
- struct symbol *sym2;
+ struct symbol *sym2, *lower, *upper;
char *use;
- int errors = 0;
+ int errors = 0, numeric_errors;
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
@@ -325,8 +325,22 @@ static int sym_check_prop(struct symbol *sym)
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
- errors += menu_validate_number(sym, prop->expr->left.sym, prop);
- errors += menu_validate_number(sym, prop->expr->right.sym, prop);
+ lower = prop->expr->left.sym;
+ upper = prop->expr->right.sym;
+ numeric_errors = menu_validate_number(sym, lower, prop);
+ numeric_errors += menu_validate_number(sym, upper, prop);
+ errors += numeric_errors;
+ if (numeric_errors || lower->type != S_UNKNOWN || upper->type != S_UNKNOWN)
+ break;
+
+ if ((sym->type == S_INT &&
+ strtoll(lower->name, NULL, 10) > strtoll(upper->name, NULL, 10)) ||
+ (sym->type == S_HEX &&
+ strtoull(lower->name, NULL, 16) > strtoull(upper->name, NULL, 16))) {
+ prop_err(prop, "range lower limit '%s' is greater than upper limit '%s'",
+ lower->name, upper->name);
+ errors++;
+ }
break;
default:
;
diff --git a/scripts/kconfig/tests/err_num_reverse_range/Kconfig b/scripts/kconfig/tests/err_num_reverse_range/Kconfig
new file mode 100644
index 000000000000..c55091aca274
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_reverse_range/Kconfig
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: GPL-2.0
+# Check constant range bounds.
+
+config INT_ORDERED
+ int
+ range -10 10
+
+config INT_EQUAL
+ int
+ range 5 5
+
+config HEX_ORDERED
+ hex
+ range 0x7fffffffffffffff 0xffffffffffffffff
+
+config HEX_EQUAL
+ hex
+ range 0xffffffffffffffff 0xffffffffffffffff
+
+# Skip ranges with symbolic bounds.
+
+config INT_LOWER
+ int
+
+config INT_UPPER
+ int
+
+config INT_SYMBOL_LOWER
+ int
+ range INT_LOWER 0
+
+config INT_SYMBOL_UPPER
+ int
+ range 0 INT_UPPER
+
+config INT_SYMBOL_BOTH
+ int
+ range INT_LOWER INT_UPPER
+
+config HEX_LOWER
+ hex
+
+config HEX_UPPER
+ hex
+
+config HEX_SYMBOL_LOWER
+ hex
+ range HEX_LOWER 0x0
+
+config HEX_SYMBOL_UPPER
+ hex
+ range 0x0 HEX_UPPER
+
+config HEX_SYMBOL_BOTH
+ hex
+ range HEX_LOWER HEX_UPPER
+
+# Reject reversed constant bounds.
+
+config INT_REVERSED
+ int
+ range 10 2
+
+config INT_REVERSED_NEGATIVE
+ int
+ range -1 -10
+
+config INT_REVERSED_SIGNED
+ int
+ range 1 -1
+
+config INT_REVERSED_QUOTED
+ int
+ range "8" "2"
+
+config HEX_REVERSED
+ hex
+ range 0x10 0xf
+
+config HEX_REVERSED_HIGH
+ hex
+ range 0xffffffffffffffff 0x8000000000000000
+
+config HEX_REVERSED_UNPREFIXED
+ hex
+ range f a
+
+# Check each conditional range independently.
+
+config RANGE_CONDITION
+ bool
+
+config INT_REVERSED_FIRST
+ int
+ range 10 2 if RANGE_CONDITION
+ range -10 10 if !RANGE_CONDITION
+
+config INT_REVERSED_SECOND
+ int
+ range -10 10 if RANGE_CONDITION
+ range 10 2 if !RANGE_CONDITION
+
+config HEX_REVERSED_FIRST
+ hex
+ range 0x10 0xf if RANGE_CONDITION
+ range 0x0 0x10 if !RANGE_CONDITION
+
+config HEX_REVERSED_SECOND
+ hex
+ range 0x0 0x10 if RANGE_CONDITION
+ range 0x10 0xf if !RANGE_CONDITION
diff --git a/scripts/kconfig/tests/err_num_reverse_range/__init__.py b/scripts/kconfig/tests/err_num_reverse_range/__init__.py
new file mode 100644
index 000000000000..4a7219bbe49e
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_reverse_range/__init__.py
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Reject constant range bounds when the lower bound is greater than the upper.
+"""
+
+def test(conf):
+ assert conf.olddefconfig() == 1
+ assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/err_num_reverse_range/expected_stderr b/scripts/kconfig/tests/err_num_reverse_range/expected_stderr
new file mode 100644
index 000000000000..8742f3f46469
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_reverse_range/expected_stderr
@@ -0,0 +1,11 @@
+Kconfig:62: error: range lower limit '10' is greater than upper limit '2'
+Kconfig:66: error: range lower limit '-1' is greater than upper limit '-10'
+Kconfig:70: error: range lower limit '1' is greater than upper limit '-1'
+Kconfig:74: error: range lower limit '8' is greater than upper limit '2'
+Kconfig:78: error: range lower limit '0x10' is greater than upper limit '0xf'
+Kconfig:82: error: range lower limit '0xffffffffffffffff' is greater than upper limit '0x8000000000000000'
+Kconfig:86: error: range lower limit 'f' is greater than upper limit 'a'
+Kconfig:95: error: range lower limit '10' is greater than upper limit '2'
+Kconfig:101: error: range lower limit '10' is greater than upper limit '2'
+Kconfig:105: error: range lower limit '0x10' is greater than upper limit '0xf'
+Kconfig:111: error: range lower limit '0x10' is greater than upper limit '0xf'
--
2.55.0
^ permalink raw reply [flat|nested] 3+ messages in thread