aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2020-02-10 17:20:38 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-02-10 22:52:42 +0100
commit7e4a5b6fded1ff9b09da41900eb01a9f6749064b (patch)
treeeb27cdc8e86f894d976da174de4df09e598be4a7
parent75757784c819c798709576bac8ce208e90ff1d1f (diff)
downloadsparse-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.c4
-rw-r--r--test-dissect.c2
2 files changed, 4 insertions, 2 deletions
diff --git a/dissect.c b/dissect.c
index 20456b2c..d9ca1422 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 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)