summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-03 15:48:45 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-12 18:48:49 +0100
commit69fce9f7bc6f81231953b4551e574dd90fc10e45 (patch)
tree4f67af06dc564e8713ca98111b8c9b04b68661b7
parente206ae0348021d4d3c2c7c02f41fb5dbcf14cdb2 (diff)
downloadsparse-69fce9f7bc6f81231953b4551e574dd90fc10e45.tar.gz
as-name: use idents for address spaces
Currently, address space are identified by an number and displayed as '<asn:%d>'. It would be more useful to display a name like the one used in the code: '__user', '__iomem', .... Prepare this by using an identifier instead of the AS number. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--evaluate.c45
-rw-r--r--parse.c12
-rw-r--r--show-parse.c27
-rw-r--r--symbol.c4
-rw-r--r--symbol.h24
5 files changed, 70 insertions, 42 deletions
diff --git a/evaluate.c b/evaluate.c
index 05ea7640..0ad6da88 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -45,6 +45,8 @@
struct symbol *current_fn;
+struct ident bad_address_space = { .len = 6, .name = "bad AS", };
+
static struct symbol *degenerate(struct expression *expr);
static struct symbol *evaluate_symbol(struct symbol *sym);
@@ -208,14 +210,14 @@ static int same_cast_type(struct symbol *orig, struct symbol *new)
orig->bit_offset == new->bit_offset;
}
-static struct symbol *base_type(struct symbol *node, unsigned long *modp, unsigned long *asp)
+static struct symbol *base_type(struct symbol *node, unsigned long *modp, struct ident **asp)
{
- unsigned long mod, as;
+ unsigned long mod = 0;
+ struct ident *as = NULL;
- mod = 0; as = 0;
while (node) {
mod |= node->ctype.modifiers;
- as |= node->ctype.as;
+ combine_address_space(&as, node->ctype.as);
if (node->type == SYM_NODE) {
node = node->ctype.base_type;
continue;
@@ -230,7 +232,8 @@ static struct symbol *base_type(struct symbol *node, unsigned long *modp, unsign
static int is_same_type(struct expression *expr, struct symbol *new)
{
struct symbol *old = expr->ctype;
- unsigned long oldmod, newmod, oldas, newas;
+ unsigned long oldmod, newmod;
+ struct ident *oldas, *newas;
old = base_type(old, &oldmod, &oldas);
new = base_type(new, &newmod, &newas);
@@ -660,7 +663,7 @@ static void examine_fn_arguments(struct symbol *fn);
const char *type_difference(struct ctype *c1, struct ctype *c2,
unsigned long mod1, unsigned long mod2)
{
- unsigned long as1 = c1->as, as2 = c2->as;
+ struct ident *as1 = c1->as, *as2 = c2->as;
struct symbol *t1 = c1->base_type;
struct symbol *t2 = c2->base_type;
int move1 = 1, move2 = 1;
@@ -678,7 +681,7 @@ const char *type_difference(struct ctype *c1, struct ctype *c2,
if (move1) {
if (t1 && t1->type != SYM_PTR) {
mod1 |= t1->ctype.modifiers;
- as1 |= t1->ctype.as;
+ combine_address_space(&as1, t1->ctype.as);
}
move1 = 0;
}
@@ -686,7 +689,7 @@ const char *type_difference(struct ctype *c1, struct ctype *c2,
if (move2) {
if (t2 && t2->type != SYM_PTR) {
mod2 |= t2->ctype.modifiers;
- as2 |= t2->ctype.as;
+ combine_address_space(&as2, t2->ctype.as);
}
move2 = 0;
}
@@ -1609,11 +1612,11 @@ static void examine_fn_arguments(struct symbol *fn)
ptr->ctype = arg->ctype;
else
ptr->ctype.base_type = arg;
- ptr->ctype.as |= s->ctype.as;
+ combine_address_space(&ptr->ctype.as, s->ctype.as);
ptr->ctype.modifiers |= s->ctype.modifiers & MOD_PTRINHERIT;
s->ctype.base_type = ptr;
- s->ctype.as = 0;
+ s->ctype.as = NULL;
s->ctype.modifiers &= ~MOD_PTRINHERIT;
s->bit_size = 0;
s->examined = 0;
@@ -1627,7 +1630,7 @@ static void examine_fn_arguments(struct symbol *fn)
} END_FOR_EACH_PTR(s);
}
-static struct symbol *convert_to_as_mod(struct symbol *sym, int as, int mod)
+static struct symbol *convert_to_as_mod(struct symbol *sym, struct ident *as, int mod)
{
/* Take the modifiers of the pointer, and apply them to the member */
mod |= sym->ctype.modifiers;
@@ -1659,12 +1662,12 @@ static struct symbol *create_pointer(struct expression *expr, struct symbol *sym
sym->ctype.modifiers &= ~MOD_REGISTER;
}
if (sym->type == SYM_NODE) {
- ptr->ctype.as |= sym->ctype.as;
+ combine_address_space(&ptr->ctype.as, sym->ctype.as);
ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT;
sym = sym->ctype.base_type;
}
if (degenerate && sym->type == SYM_ARRAY) {
- ptr->ctype.as |= sym->ctype.as;
+ combine_address_space(&ptr->ctype.as, sym->ctype.as);
ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT;
sym = sym->ctype.base_type;
}
@@ -2051,8 +2054,8 @@ static struct symbol *evaluate_member_dereference(struct expression *expr)
struct symbol *ctype, *member;
struct expression *deref = expr->deref, *add;
struct ident *ident = expr->member;
+ struct ident *address_space;
unsigned int mod;
- int address_space;
if (!evaluate_expression(deref))
return NULL;
@@ -2067,7 +2070,7 @@ static struct symbol *evaluate_member_dereference(struct expression *expr)
mod = ctype->ctype.modifiers;
if (ctype->type == SYM_NODE) {
ctype = ctype->ctype.base_type;
- address_space |= ctype->ctype.as;
+ combine_address_space(&address_space, ctype->ctype.as);
mod |= ctype->ctype.modifiers;
}
if (!ctype || (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION)) {
@@ -2913,7 +2916,7 @@ static struct symbol *evaluate_cast(struct expression *expr)
struct symbol *ctype;
struct symbol *ttype, *stype;
int tclass, sclass;
- int tas = 0, sas = 0;
+ struct ident *tas = NULL, *sas = NULL;
if (!source)
return NULL;
@@ -3004,24 +3007,24 @@ static struct symbol *evaluate_cast(struct expression *expr)
}
if (ttype == &ulong_ctype && !Wcast_from_as)
- tas = -1;
+ tas = &bad_address_space;
else if (tclass == TYPE_PTR) {
examine_pointer_target(ttype);
tas = ttype->ctype.as;
}
if (stype == &ulong_ctype && !Wcast_from_as)
- sas = -1;
+ sas = &bad_address_space;
else if (sclass == TYPE_PTR) {
examine_pointer_target(stype);
sas = stype->ctype.as;
}
- if (!tas && sas > 0)
+ if (!tas && valid_as(sas))
warning(expr->pos, "cast removes address space '%s' of expression", show_as(sas));
- if (tas > 0 && sas > 0 && tas != sas)
+ if (valid_as(tas) && valid_as(sas) && tas != sas)
warning(expr->pos, "cast between address spaces (%s -> %s)", show_as(sas), show_as(tas));
- if (tas > 0 && !sas &&
+ if (valid_as(tas) && !sas &&
!is_null_pointer_constant(source) && Wcast_to_as)
warning(expr->pos,
"cast adds address space '%s' to expression", show_as(tas));
diff --git a/parse.c b/parse.c
index da912aca..3fef7b6b 100644
--- a/parse.c
+++ b/parse.c
@@ -1094,6 +1094,14 @@ static struct token *attribute_bitwise(struct token *token, struct symbol *attr,
return token;
}
+static struct ident *numerical_address_space(int asn)
+{
+ char buff[32];
+
+ sprintf(buff, "<asn:%d>", asn);
+ return built_in_ident(buff);
+}
+
static struct token *attribute_address_space(struct token *token, struct symbol *attr, struct decl_state *ctx)
{
struct expression *expr = NULL;
@@ -1103,7 +1111,7 @@ static struct token *attribute_address_space(struct token *token, struct symbol
if (expr) {
as = const_expression_value(expr);
if (Waddress_space && as)
- ctx->ctype.as = as;
+ ctx->ctype.as = numerical_address_space(as);
}
token = expect(token, ')', "after address_space attribute");
return token;
@@ -1825,7 +1833,7 @@ static struct token *pointer(struct token *token, struct decl_state *ctx)
ptr->ctype.contexts = ctx->ctype.contexts;
ctx->ctype.modifiers = 0;
ctx->ctype.base_type = ptr;
- ctx->ctype.as = 0;
+ ctx->ctype.as = NULL;
ctx->ctype.contexts = NULL;
ctx->ctype.alignment = 0;
diff --git a/show-parse.c b/show-parse.c
index ae098c28..0a980a5a 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -72,10 +72,11 @@ static void do_debug_symbol(struct symbol *sym, int indent)
if (!sym)
return;
- fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %p (%s:%d:%d) %s\n",
+ fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %s) %p (%s:%d:%d) %s\n",
indent, indent_string, typestr[sym->type],
sym->bit_size, sym->ctype.alignment,
- modifier_string(sym->ctype.modifiers), show_ident(sym->ident), sym->ctype.as,
+ modifier_string(sym->ctype.modifiers), show_ident(sym->ident),
+ show_as(sym->ctype.as),
sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos,
builtin_typename(sym) ?: "");
i = 0;
@@ -182,15 +183,11 @@ void show_symbol_list(struct symbol_list *list, const char *sep)
} END_FOR_EACH_PTR(sym);
}
-const char *show_as(unsigned int as)
+const char *show_as(struct ident *as)
{
- static char buffer[4][32];
- static int n;
- char *buff;
-
- buff = buffer[3 & ++n];
- sprintf(buff, "<asn:%u>", as);
- return buff;
+ if (!as)
+ return "";
+ return show_ident(as);
}
struct type_name {
@@ -287,7 +284,7 @@ static void do_show_type(struct symbol *sym, struct type_name *name)
{
const char *typename;
unsigned long mod = 0;
- int as = 0;
+ struct ident *as = NULL;
int was_ptr = 0;
int restr = 0;
int fouled = 0;
@@ -306,7 +303,7 @@ deeper:
name->start -= len;
memcpy(name->start, s, len);
mod = 0;
- as = 0;
+ as = NULL;
}
if (!sym)
@@ -358,12 +355,12 @@ deeper:
case SYM_NODE:
append(name, "%s", show_ident(sym->ident));
mod |= sym->ctype.modifiers;
- as |= sym->ctype.as;
+ combine_address_space(&as, sym->ctype.as);
break;
case SYM_BITFIELD:
mod |= sym->ctype.modifiers;
- as |= sym->ctype.as;
+ combine_address_space(&as, sym->ctype.as);
append(name, ":%d", sym->bit_size);
break;
@@ -373,7 +370,7 @@ deeper:
case SYM_ARRAY:
mod |= sym->ctype.modifiers;
- as |= sym->ctype.as;
+ combine_address_space(&as, sym->ctype.as);
if (was_ptr) {
prepend(name, "( ");
append(name, " )");
diff --git a/symbol.c b/symbol.c
index 2dcabe85..a3021223 100644
--- a/symbol.c
+++ b/symbol.c
@@ -214,7 +214,7 @@ static struct symbol *examine_base_type(struct symbol *sym)
base_type = examine_symbol_type(sym->ctype.base_type);
if (!base_type || base_type->type == SYM_PTR)
return base_type;
- sym->ctype.as |= base_type->ctype.as;
+ combine_address_space(&sym->ctype.as, base_type->ctype.as);
sym->ctype.modifiers |= base_type->ctype.modifiers & MOD_PTRINHERIT;
concat_ptr_list((struct ptr_list *)base_type->ctype.contexts,
(struct ptr_list **)&sym->ctype.contexts);
@@ -278,7 +278,7 @@ static struct symbol *examine_bitfield_type(struct symbol *sym)
*/
void merge_type(struct symbol *sym, struct symbol *base_type)
{
- sym->ctype.as |= base_type->ctype.as;
+ combine_address_space(&sym->ctype.as, base_type->ctype.as);
sym->ctype.modifiers |= (base_type->ctype.modifiers & ~MOD_STORAGE);
concat_ptr_list((struct ptr_list *)base_type->ctype.contexts,
(struct ptr_list **)&sym->ctype.contexts);
diff --git a/symbol.h b/symbol.h
index b8e0cac8..35e932d9 100644
--- a/symbol.h
+++ b/symbol.h
@@ -101,7 +101,7 @@ struct ctype {
unsigned long modifiers;
unsigned long alignment;
struct context_list *contexts;
- unsigned int as;
+ struct ident *as;
struct symbol *base_type;
};
@@ -315,7 +315,7 @@ extern void bind_symbol(struct symbol *, struct ident *, enum namespace);
extern struct symbol *examine_symbol_type(struct symbol *);
extern struct symbol *examine_pointer_target(struct symbol *);
-extern const char *show_as(unsigned int as);
+extern const char *show_as(struct ident *as);
extern const char *show_typename(struct symbol *sym);
extern const char *builtin_typename(struct symbol *sym);
extern const char *builtin_ctypename(struct ctype *ctype);
@@ -500,4 +500,24 @@ static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace
void create_fouled(struct symbol *type);
struct symbol *befoul(struct symbol *type);
+
+extern struct ident bad_address_space;
+
+static inline bool valid_as(struct ident *as)
+{
+ return as && as != &bad_address_space;
+}
+
+static inline void combine_address_space(struct ident **tas, struct ident *sas)
+{
+ struct ident *as;
+ if (!sas)
+ return;
+ as = *tas;
+ if (!as)
+ *tas = sas;
+ else if (as != sas)
+ *tas = &bad_address_space;
+}
+
#endif /* SYMBOL_H */