* [PATCH] kconfig: warn on dead default
@ 2026-06-06 14:00 Julian Braha
2026-06-06 14:23 ` Sam Ravnborg
2026-07-07 5:31 ` Nathan Chancellor
0 siblings, 2 replies; 7+ messages in thread
From: Julian Braha @ 2026-06-06 14:00 UTC (permalink / raw)
To: nathan, nsc
Cc: rdunlap, masahiroy, grahamr, nico, linux-kernel, linux-kbuild,
Julian Braha
The dead default check was originally introduced with kconfirm:
https://lore.kernel.org/all/6ec4df6d-1445-48ca-8f54-1d1a83c4716d@gmail.com/
While I'm still working on that tool, it's not yet ready for inclusion
into the tree. I am currently waiting for common distro packagers to
package the parsing library before submitting the next RFC iteration.
However, the dead default check is more impactful than the other checks:
all 4 dead defaults that were detected should not have been dead and could
cause misconfiguration bugs. But fortunately, these were just for kunit
tests. The 3 patches to fix them have all since been merged:
commit aef656a0e6c0 ("powerpc: fix dead default for GUEST_STATE_BUFFER_TEST")
commit 30cc5e2ad826 ("s390/Kconfig: Cleanup defaults for selftests")
commit df75430515c3 ("drm: fix dead default for DRM_TTM_KUNIT_TEST")
We can actually check for dead defaults while evaluating Kconfig, which
should be even more effective at preventing future instances than keeping
it in a static checker.
Note that this patch will only trigger a warning when the default values
are different, in other words, pure duplicate defaults won't cause a
warning, as they are simply redundant.
Signed-off-by: Julian Braha <julianbraha@gmail.com>
---
| 22 +++++++++-
.../kconfig/tests/warn_dead_default/Kconfig | 40 +++++++++++++++++++
.../tests/warn_dead_default/__init__.py | 8 ++++
.../tests/warn_dead_default/expected_stderr | 4 ++
4 files changed, 73 insertions(+), 1 deletion(-)
create mode 100644 scripts/kconfig/tests/warn_dead_default/Kconfig
create mode 100644 scripts/kconfig/tests/warn_dead_default/__init__.py
create mode 100644 scripts/kconfig/tests/warn_dead_default/expected_stderr
--git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index b2d8d4e11e07..8c280292f9cd 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -242,13 +242,33 @@ static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
static void sym_check_prop(struct symbol *sym)
{
- struct property *prop;
+ struct property *prev, *prop;
struct symbol *sym2;
char *use;
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
case P_DEFAULT:
+ for_all_defaults(sym, prev) {
+ if (prev == prop)
+ break;
+ if (expr_is_yes(prev->visible.expr)) {
+ if (!expr_eq(prev->expr, prop->expr))
+ prop_warn(prop,
+ "default for '%s' is unreachable: earlier default at %s:%d is unconditional",
+ sym->name ? sym->name : "<choice>",
+ prev->filename, prev->lineno);
+ break;
+ }
+ if (expr_eq(prev->visible.expr, prop->visible.expr)) {
+ if (!expr_eq(prev->expr, prop->expr))
+ prop_warn(prop,
+ "default for '%s' has the same condition as the earlier default at %s:%d",
+ sym->name ? sym->name : "<choice>",
+ prev->filename, prev->lineno);
+ break;
+ }
+ }
if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
prop->expr->type != E_SYMBOL)
prop_warn(prop,
diff --git a/scripts/kconfig/tests/warn_dead_default/Kconfig b/scripts/kconfig/tests/warn_dead_default/Kconfig
new file mode 100644
index 000000000000..adf421d73dbd
--- /dev/null
+++ b/scripts/kconfig/tests/warn_dead_default/Kconfig
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config A
+ bool
+
+config B
+ bool
+
+config UNCONDITIONAL
+ int
+ default 1
+ default 2
+
+config CONDITIONAL
+ int
+ default 1 if A
+ default 2 if A
+ default 3 if B
+
+config CONDITIONAL_COMMUTATIVE
+ int
+ default 1 if A && B
+ default 2 if B && A
+
+config CONTROL
+ int
+ default 1 if A
+ default 2 if B
+ default 3
+
+choice
+ prompt "test choice"
+ default C
+ default D
+
+ config C
+ bool "C"
+ config D
+ bool "D"
+endchoice
diff --git a/scripts/kconfig/tests/warn_dead_default/__init__.py b/scripts/kconfig/tests/warn_dead_default/__init__.py
new file mode 100644
index 000000000000..911b30ce19fe
--- /dev/null
+++ b/scripts/kconfig/tests/warn_dead_default/__init__.py
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Test detection of dead defaults (different defaults that can never be active).
+"""
+
+def test(conf):
+ assert conf.olddefconfig() == 0
+ assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/warn_dead_default/expected_stderr b/scripts/kconfig/tests/warn_dead_default/expected_stderr
new file mode 100644
index 000000000000..baa20bf33910
--- /dev/null
+++ b/scripts/kconfig/tests/warn_dead_default/expected_stderr
@@ -0,0 +1,4 @@
+Kconfig:12:warning: default for 'UNCONDITIONAL' is unreachable: earlier default at Kconfig:11 is unconditional
+Kconfig:17:warning: default for 'CONDITIONAL' has the same condition as the earlier default at Kconfig:16
+Kconfig:23:warning: default for 'CONDITIONAL_COMMUTATIVE' has the same condition as the earlier default at Kconfig:22
+Kconfig:34:warning: default for '<choice>' is unreachable: earlier default at Kconfig:33 is unconditional
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] kconfig: warn on dead default
2026-06-06 14:00 [PATCH] kconfig: warn on dead default Julian Braha
@ 2026-06-06 14:23 ` Sam Ravnborg
2026-06-06 15:01 ` Julian Braha
2026-07-07 5:31 ` Nathan Chancellor
1 sibling, 1 reply; 7+ messages in thread
From: Sam Ravnborg @ 2026-06-06 14:23 UTC (permalink / raw)
To: Julian Braha
Cc: nathan, nsc, rdunlap, masahiroy, grahamr, nico, linux-kernel,
linux-kbuild
Hi Julian.
On Sat, Jun 06, 2026 at 03:00:08PM +0100, Julian Braha wrote:
> The dead default check was originally introduced with kconfirm:
> https://lore.kernel.org/all/6ec4df6d-1445-48ca-8f54-1d1a83c4716d@gmail.com/
>
> While I'm still working on that tool, it's not yet ready for inclusion
> into the tree. I am currently waiting for common distro packagers to
> package the parsing library before submitting the next RFC iteration.
>
> However, the dead default check is more impactful than the other checks:
> all 4 dead defaults that were detected should not have been dead and could
> cause misconfiguration bugs. But fortunately, these were just for kunit
> tests. The 3 patches to fix them have all since been merged:
> commit aef656a0e6c0 ("powerpc: fix dead default for GUEST_STATE_BUFFER_TEST")
> commit 30cc5e2ad826 ("s390/Kconfig: Cleanup defaults for selftests")
> commit df75430515c3 ("drm: fix dead default for DRM_TTM_KUNIT_TEST")
>
> We can actually check for dead defaults while evaluating Kconfig, which
> should be even more effective at preventing future instances than keeping
> it in a static checker.
>
> Note that this patch will only trigger a warning when the default values
> are different, in other words, pure duplicate defaults won't cause a
> warning, as they are simply redundant.
A drive-by comment below.
>
> Signed-off-by: Julian Braha <julianbraha@gmail.com>
> ---
> scripts/kconfig/menu.c | 22 +++++++++-
> .../kconfig/tests/warn_dead_default/Kconfig | 40 +++++++++++++++++++
> .../tests/warn_dead_default/__init__.py | 8 ++++
> .../tests/warn_dead_default/expected_stderr | 4 ++
> 4 files changed, 73 insertions(+), 1 deletion(-)
> create mode 100644 scripts/kconfig/tests/warn_dead_default/Kconfig
> create mode 100644 scripts/kconfig/tests/warn_dead_default/__init__.py
> create mode 100644 scripts/kconfig/tests/warn_dead_default/expected_stderr
>
> diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
> index b2d8d4e11e07..8c280292f9cd 100644
> --- a/scripts/kconfig/menu.c
> +++ b/scripts/kconfig/menu.c
> @@ -242,13 +242,33 @@ static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
>
> static void sym_check_prop(struct symbol *sym)
> {
> - struct property *prop;
> + struct property *prev, *prop;
> struct symbol *sym2;
> char *use;
>
> for (prop = sym->prop; prop; prop = prop->next) {
This part iterates through all properties of sym.
> switch (prop->type) {
> case P_DEFAULT:
> + for_all_defaults(sym, prev) {
And this part iterates through all properties of sym and will match only
P_DEFAULT.
I looks redundant with the two loops were we for the latter knows it is
a P_DEFAULT.
> + if (prev == prop)
> + break;
> + if (expr_is_yes(prev->visible.expr)) {
> + if (!expr_eq(prev->expr, prop->expr))
> + prop_warn(prop,
> + "default for '%s' is unreachable: earlier default at %s:%d is unconditional",
> + sym->name ? sym->name : "<choice>",
> + prev->filename, prev->lineno);
> + break;
> + }
> + if (expr_eq(prev->visible.expr, prop->visible.expr)) {
> + if (!expr_eq(prev->expr, prop->expr))
> + prop_warn(prop,
> + "default for '%s' has the same condition as the earlier default at %s:%d",
> + sym->name ? sym->name : "<choice>",
> + prev->filename, prev->lineno);
> + break;
> + }
> + }
> if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
> prop->expr->type != E_SYMBOL)
> prop_warn(prop,
Sam
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] kconfig: warn on dead default
2026-06-06 14:23 ` Sam Ravnborg
@ 2026-06-06 15:01 ` Julian Braha
2026-06-06 17:36 ` Sam Ravnborg
0 siblings, 1 reply; 7+ messages in thread
From: Julian Braha @ 2026-06-06 15:01 UTC (permalink / raw)
To: Sam Ravnborg
Cc: nathan, nsc, rdunlap, masahiroy, grahamr, nico, linux-kernel,
linux-kbuild
On 6/6/26 15:23, Sam Ravnborg wrote:
> I looks redundant with the two loops were we for the latter knows it is
> a P_DEFAULT.
Hi Sam,
It may look redundant, but we do need to check each default we encounter
in the
```
for (prop = sym->prop; prop; prop = prop->next) {
```
loop against the previous defaults to know if we've encountered a
duplicate default condition.
I guess the other approach would be to copy each default as we encounter
them into a hashtable and check against that, instead? Let me know if
you have another, preferred approach.
- Julian Braha
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] kconfig: warn on dead default
2026-06-06 15:01 ` Julian Braha
@ 2026-06-06 17:36 ` Sam Ravnborg
0 siblings, 0 replies; 7+ messages in thread
From: Sam Ravnborg @ 2026-06-06 17:36 UTC (permalink / raw)
To: Julian Braha
Cc: nathan, nsc, rdunlap, masahiroy, grahamr, nico, linux-kernel,
linux-kbuild
Hi Julian.
On Sat, Jun 06, 2026 at 04:01:34PM +0100, Julian Braha wrote:
> On 6/6/26 15:23, Sam Ravnborg wrote:
> > I looks redundant with the two loops were we for the latter knows it is
> > a P_DEFAULT.
>
> Hi Sam,
>
> It may look redundant, but we do need to check each default we encounter
> in the
> ```
> for (prop = sym->prop; prop; prop = prop->next) {
> ```
> loop against the previous defaults to know if we've encountered a
> duplicate default condition.
>
> I guess the other approach would be to copy each default as we encounter
> them into a hashtable and check against that, instead? Let me know if
> you have another, preferred approach.
It was just a drive-by comment, keep it as simple as possible.
Sam
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] kconfig: warn on dead default
2026-06-06 14:00 [PATCH] kconfig: warn on dead default Julian Braha
2026-06-06 14:23 ` Sam Ravnborg
@ 2026-07-07 5:31 ` Nathan Chancellor
2026-07-07 6:06 ` Nicolas Schier
2026-07-07 8:32 ` Julian Braha
1 sibling, 2 replies; 7+ messages in thread
From: Nathan Chancellor @ 2026-07-07 5:31 UTC (permalink / raw)
To: Julian Braha
Cc: nsc, rdunlap, masahiroy, grahamr, nico, linux-kernel,
linux-kbuild
Hi Julian,
On Sat, Jun 06, 2026 at 03:00:08PM +0100, Julian Braha wrote:
> The dead default check was originally introduced with kconfirm:
> https://lore.kernel.org/all/6ec4df6d-1445-48ca-8f54-1d1a83c4716d@gmail.com/
>
> While I'm still working on that tool, it's not yet ready for inclusion
> into the tree. I am currently waiting for common distro packagers to
> package the parsing library before submitting the next RFC iteration.
>
> However, the dead default check is more impactful than the other checks:
> all 4 dead defaults that were detected should not have been dead and could
> cause misconfiguration bugs. But fortunately, these were just for kunit
> tests. The 3 patches to fix them have all since been merged:
> commit aef656a0e6c0 ("powerpc: fix dead default for GUEST_STATE_BUFFER_TEST")
> commit 30cc5e2ad826 ("s390/Kconfig: Cleanup defaults for selftests")
> commit df75430515c3 ("drm: fix dead default for DRM_TTM_KUNIT_TEST")
>
> We can actually check for dead defaults while evaluating Kconfig, which
> should be even more effective at preventing future instances than keeping
> it in a static checker.
>
> Note that this patch will only trigger a warning when the default values
> are different, in other words, pure duplicate defaults won't cause a
> warning, as they are simply redundant.
>
> Signed-off-by: Julian Braha <julianbraha@gmail.com>
Nicolas pushed this into -next, where it fires several times for me. I
have not looked at these closely yet, I just wanted to get the report
out so that more eyes could be on it.
ARCH=powerpc allmodconfig:
arch/powerpc/platforms/Kconfig.cputype:269:warning: default for 'TUNE_CPU' has the same condition as the earlier default at arch/powerpc/platforms/Kconfig.cputype:268
arch/powerpc/platforms/Kconfig.cputype:270:warning: default for 'TUNE_CPU' has the same condition as the earlier default at arch/powerpc/platforms/Kconfig.cputype:268
lib/Kconfig.debug:1083:warning: default for 'PANIC_TIMEOUT' is unreachable: earlier default at arch/powerpc/Kconfig:350 is unconditional
arch/Kconfig:1194:warning: default for 'PGTABLE_LEVELS' is unreachable: earlier default at arch/powerpc/Kconfig:482 is unconditional
ARCH=s390 allmodconfig:
arch/Kconfig:1194:warning: default for 'PGTABLE_LEVELS' is unreachable: earlier default at arch/s390/Kconfig:295 is unconditional
lib/Kconfig:372:warning: default for 'HAS_IOMEM' is unreachable: earlier default at arch/s390/Kconfig:760 is unconditional
When building with clang-23, which supports '-fms-anonymous-struct':
init/Kconfig:978:warning: default for 'CC_MS_EXTENSIONS' is unreachable: earlier default at init/Kconfig:977 is unconditional
I think the init/Kconfig and arch/powerpc/platforms/Kconfig.cputype ones
are intentional due to how cc-option works but I know those might be
hard to silence because they are already evaluated by this stage if I
understand correctly? Not sure about the other ones (apologies if they
are already known or have fixes).
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] kconfig: warn on dead default
2026-07-07 5:31 ` Nathan Chancellor
@ 2026-07-07 6:06 ` Nicolas Schier
2026-07-07 8:32 ` Julian Braha
1 sibling, 0 replies; 7+ messages in thread
From: Nicolas Schier @ 2026-07-07 6:06 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Julian Braha, rdunlap, masahiroy, grahamr, nico, linux-kernel,
linux-kbuild
On Mon, Jul 06, 2026 at 10:31:43PM -0700, Nathan Chancellor wrote:
> Hi Julian,
>
> On Sat, Jun 06, 2026 at 03:00:08PM +0100, Julian Braha wrote:
> > The dead default check was originally introduced with kconfirm:
> > https://lore.kernel.org/all/6ec4df6d-1445-48ca-8f54-1d1a83c4716d@gmail.com/
> >
> > While I'm still working on that tool, it's not yet ready for inclusion
> > into the tree. I am currently waiting for common distro packagers to
> > package the parsing library before submitting the next RFC iteration.
> >
> > However, the dead default check is more impactful than the other checks:
> > all 4 dead defaults that were detected should not have been dead and could
> > cause misconfiguration bugs. But fortunately, these were just for kunit
> > tests. The 3 patches to fix them have all since been merged:
> > commit aef656a0e6c0 ("powerpc: fix dead default for GUEST_STATE_BUFFER_TEST")
> > commit 30cc5e2ad826 ("s390/Kconfig: Cleanup defaults for selftests")
> > commit df75430515c3 ("drm: fix dead default for DRM_TTM_KUNIT_TEST")
> >
> > We can actually check for dead defaults while evaluating Kconfig, which
> > should be even more effective at preventing future instances than keeping
> > it in a static checker.
> >
> > Note that this patch will only trigger a warning when the default values
> > are different, in other words, pure duplicate defaults won't cause a
> > warning, as they are simply redundant.
> >
> > Signed-off-by: Julian Braha <julianbraha@gmail.com>
>
> Nicolas pushed this into -next, where it fires several times for me. I
> have not looked at these closely yet, I just wanted to get the report
> out so that more eyes could be on it.
>
> ARCH=powerpc allmodconfig:
>
> arch/powerpc/platforms/Kconfig.cputype:269:warning: default for 'TUNE_CPU' has the same condition as the earlier default at arch/powerpc/platforms/Kconfig.cputype:268
> arch/powerpc/platforms/Kconfig.cputype:270:warning: default for 'TUNE_CPU' has the same condition as the earlier default at arch/powerpc/platforms/Kconfig.cputype:268
> lib/Kconfig.debug:1083:warning: default for 'PANIC_TIMEOUT' is unreachable: earlier default at arch/powerpc/Kconfig:350 is unconditional
> arch/Kconfig:1194:warning: default for 'PGTABLE_LEVELS' is unreachable: earlier default at arch/powerpc/Kconfig:482 is unconditional
>
> ARCH=s390 allmodconfig:
>
> arch/Kconfig:1194:warning: default for 'PGTABLE_LEVELS' is unreachable: earlier default at arch/s390/Kconfig:295 is unconditional
> lib/Kconfig:372:warning: default for 'HAS_IOMEM' is unreachable: earlier default at arch/s390/Kconfig:760 is unconditional
>
> When building with clang-23, which supports '-fms-anonymous-struct':
>
> init/Kconfig:978:warning: default for 'CC_MS_EXTENSIONS' is unreachable: earlier default at init/Kconfig:977 is unconditional
>
> I think the init/Kconfig and arch/powerpc/platforms/Kconfig.cputype ones
> are intentional due to how cc-option works but I know those might be
> hard to silence because they are already evaluated by this stage if I
> understand correctly? Not sure about the other ones (apologies if they
> are already known or have fixes).
thanks for the report. I'll remove the patch from kbuild-for-next
again as there is not obvious immediate solution visible to me right
now.
--
Nicolas
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] kconfig: warn on dead default
2026-07-07 5:31 ` Nathan Chancellor
2026-07-07 6:06 ` Nicolas Schier
@ 2026-07-07 8:32 ` Julian Braha
1 sibling, 0 replies; 7+ messages in thread
From: Julian Braha @ 2026-07-07 8:32 UTC (permalink / raw)
To: Nathan Chancellor, nsc
Cc: rdunlap, masahiroy, grahamr, nico, linux-kernel, linux-kbuild
Hi Nathan,
On 7/7/26 06:31, Nathan Chancellor wrote:
> Nicolas pushed this into -next, where it fires several times for me. I
> have not looked at these closely yet, I just wanted to get the report
> out so that more eyes could be on it.
Thank you for sharing, I've taken a close look.
> ARCH=powerpc allmodconfig:
>
> arch/powerpc/platforms/Kconfig.cputype:269:warning: default for 'TUNE_CPU' has the same condition as the earlier default at arch/powerpc/platforms/Kconfig.cputype:268
> arch/powerpc/platforms/Kconfig.cputype:270:warning: default for 'TUNE_CPU' has the same condition as the earlier default at arch/powerpc/platforms/Kconfig.cputype:268
> lib/Kconfig.debug:1083:warning: default for 'PANIC_TIMEOUT' is unreachable: earlier default at arch/powerpc/Kconfig:350 is unconditional
> arch/Kconfig:1194:warning: default for 'PGTABLE_LEVELS' is unreachable: earlier default at arch/powerpc/Kconfig:482 is unconditional
>
> ARCH=s390 allmodconfig:
>
> arch/Kconfig:1194:warning: default for 'PGTABLE_LEVELS' is unreachable: earlier default at arch/s390/Kconfig:295 is unconditional
> lib/Kconfig:372:warning: default for 'HAS_IOMEM' is unreachable: earlier default at arch/s390/Kconfig:760 is unconditional
It seems to me that all of these instances are probably intended by the
architectures to override the global default.
Personally, I find this redefine-and-override style confusing as it
requires the reader to think about the order of imports in kconfig. I'll
throw them in my kconfig cleanup pile, and see what the relevant
maintainers think of my version.
> When building with clang-23, which supports '-fms-anonymous-struct':
>
> init/Kconfig:978:warning: default for 'CC_MS_EXTENSIONS' is unreachable: earlier default at init/Kconfig:977 is unconditional
>
> I think the init/Kconfig and arch/powerpc/platforms/Kconfig.cputype ones
> are intentional due to how cc-option works but I know those might be
> hard to silence because they are already evaluated by this stage if I
> understand correctly? Not sure about the other ones (apologies if they
> are already known or have fixes).
Yeah, let's leave these alone.
Best not to merge this. Thank you all for taking a look.
- Julian Braha
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-07 8:32 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-06 14:00 [PATCH] kconfig: warn on dead default Julian Braha
2026-06-06 14:23 ` Sam Ravnborg
2026-06-06 15:01 ` Julian Braha
2026-06-06 17:36 ` Sam Ravnborg
2026-07-07 5:31 ` Nathan Chancellor
2026-07-07 6:06 ` Nicolas Schier
2026-07-07 8:32 ` Julian Braha
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox