diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-07-29 16:50:44 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-07-29 18:13:44 +0200 |
commit | 4932334a3205c913e61587518539a44a0941a2ef (patch) | |
tree | 3e00e53970287deb482c68c04078fec7456970d4 | |
parent | ee4aea9a9b097bc0b99346a697d8a09e7f373af6 (diff) | |
download | sparse-4932334a3205c913e61587518539a44a0941a2ef.tar.gz |
dissect: use struct symbol::visited/inspected instead of ::examined/evaluated
The dissect client uses struct symbol's fields 'examined' & 'evaluated'
to avoid reprocessing the same symbols. But these fields are used
internally by sparse for type examination & evaluation and despite
dissect not doing these operations explicitly, they can be done
implicitly (for example to handle static assertions or when the
value of a constant expression is needed) inside __sparse().
If this happens, dissect.c:examine_sym_node() will be a no-op because
node->examined will already be set and node->kind would be 0.
Same can happen with node->evaluated.
So, add a new field to struct symbol: 'inspected' and use it, as
well as the existing 'visited', instead of 'evaluated' & 'examined'.
This way, dissect will control its recursion via flags reserved for
backends and thus never set by sparse internals.
Note: when used on the kernel, this patch avoids a lot of warnings:
"warning: r_member bad sym type=7 kind=0"
"warning: r_member bad mem->kind = 0"
and creates substantially more normal output.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
-rw-r--r-- | dissect.c | 8 | ||||
-rw-r--r-- | symbol.h | 5 |
2 files changed, 7 insertions, 6 deletions
@@ -204,9 +204,9 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent) struct ident *name = node->ident; struct symbol *base, *dctx; - if (node->examined) + if (node->visited) return; - node->examined = 1; + node->visited = 1; node->kind = 'v'; while ((base = node->ctype.base_type) != NULL) @@ -228,9 +228,9 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent) break; case SYM_STRUCT: case SYM_UNION: //case SYM_ENUM: - if (base->evaluated) + if (base->inspected) return; - base->evaluated = 1; + base->inspected = 1; base->kind = 's'; if (!base->symbol_list) @@ -206,9 +206,10 @@ struct symbol { union /* backend */ { struct basic_block *bb_target; /* label */ void *aux; /* Auxiliary info, e.g. backend information */ - struct { /* sparse ctags */ - char kind; + struct { + char kind; /* used by ctags & dissect */ unsigned char visited:1; + unsigned char inspected:1; }; }; pseudo_t pseudo; |