diff options
author | Oleg Nesterov <oleg@redhat.com> | 2020-02-19 17:29:34 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-02-20 01:41:46 +0100 |
commit | e078774555c66004ab404097bfd58523c2e78f86 (patch) | |
tree | 9ccd44659a843ae7e3b78c7043668a2a8b027664 | |
parent | 9ac20e9e3c06918665aada812b0452d88d835291 (diff) | |
download | sparse-e078774555c66004ab404097bfd58523c2e78f86.tar.gz |
dissect: fix sym_is_local(SYM_STRUCT/UNION/ENUM)
Now that struct_union_enum_specifier() always sets sym->scope we can
simplify sym_is_local(sym) and rely on toplevel() even if sym is type.
Test-case:
// copied from linux kernel
# define __force __attribute__((force))
#define WRITE_ONCE(x, val) \
({ \
union { typeof(x) __val; char __c[1]; } __u = \
{ .__val = (__force typeof(x)) (val) }; \
__write_once_size(&(x), __u.__c, sizeof(x)); \
__u.__val; \
})
void func(int *p)
{
WRITE_ONCE(*p, 0);
}
before this patch the widely used WRITE_ONCE() generates a lot of spam which
can't be filtered out using sym_is_local(),
11:6 def f func void ( ... )
11:11 func def . v p int *
13:9 def s :__u
13:9 --- . v p int *
13:9 def m :__u.__val int
13:9 def m :__u.__c char [1]
13:9 func def . v __u union :__u
13:9 func -w- . v __u union :__u
13:9 func -w- m :__u.__val int
13:9 func --- . v p int *
13:9 func --r f __write_once_size bad type
13:9 func -r- . v p int *
13:9 func -r- . v __u union :__u
13:9 func m-- m :__u.__c char [1]
13:9 func --- . v p int *
13:9 func --- . v __u union :__u
13:9 func --- m :__u.__val int
plus it triggers warning("no context") in test-dissect.c. With this patch
the only "nonlocal" report is __write_once_size() call.
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-- | dissect.h | 3 |
2 files changed, 4 insertions, 3 deletions
@@ -152,7 +152,6 @@ static inline struct symbol *expr_symbol(struct expression *expr) if (!sym) { sym = alloc_symbol(expr->pos, SYM_BAD); bind_symbol(sym, expr->symbol_name, NS_SYMBOL); - sym->ctype.modifiers = MOD_EXTERN | MOD_TOPLEVEL; sym->kind = expr->op ?: 'v'; /* see EXPR_CALL */ } } @@ -238,7 +237,8 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent) return; dctx = dissect_ctx; - dissect_ctx = NULL; + if (toplevel(base->scope)) + dissect_ctx = NULL; if (base->ident || deanon(base, name, parent)) reporter->r_symdef(base); @@ -4,6 +4,7 @@ #include <stdio.h> #include "parse.h" #include "expression.h" +#include "scope.h" #define U_SHIFT 8 @@ -29,7 +30,7 @@ extern struct symbol *dissect_ctx; static inline bool sym_is_local(struct symbol *sym) { - return sym->kind == 'v' && !(sym->ctype.modifiers & MOD_TOPLEVEL); + return !toplevel(sym->scope); } extern void dissect(struct reporter *, struct string_list *); |