* [PATCH] kconfig: add kconfig-sym-check static checker
@ 2026-05-13 21:03 Andrew Jones
2026-05-13 21:44 ` Andy Shevchenko
2026-05-13 23:31 ` Randy Dunlap
0 siblings, 2 replies; 3+ messages in thread
From: Andrew Jones @ 2026-05-13 21:03 UTC (permalink / raw)
To: linux-kbuild, linux-kernel; +Cc: nathan, nsc, andriy.shevchenko
Add 'make kconfig-sym-check', a static checker that finds Kconfig
symbols referenced in expressions (select, depends on, default, etc.)
but never defined via config/menuconfig anywhere in the tree. New
dangling symbols are reported as errors (exit 1) unless they are
listed in an exclusion file, e.g.
KCONFIG_SYM_CHECK_EXCLUDES=sym-check-excludes make kconfig-sym-check
The checker also warns about uppercase N/Y/M used as tristate literal
values following the same logic as checkpatch.
This new static checker is the script used for [1] with a few
improvements to avoid some false positives.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216748 [1]
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
Makefile | 7 ++-
scripts/kconfig/kconfig-sym-check.pl | 93 ++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 1 deletion(-)
create mode 100755 scripts/kconfig/kconfig-sym-check.pl
diff --git a/Makefile b/Makefile
index fc2d94aafb45..5a0a9f9d6169 100644
--- a/Makefile
+++ b/Makefile
@@ -293,6 +293,7 @@ version_h := include/generated/uapi/linux/version.h
clean-targets := %clean mrproper cleandocs
no-dot-config-targets := $(clean-targets) \
cscope gtags TAGS tags help% %docs check% coccicheck \
+ kconfig-sym-check \
$(version_h) headers headers_% archheaders archscripts \
%asm-generic kernelversion %src-pkg dt_binding_check \
outputmakefile rustavailable rustfmt rustfmtcheck \
@@ -1806,6 +1807,7 @@ help:
@echo ' includecheck - Check for duplicate included header files'
@echo ' headerdep - Detect inclusion cycles in headers'
@echo ' coccicheck - Check with Coccinelle'
+ @echo ' kconfig-sym-check - Check for dangling Kconfig symbol references'
@echo ' clang-analyzer - Check with clang static analyzer'
@echo ' clang-tidy - Check with clang-tidy'
@echo ''
@@ -2227,7 +2229,7 @@ endif
# Scripts to check various things for consistency
# ---------------------------------------------------------------------------
-PHONY += includecheck versioncheck coccicheck
+PHONY += includecheck versioncheck coccicheck kconfig-sym-check
includecheck:
find $(srctree)/* $(RCS_FIND_IGNORE) \
@@ -2242,6 +2244,9 @@ versioncheck:
coccicheck:
$(Q)$(BASH) $(srctree)/scripts/$@
+kconfig-sym-check:
+ $(Q)cd $(srctree) && $(PERL) scripts/kconfig/kconfig-sym-check.pl $(KCONFIG_SYM_CHECK_EXCLUDES)
+
PHONY += checkstack kernelrelease kernelversion image_name
# UML needs a little special treatment here. It wants to use the host
diff --git a/scripts/kconfig/kconfig-sym-check.pl b/scripts/kconfig/kconfig-sym-check.pl
new file mode 100755
index 000000000000..a6907e585962
--- /dev/null
+++ b/scripts/kconfig/kconfig-sym-check.pl
@@ -0,0 +1,93 @@
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
+
+use warnings;
+use strict;
+
+my $kconfig_sym_check_excludes = undef;
+$kconfig_sym_check_excludes = $ARGV[0] if (defined $ARGV[0]);
+
+my @files = `git ls-files '*Kconfig*'`;
+my %configs = ();
+my %refs = ();
+
+foreach my $file (<@files>) {
+ open F, $file or die "Cannot open $file: $!";
+
+ my $help = 0;
+ my $help_level;
+ my $level;
+
+ while (<F>) {
+ chomp;
+
+ next if /^\s*$/;
+ next if /^\s*#/;
+
+ /^(\s*)/;
+ $level = length $1;
+
+ if ($help && $level < $help_level) {
+ $help = 0;
+ }
+
+ next if ($help);
+
+ if (/^\s*(help|\-\-\-help\-\-\-)$/) {
+ $help = 1;
+ $_ = <F>;
+ /^(\s*)/;
+ $help_level = length $1;
+ next;
+ }
+
+ if (/^\s*(config|menuconfig)\s+([a-zA-Z0-9_]+)\s*(#.*)?$/) {
+ $configs{$2}++;
+ next;
+ }
+
+ my $comment_idx = index $_, "#";
+ if ($comment_idx != -1) {
+ $_ = substr $_, 0, $comment_idx;
+ }
+
+ if (/^\s*(default|def_bool|def_tristate|select|depends\s+on|imply|visible\s+if|range|if)\s+(.+)\s*$/) {
+ my $s = $2;
+ $s =~ s/\$\(.*\)//g;
+ $s =~ s/'[^']*'//g;
+ $s =~ s/"[^"]*"//g;
+ $s =~ s/%%[^%]*%%//g;
+ my @syms = split /[^a-zA-Z0-9_]+/, $s;
+ map {
+ $refs{$_}++ if (/[a-zA-Z]/ && $_ ne "if" && $_ ne "y" && $_ ne "n" && $_ ne "m" && !(/^0[xX]/ && !/[g-wy-zG-WY-Z]/));
+ } @syms
+ }
+ }
+
+ close F;
+}
+
+my %known_syms = ();
+if (defined $kconfig_sym_check_excludes) {
+ my $file = $kconfig_sym_check_excludes;
+ open F, $file or die "Cannot open $file: $!";
+ while (<F>) {
+ chomp;
+ next if /^\s*$/;
+ next if /^\s*#/;
+ $known_syms{$1}++ if (/^\s*([a-zA-Z0-9_]+)\s*(#.*)?$/);
+ }
+}
+
+my $ret = 0;
+foreach my $k (sort keys %refs) {
+ next if (exists $configs{$k} || exists $known_syms{$k});
+
+ print "$k";
+ print " - warning: '$k' is probably not what you want; Kconfig tristate literals are always lowercase ('n', 'y', 'm')" if ($k eq "N" || $k eq "Y" || $k eq "M");
+ print "\n";
+
+ $ret = 1;
+}
+
+exit $ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] kconfig: add kconfig-sym-check static checker
2026-05-13 21:03 [PATCH] kconfig: add kconfig-sym-check static checker Andrew Jones
@ 2026-05-13 21:44 ` Andy Shevchenko
2026-05-13 23:31 ` Randy Dunlap
1 sibling, 0 replies; 3+ messages in thread
From: Andy Shevchenko @ 2026-05-13 21:44 UTC (permalink / raw)
To: Andrew Jones, Randy Dunlap; +Cc: linux-kbuild, linux-kernel, nathan, nsc
+Cc: Randy: FYI.
On Wed, May 13, 2026 at 04:03:29PM -0500, Andrew Jones wrote:
> Add 'make kconfig-sym-check', a static checker that finds Kconfig
> symbols referenced in expressions (select, depends on, default, etc.)
> but never defined via config/menuconfig anywhere in the tree. New
> dangling symbols are reported as errors (exit 1) unless they are
> listed in an exclusion file, e.g.
>
> KCONFIG_SYM_CHECK_EXCLUDES=sym-check-excludes make kconfig-sym-check
>
> The checker also warns about uppercase N/Y/M used as tristate literal
> values following the same logic as checkpatch.
>
> This new static checker is the script used for [1] with a few
> improvements to avoid some false positives.
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] kconfig: add kconfig-sym-check static checker
2026-05-13 21:03 [PATCH] kconfig: add kconfig-sym-check static checker Andrew Jones
2026-05-13 21:44 ` Andy Shevchenko
@ 2026-05-13 23:31 ` Randy Dunlap
1 sibling, 0 replies; 3+ messages in thread
From: Randy Dunlap @ 2026-05-13 23:31 UTC (permalink / raw)
To: Andrew Jones, linux-kbuild, linux-kernel; +Cc: nathan, nsc, andriy.shevchenko
On 5/13/26 2:03 PM, Andrew Jones wrote:
> Add 'make kconfig-sym-check', a static checker that finds Kconfig
> symbols referenced in expressions (select, depends on, default, etc.)
> but never defined via config/menuconfig anywhere in the tree. New
> dangling symbols are reported as errors (exit 1) unless they are
> listed in an exclusion file, e.g.
>
> KCONFIG_SYM_CHECK_EXCLUDES=sym-check-excludes make kconfig-sym-check
>
> The checker also warns about uppercase N/Y/M used as tristate literal
> values following the same logic as checkpatch.
>
> This new static checker is the script used for [1] with a few
> improvements to avoid some false positives.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=216748 [1]
> Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
> ---
> Makefile | 7 ++-
> scripts/kconfig/kconfig-sym-check.pl | 93 ++++++++++++++++++++++++++++
> 2 files changed, 99 insertions(+), 1 deletion(-)
> create mode 100755 scripts/kconfig/kconfig-sym-check.pl
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Thanks.
--
~Randy
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-13 23:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 21:03 [PATCH] kconfig: add kconfig-sym-check static checker Andrew Jones
2026-05-13 21:44 ` Andy Shevchenko
2026-05-13 23:31 ` Randy Dunlap
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox