* [PATCH 0/4] sparse/dissect: fix missing usage reports for unnamed members of named types
@ 2026-06-05 14:56 Oleg Nesterov
2026-06-05 14:56 ` [PATCH 1/4] sparse/dissect: introduce find_report_member() Oleg Nesterov
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Oleg Nesterov @ 2026-06-05 14:56 UTC (permalink / raw)
To: Chris Li, Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
Hello,
With the recent change, dissect.c correctly reports the definitions of the
promoted members, but it still doesn't report the usages of the underlying
members.
The only functional change is 4/4.
Oleg.
---
dissect.c | 70 +++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 50 insertions(+), 20 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] sparse/dissect: introduce find_report_member()
2026-06-05 14:56 [PATCH 0/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
@ 2026-06-05 14:56 ` Oleg Nesterov
2026-06-05 14:56 ` [PATCH 2/4] sparse/dissect: fold lookup_member() into find_report_member() Oleg Nesterov
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Oleg Nesterov @ 2026-06-05 14:56 UTC (permalink / raw)
To: Chris Li, Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
No functional changes, preparation for the next patches.
Add the new helper, find_report_member(), which simply does
lookup_member() + report_member(), and update the current users of
the same pattern to use it.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
dissect.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/dissect.c b/dissect.c
index 04ec89ca..6b5cb0ef 100644
--- a/dissect.c
+++ b/dissect.c
@@ -331,6 +331,13 @@ static struct symbol *lookup_member(struct symbol *type, struct ident *name, int
return mem;
}
+static struct symbol *find_report_member(usage_t mode, struct position *pos,
+ struct symbol *type, struct ident *name,
+ int *p_addr)
+{
+ return report_member(mode, pos, type, lookup_member(type, name, p_addr));
+}
+
static struct expression *peek_preop(struct expression *expr, int op)
{
do {
@@ -474,8 +481,8 @@ again:
p_mode = U_R_VAL;
p_type = do_expression(p_mode, expr->deref);
- ret = report_member(mode, &expr->m_pos, p_type,
- lookup_member(p_type, expr->member, NULL));
+ ret = find_report_member(mode, &expr->m_pos,
+ p_type, expr->member, NULL);
}
break; case EXPR_OFFSETOF: {
@@ -483,8 +490,8 @@ again:
do {
if (expr->op == '.') {
- in = report_member(U_VOID, &expr->pos, in,
- lookup_member(in, expr->ident, NULL));
+ in = find_report_member(U_VOID, &expr->pos,
+ in, expr->ident, NULL);
} else {
do_expression(U_R_VAL, expr->index);
in = in->ctype.base_type;
@@ -609,8 +616,8 @@ static struct symbol *do_initializer(struct symbol *type, struct expression *exp
m_type = type;
while (m_expr->type == EXPR_IDENTIFIER) {
- m_type = report_member(U_W_VAL, &m_expr->pos, m_type,
- lookup_member(m_type, m_expr->expr_ident, m_atop));
+ m_type = find_report_member(U_W_VAL, &m_expr->pos,
+ m_type, m_expr->expr_ident, m_atop);
m_expr = m_expr->ident_expression;
m_atop = NULL;
@@ -621,8 +628,8 @@ static struct symbol *do_initializer(struct symbol *type, struct expression *exp
}
if (m_atop) {
- m_type = report_member(U_W_VAL, &m_expr->pos, m_type,
- lookup_member(m_type, NULL, m_atop));
+ m_type = find_report_member(U_W_VAL, &m_expr->pos,
+ m_type, NULL, m_atop);
}
if (m_expr->type != EXPR_INITIALIZER)
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/4] sparse/dissect: fold lookup_member() into find_report_member()
2026-06-05 14:56 [PATCH 0/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
2026-06-05 14:56 ` [PATCH 1/4] sparse/dissect: introduce find_report_member() Oleg Nesterov
@ 2026-06-05 14:56 ` Oleg Nesterov
2026-06-05 14:56 ` [PATCH 3/4] sparse/dissect: introduce struct lookup_args for lookup_member() Oleg Nesterov
2026-06-05 14:56 ` [PATCH 4/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
3 siblings, 0 replies; 5+ messages in thread
From: Oleg Nesterov @ 2026-06-05 14:56 UTC (permalink / raw)
To: Chris Li, Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
After the previous change lookup_member() has a single caller. Fold it
into find_report_member() and rename __lookup_member().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
dissect.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/dissect.c b/dissect.c
index 6b5cb0ef..c790807e 100644
--- a/dissect.c
+++ b/dissect.c
@@ -283,7 +283,7 @@ static struct symbol *base_type(struct symbol *sym)
?: &bad_ctype;
}
-static struct symbol *__lookup_member(struct symbol *type, struct ident *name, int *p_addr)
+static struct symbol *lookup_member(struct symbol *type, struct ident *name, int *p_addr)
{
struct symbol *node;
int addr = 0;
@@ -294,7 +294,7 @@ static struct symbol *__lookup_member(struct symbol *type, struct ident *name, i
return node;
}
else if (node->ident == NULL) {
- node = __lookup_member(node->ctype.base_type, name, NULL);
+ node = lookup_member(node->ctype.base_type, name, NULL);
if (node)
goto found;
}
@@ -310,9 +310,11 @@ found:
return NULL;
}
-static struct symbol *lookup_member(struct symbol *type, struct ident *name, int *addr)
+static struct symbol *find_report_member(usage_t mode, struct position *pos,
+ struct symbol *type, struct ident *name,
+ int *p_addr)
{
- struct symbol *mem = __lookup_member(type, name, addr);
+ struct symbol *mem = lookup_member(type, name, p_addr);
if (!mem) {
static struct symbol bad_member = {
@@ -328,14 +330,7 @@ static struct symbol *lookup_member(struct symbol *type, struct ident *name, int
mem->ident = name;
}
- return mem;
-}
-
-static struct symbol *find_report_member(usage_t mode, struct position *pos,
- struct symbol *type, struct ident *name,
- int *p_addr)
-{
- return report_member(mode, pos, type, lookup_member(type, name, p_addr));
+ return report_member(mode, pos, type, mem);
}
static struct expression *peek_preop(struct expression *expr, int op)
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] sparse/dissect: introduce struct lookup_args for lookup_member()
2026-06-05 14:56 [PATCH 0/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
2026-06-05 14:56 ` [PATCH 1/4] sparse/dissect: introduce find_report_member() Oleg Nesterov
2026-06-05 14:56 ` [PATCH 2/4] sparse/dissect: fold lookup_member() into find_report_member() Oleg Nesterov
@ 2026-06-05 14:56 ` Oleg Nesterov
2026-06-05 14:56 ` [PATCH 4/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
3 siblings, 0 replies; 5+ messages in thread
From: Oleg Nesterov @ 2026-06-05 14:56 UTC (permalink / raw)
To: Chris Li, Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
No functional changes, preparation for the next patch.
The new "struct lookup_args" bundles the current name/p_addr arguments
of lookup_member().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
dissect.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/dissect.c b/dissect.c
index c790807e..3da9e3a2 100644
--- a/dissect.c
+++ b/dissect.c
@@ -283,25 +283,29 @@ static struct symbol *base_type(struct symbol *sym)
?: &bad_ctype;
}
-static struct symbol *lookup_member(struct symbol *type, struct ident *name, int *p_addr)
+struct lookup_args {
+ struct ident *name;
+ int *p_addr;
+};
+
+static struct symbol *lookup_member(struct symbol *type, struct lookup_args *la)
{
struct symbol *node;
int addr = 0;
FOR_EACH_PTR(type->symbol_list, node)
- if (!name) {
- if (addr == *p_addr)
+ if (!la->name) {
+ if (*la->p_addr == addr)
return node;
}
else if (node->ident == NULL) {
- node = lookup_member(node->ctype.base_type, name, NULL);
+ node = lookup_member(node->ctype.base_type, la);
if (node)
goto found;
}
- else if (node->ident == name) {
-found:
- if (p_addr)
- *p_addr = addr;
+ else if (node->ident == la->name) {
+found: if (la->p_addr)
+ *la->p_addr = addr;
return node;
}
addr++;
@@ -314,7 +318,11 @@ static struct symbol *find_report_member(usage_t mode, struct position *pos,
struct symbol *type, struct ident *name,
int *p_addr)
{
- struct symbol *mem = lookup_member(type, name, p_addr);
+ struct lookup_args la = {
+ .name = name,
+ .p_addr = p_addr,
+ };
+ struct symbol *mem = lookup_member(type, &la);
if (!mem) {
static struct symbol bad_member = {
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/4] sparse/dissect: fix missing usage reports for unnamed members of named types
2026-06-05 14:56 [PATCH 0/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
` (2 preceding siblings ...)
2026-06-05 14:56 ` [PATCH 3/4] sparse/dissect: introduce struct lookup_args for lookup_member() Oleg Nesterov
@ 2026-06-05 14:56 ` Oleg Nesterov
3 siblings, 0 replies; 5+ messages in thread
From: Oleg Nesterov @ 2026-06-05 14:56 UTC (permalink / raw)
To: Chris Li, Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
With the recent change, dissect.c correctly reports the definitions of the
promoted members, but it still doesn't report the usages of the underlying
members.
This means, for example, that
$ semind search -m r ns_tree.ns_id
finds nothing without this change.
Minimal (same) test-case:
union U { int i; };
struct S { union U; } v = { .i = 0 };
Before the patch:
$ test-dissect TEST.c
3:8 def s S
1:7 def s U
1:15 def m U.i int
3:19 def m S.i int
3:23 def v v struct S
3:23 -w- v v struct S
3:30 v -w- m S.i int
The usage of U.i is not reported.
After the patch:
$ test-dissect TEST.c
3:8 def s S
1:7 def s U
1:15 def m U.i int
3:19 def m S.i int
3:23 def v v struct S
3:23 -w- v v struct S
3:30 v -w- m U.i int
3:30 v -w- m S.i int
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
dissect.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/dissect.c b/dissect.c
index 3da9e3a2..2358297b 100644
--- a/dissect.c
+++ b/dissect.c
@@ -286,8 +286,19 @@ static struct symbol *base_type(struct symbol *sym)
struct lookup_args {
struct ident *name;
int *p_addr;
+ struct position pos;
+ struct symbol *stack[8];
+ unsigned int depth;
};
+static inline void lookup_push(struct lookup_args *la, struct symbol *type)
+{
+ if (la->depth == ARRAY_SIZE(la->stack))
+ warning(la->pos, "lookup stack overflow");
+ else
+ la->stack[la->depth++] = type;
+}
+
static struct symbol *lookup_member(struct symbol *type, struct lookup_args *la)
{
struct symbol *node;
@@ -299,9 +310,13 @@ static struct symbol *lookup_member(struct symbol *type, struct lookup_args *la)
return node;
}
else if (node->ident == NULL) {
- node = lookup_member(node->ctype.base_type, la);
- if (node)
+ struct symbol *base = node->ctype.base_type;
+ node = lookup_member(base, la);
+ if (node) {
+ if (type->ident != base->ident)
+ lookup_push(la, base);
goto found;
+ }
}
else if (node->ident == la->name) {
found: if (la->p_addr)
@@ -321,6 +336,8 @@ static struct symbol *find_report_member(usage_t mode, struct position *pos,
struct lookup_args la = {
.name = name,
.p_addr = p_addr,
+ .pos = *pos,
+ .depth = 0,
};
struct symbol *mem = lookup_member(type, &la);
@@ -338,6 +355,9 @@ static struct symbol *find_report_member(usage_t mode, struct position *pos,
mem->ident = name;
}
+ while (la.depth)
+ report_member(mode, pos, la.stack[--la.depth], mem);
+
return report_member(mode, pos, type, mem);
}
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-05 14:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-05 14:56 [PATCH 0/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
2026-06-05 14:56 ` [PATCH 1/4] sparse/dissect: introduce find_report_member() Oleg Nesterov
2026-06-05 14:56 ` [PATCH 2/4] sparse/dissect: fold lookup_member() into find_report_member() Oleg Nesterov
2026-06-05 14:56 ` [PATCH 3/4] sparse/dissect: introduce struct lookup_args for lookup_member() Oleg Nesterov
2026-06-05 14:56 ` [PATCH 4/4] sparse/dissect: fix missing usage reports for unnamed members of named types Oleg Nesterov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox