[PATCH 4/4] sparse/dissect: sanitize the de-anonymization of SYM_ENUMs
Oleg Nesterov <[email protected]> Sun, 4 Jan 2026 16:22:08 +0100
| Newsgroups | org.kernel.vger.linux-sparse |
|---|---|
| Message-ID | <[email protected]> |
examine_sym_node() tries to de-anonymize enums just like structs,
and sometimes it makes sense:
$ ~/tmp/sparse/test-dissect - <<<'enum { X } x;'
1:6 def E :x unsigned int
1:8 def e :x.X unsigned int enum :x
1:12 def v x unsigned int enum :x
But it doesn't make sense to de-anonymize enum types using the name
of its enum_member.
Test-case:
$ cat -n ENUM_3.c
1 enum { A, B };
2 typeof(B) x = A;
$ ./test-dissect ENUM_3.c
1:6 def E :B unsigned int
1:8 def e :B.A unsigned int enum :B
1:11 def e :B.B unsigned int enum :B
2:8 --- e :B.B unsigned int enum :B
2:11 def v x int
2:11 -w- v x int
2:15 x -r- e :B.A unsigned int enum :B
With this patch:
$ ./test-dissect ENUM_3.c
1:8 def e A unsigned int enum <noident>
1:11 def e B unsigned int enum <noident>
2:8 --- e B unsigned int enum <noident>
2:11 def v x int
2:11 -w- v x int
2:15 x -r- e A unsigned int enum <noident>
Signed-off-by: Oleg Nesterov <[email protected]>
---
dissect.c | 5 +++--
test-dissect.c | 13 +++++++------
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/dissect.c b/dissect.c
index d36986dd..a0fda09c 100644
--- a/dissect.c
+++ b/dissect.c
@@ -245,10 +245,11 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent)
if (toplevel(base->scope))
dissect_ctx = NULL;
- if (base->ident || deanon(base, name, parent))
+ if (base->ident || (!node->enum_member &&
+ deanon(base, name, parent)))
reporter->r_symdef(base);
- if (base->ident)
+ if (base->ident || base->type == SYM_ENUM)
parent = base;
DO_LIST(base->symbol_list, mem,
examine_sym_node(mem, parent);
diff --git a/test-dissect.c b/test-dissect.c
index e2b8ec9d..0a7ee98c 100644
--- a/test-dissect.c
+++ b/test-dissect.c
@@ -88,19 +88,20 @@ err:
static void r_member(unsigned mode, struct position *pos, struct symbol *sym, struct symbol *mem)
{
struct ident *ni, *si, *mi;
- int mk;
+ int mk, ms = 32;
ni = built_in_ident("?");
- si = sym->ident ?: ni;
/* mem == NULL means entire struct accessed */
- mi = mem ? (mem->ident ?: ni) : built_in_ident("*");
mk = mem ? mem->kind : 'm';
+ mi = mem ? (mem->ident ?: ni) : built_in_ident("*");
+ si = sym->ident ?: (mk == 'e' ? NULL : ni);
print_usage(pos, sym, mode, mk);
- printf("%.*s.%-*.*s %s\n",
- si->len, si->name,
- 32-1 - si->len, mi->len, mi->name,
+ if (si)
+ ms -= printf("%.*s.", si->len, si->name);
+
+ printf("%-*.*s %s\n", ms, mi->len, mi->name,
show_typename(mem ? mem->ctype.base_type : sym));
if (sym->ident && sym->kind != 's' && sym->kind != 'E')
--
2.52.0