* [PATCH 1/2] dissect: set sym->kind for reporter
@ 2020-02-10 16:20 Oleg Nesterov
2020-02-10 16:20 ` [PATCH 2/2] dissect: enforce sym->kind='f' when it looks like a function call Oleg Nesterov
2020-02-10 23:32 ` [PATCH 1/2] dissect: set sym->kind for reporter Luc Van Oostenryck
0 siblings, 2 replies; 3+ messages in thread
From: Oleg Nesterov @ 2020-02-10 16:20 UTC (permalink / raw)
To: Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
Change dissect to report ctags-like kind passed in sym->kind.
Currently only v,f,s and m kinds are possible.
SYM_UNION doesn't differ from SYM_STRUCT and has ->kind = 's'.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
dissect.c | 19 ++++++++++++++-----
test-dissect.c | 34 ++++++++++++++++++++++++++++++----
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/dissect.c b/dissect.c
index 85489a2..20456b2 100644
--- a/dissect.c
+++ b/dissect.c
@@ -123,6 +123,7 @@ static inline struct symbol *no_member(struct ident *name)
{
static struct symbol sym = {
.type = SYM_BAD,
+ .kind = 'm',
};
sym.ctype.base_type = &bad_ctype;
@@ -165,6 +166,7 @@ static inline struct symbol *expr_symbol(struct expression *expr)
sym = alloc_symbol(expr->pos, SYM_BAD);
bind_symbol(sym, expr->symbol_name, NS_SYMBOL);
sym->ctype.modifiers = MOD_EXTERN;
+ sym->kind = 'v';
}
}
@@ -206,20 +208,20 @@ static bool deanon(struct symbol *base, struct ident *node, struct symbol *paren
static void report_memdef(struct symbol *sym, struct symbol *mem)
{
+ mem->kind = 'm';
if (sym && mem->ident)
reporter->r_memdef(sym, mem);
}
static void examine_sym_node(struct symbol *node, struct symbol *parent)
{
+ struct ident *name = node->ident;
struct symbol *base, *dctx;
- struct ident *name;
if (node->examined)
return;
-
node->examined = 1;
- name = node->ident;
+ node->kind = 'v';
while ((base = node->ctype.base_type) != NULL)
switch (base->type) {
@@ -230,16 +232,23 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent)
case SYM_ARRAY:
do_expression(U_R_VAL, base->array_size);
- case SYM_PTR: case SYM_FN:
+ case SYM_PTR:
+ node = base;
+ break;
+
+ case SYM_FN:
+ node->kind = 'f';
node = base;
break;
case SYM_STRUCT: case SYM_UNION: //case SYM_ENUM:
if (base->evaluated)
return;
+ base->evaluated = 1;
+ base->kind = 's';
+
if (!base->symbol_list)
return;
- base->evaluated = 1;
dctx = dissect_ctx;
dissect_ctx = NULL;
diff --git a/test-dissect.c b/test-dissect.c
index d93a2a0..81cc89d 100644
--- a/test-dissect.c
+++ b/test-dissect.c
@@ -32,7 +32,7 @@ static void print_usage(struct position *pos, struct symbol *sym, unsigned mode)
if (dissect_ctx)
ctx = dissect_ctx->ident;
- printf("%4d:%-3d %-16.*s %-5.3s",
+ printf("%4d:%-3d %-16.*s %s ",
pos->line, pos->pos, ctx->len, ctx->name, show_mode(mode));
}
@@ -44,9 +44,30 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)
if (!sym->ident)
sym->ident = built_in_ident("__asm__");
- printf("%-32.*s %s\n",
- sym->ident->len, sym->ident->name,
+ printf("%c %-32.*s %s\n",
+ sym->kind, sym->ident->len, sym->ident->name,
show_typename(sym->ctype.base_type));
+
+ switch (sym->kind) {
+ case 's':
+ if (sym->type == SYM_STRUCT || sym->type == SYM_UNION)
+ break;
+ goto err;
+
+ case 'f':
+ if (sym->ctype.base_type->type != SYM_FN)
+ goto err;
+ case 'v':
+ if (sym->type == SYM_NODE || sym->type == SYM_BAD)
+ break;
+ goto err;
+ default:
+ goto err;
+ }
+
+ return;
+err:
+ warning(*pos, "r_symbol bad sym type=%d kind=%d", sym->type, sym->kind);
}
static void r_member(unsigned mode, struct position *pos, struct symbol *sym, struct symbol *mem)
@@ -59,10 +80,15 @@ static void r_member(unsigned mode, struct position *pos, struct symbol *sym, st
/* mem == NULL means entire struct accessed */
mi = mem ? mem->ident : built_in_ident("*");
- printf("%.*s.%-*.*s %s\n",
+ printf("m %.*s.%-*.*s %s\n",
si->len, si->name,
32-1 - si->len, mi->len, mi->name,
show_typename(mem ? mem->ctype.base_type : sym));
+
+ if (sym->ident && sym->kind != 's')
+ warning(*pos, "r_member bad sym type=%d kind=%d", sym->type, sym->kind);
+ if (mem && mem->kind != 'm')
+ warning(*pos, "r_member bad mem->kind = %d", mem->kind);
}
static void r_symdef(struct symbol *sym)
--
2.5.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] dissect: enforce sym->kind='f' when it looks like a function call
2020-02-10 16:20 [PATCH 1/2] dissect: set sym->kind for reporter Oleg Nesterov
@ 2020-02-10 16:20 ` Oleg Nesterov
2020-02-10 23:32 ` [PATCH 1/2] dissect: set sym->kind for reporter Luc Van Oostenryck
1 sibling, 0 replies; 3+ messages in thread
From: Oleg Nesterov @ 2020-02-10 16:20 UTC (permalink / raw)
To: Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse
A separate change for documentation purposes.
dissect() tries to work even if the parsed code is buggy or incomplete,
thus it makes sense to change expr_symbol() to set kind = 'f' when it
likely looks like a function name.
We can safely abuse EXPR_SYMBOL->op to pass the hint to expr_symbol(),
it must be 0.
Test-case:
void call(void)
{
func();
}
before this patch
1:14 def f call void ( ... )
3:17 call --r v func bad type
after:
1:14 def f call void ( ... )
3:17 call --r f func bad type
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
dissect.c | 4 +++-
test-dissect.c | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dissect.c b/dissect.c
index 20456b2..d9ca142 100644
--- a/dissect.c
+++ b/dissect.c
@@ -166,7 +166,7 @@ static inline struct symbol *expr_symbol(struct expression *expr)
sym = alloc_symbol(expr->pos, SYM_BAD);
bind_symbol(sym, expr->symbol_name, NS_SYMBOL);
sym->ctype.modifiers = MOD_EXTERN;
- sym->kind = 'v';
+ sym->kind = expr->op ?: 'v'; /* see EXPR_CALL */
}
}
@@ -374,6 +374,8 @@ again:
ret = do_expression(mode, expr->cond_false);
break; case EXPR_CALL:
+ if (expr->fn->type == EXPR_SYMBOL)
+ expr->fn->op = 'f'; /* for expr_symbol() */
ret = do_expression(U_R_PTR, expr->fn);
if (is_ptr(ret))
ret = ret->ctype.base_type;
diff --git a/test-dissect.c b/test-dissect.c
index 81cc89d..ece2253 100644
--- a/test-dissect.c
+++ b/test-dissect.c
@@ -55,7 +55,7 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)
goto err;
case 'f':
- if (sym->ctype.base_type->type != SYM_FN)
+ if (sym->type != SYM_BAD && sym->ctype.base_type->type != SYM_FN)
goto err;
case 'v':
if (sym->type == SYM_NODE || sym->type == SYM_BAD)
--
2.5.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/2] dissect: set sym->kind for reporter
2020-02-10 16:20 [PATCH 1/2] dissect: set sym->kind for reporter Oleg Nesterov
2020-02-10 16:20 ` [PATCH 2/2] dissect: enforce sym->kind='f' when it looks like a function call Oleg Nesterov
@ 2020-02-10 23:32 ` Luc Van Oostenryck
1 sibling, 0 replies; 3+ messages in thread
From: Luc Van Oostenryck @ 2020-02-10 23:32 UTC (permalink / raw)
To: Oleg Nesterov; +Cc: Alexey Gladkov, linux-sparse
On Mon, Feb 10, 2020 at 05:20:18PM +0100, Oleg Nesterov wrote:
> Change dissect to report ctags-like kind passed in sym->kind.
> Currently only v,f,s and m kinds are possible.
>
> SYM_UNION doesn't differ from SYM_STRUCT and has ->kind = 's'.
>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Thanks.
Both patches applied and pushed.
-- Luc
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-02-10 23:32 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-02-10 16:20 [PATCH 1/2] dissect: set sym->kind for reporter Oleg Nesterov
2020-02-10 16:20 ` [PATCH 2/2] dissect: enforce sym->kind='f' when it looks like a function call Oleg Nesterov
2020-02-10 23:32 ` [PATCH 1/2] dissect: set sym->kind for reporter Luc Van Oostenryck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).