kconfig: promote invalid numeric reference from warning to error

The Kconfig interpreter already warns if a numeric option attempts to use
a non-numeric option (bool, tristate, or string) to set its value (for
example, with a 'default' or 'range').

Since there is nowhere in the tree that attempts this, we can safely
promote this check from warning to error.

Assisted-by: LLM
Signed-off-by: Julian Braha <julianbraha@gmail.com>
Reviewed-by: Nicolas Schier <n.schier@fritz.com>
Link: https://patch.msgid.link/20260915211508.291790-2-julianbraha@gmail.com
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
This commit is contained in:
Julian Braha 2026-09-15 22:15:04 +01:00 committed by Nathan Chancellor
parent a2a402bd5e
commit 95fde4bcc0
No known key found for this signature in database
GPG Key ID: 1D6B269171C01A96
6 changed files with 126 additions and 15 deletions

View File

@ -89,7 +89,7 @@ struct property *menu_add_prompt(enum prop_type type, const char *prompt,
struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
void menu_finalize(void);
int menu_finalize(void);
void menu_set_type(int type);
extern struct menu rootmenu;

View File

@ -240,11 +240,12 @@ static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
(sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
}
static void sym_check_prop(struct symbol *sym)
static int sym_check_prop(struct symbol *sym)
{
struct property *prop;
struct symbol *sym2;
char *use;
int errors = 0;
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
@ -258,10 +259,13 @@ static void sym_check_prop(struct symbol *sym)
break;
sym2 = prop_get_symbol(prop);
if (sym->type == S_HEX || sym->type == S_INT) {
if (!menu_validate_number(sym, sym2))
prop_warn(prop,
"'%s': number is invalid",
sym->name);
if (!menu_validate_number(sym, sym2)) {
fprintf(stderr,
"%s:%d: error: '%s': number is invalid\n",
prop->filename, prop->lineno,
sym->name);
errors++;
}
}
if (sym_is_choice(sym)) {
struct menu *choice = sym_get_choice_menu(sym2);
@ -293,21 +297,28 @@ static void sym_check_prop(struct symbol *sym)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
if (!menu_validate_number(sym, prop->expr->left.sym) ||
!menu_validate_number(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid");
!menu_validate_number(sym, prop->expr->right.sym)) {
fprintf(stderr,
"%s:%d: error: range is invalid\n",
prop->filename, prop->lineno);
errors++;
}
break;
default:
;
}
}
return errors;
}
static void _menu_finalize(struct menu *parent, bool inside_choice)
static int _menu_finalize(struct menu *parent, bool inside_choice)
{
struct menu *menu, *last_menu;
struct symbol *sym;
struct property *prop;
struct expr *basedep, *dep, *dep2;
int errors = 0;
sym = parent->sym;
if (parent->list) {
@ -393,7 +404,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
* moving on
*/
for (menu = parent->list; menu; menu = menu->next)
_menu_finalize(menu, sym && sym_is_choice(sym));
errors += _menu_finalize(menu, sym && sym_is_choice(sym));
} else if (!inside_choice && sym) {
/*
* Automatic submenu creation. If sym is a symbol and A, B, C,
@ -461,7 +472,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
}
/* Superset, put in submenu */
next:
_menu_finalize(menu, false);
errors += _menu_finalize(menu, false);
menu->parent = parent;
last_menu = menu;
}
@ -519,14 +530,16 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
menu_warn(parent, "config symbol defined without type");
/* Check properties connected to this symbol */
sym_check_prop(sym);
errors += sym_check_prop(sym);
sym->flags |= SYMBOL_WARNED;
}
return errors;
}
void menu_finalize(void)
int menu_finalize(void)
{
_menu_finalize(&rootmenu, false);
return _menu_finalize(&rootmenu, false);
}
bool menu_has_prompt(const struct menu *menu)

View File

@ -587,7 +587,7 @@ void conf_parse(const char *name)
menu_add_prompt(P_MENU, "Main menu", NULL);
}
menu_finalize();
yynerrs += menu_finalize();
menu_for_each_entry(menu) {
struct menu *child;

View File

@ -0,0 +1,75 @@
# SPDX-License-Identifier: GPL-2.0
# Test non-numeric symbol references from numeric symbols
config BOOL_SOURCE
bool
config TRISTATE_SOURCE
tristate
config STRING_SOURCE
string
# Invalid int defaults
config INT_DEFAULT_BOOL
int
default BOOL_SOURCE
config INT_DEFAULT_TRISTATE
int
default TRISTATE_SOURCE
config INT_DEFAULT_STRING
int
default STRING_SOURCE
# Invalid hex defaults
config HEX_DEFAULT_BOOL
hex
default BOOL_SOURCE
config HEX_DEFAULT_TRISTATE
hex
default TRISTATE_SOURCE
config HEX_DEFAULT_STRING
hex
default STRING_SOURCE
# Invalid int ranges
config INT_RANGE_BOOL
int
range BOOL_SOURCE 1
config INT_RANGE_TRISTATE
int
range TRISTATE_SOURCE 1
config INT_RANGE_STRING
int
range STRING_SOURCE 1
config INT_RANGE_MULTIPLE
int
range BOOL_SOURCE TRISTATE_SOURCE
# Invalid hex ranges
config HEX_RANGE_BOOL
hex
range BOOL_SOURCE 0x1
config HEX_RANGE_TRISTATE
hex
range TRISTATE_SOURCE 0x1
config HEX_RANGE_STRING
hex
range STRING_SOURCE 0x1
config HEX_RANGE_MULTIPLE
hex
range BOOL_SOURCE TRISTATE_SOURCE

View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
"""
Reject nonnumeric symbol references from int and hex properties.
"""
def test(conf):
assert conf.olddefconfig() == 1
assert conf.stderr_matches('expected_stderr')

View File

@ -0,0 +1,14 @@
Kconfig:17: error: 'INT_DEFAULT_BOOL': number is invalid
Kconfig:21: error: 'INT_DEFAULT_TRISTATE': number is invalid
Kconfig:25: error: 'INT_DEFAULT_STRING': number is invalid
Kconfig:31: error: 'HEX_DEFAULT_BOOL': number is invalid
Kconfig:35: error: 'HEX_DEFAULT_TRISTATE': number is invalid
Kconfig:39: error: 'HEX_DEFAULT_STRING': number is invalid
Kconfig:45: error: range is invalid
Kconfig:49: error: range is invalid
Kconfig:53: error: range is invalid
Kconfig:57: error: range is invalid
Kconfig:63: error: range is invalid
Kconfig:67: error: range is invalid
Kconfig:71: error: range is invalid
Kconfig:75: error: range is invalid