diff options
author | Oleg Nesterov <oleg@redhat.com> | 2020-02-10 17:20:38 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-02-10 22:52:42 +0100 |
commit | 7e4a5b6fded1ff9b09da41900eb01a9f6749064b (patch) | |
tree | eb27cdc8e86f894d976da174de4df09e598be4a7 | |
parent | 75757784c819c798709576bac8ce208e90ff1d1f (diff) | |
download | sparse-7e4a5b6fded1ff9b09da41900eb01a9f6749064b.tar.gz |
dissect: enforce sym->kind='f' when it looks like a function call
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>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | dissect.c | 4 | ||||
-rw-r--r-- | test-dissect.c | 2 |
2 files changed, 4 insertions, 2 deletions
@@ -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 81cc89d1..ece22536 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) |