On 08/12/2018 22:04, Luc Van Oostenryck wrote: > Currently, address space 1 is displayed as '<asn:1>' and so on. > Now that address spaces can be displayed by name, the address space > number should just be an implementation detail and it would make > more sense the be able to 'declare' these address space directly > by name, like: > #define __user attribute((noderef, address_space(__user))) > > Since directly using the name instead of an number creates some > problems internally, allow this syntax but for the moment keep > the address space number and use a table to lookup the number > from the name. > > References: https://marc.info/?l=linux-sparse&m=153627490128505 > Idea-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> > --- > parse.c | 41 ++++++++++++++++++++++++++++++++++++----- > validation/as-name.c | 17 +++++++++++++++++ > 2 files changed, 53 insertions(+), 5 deletions(-) > create mode 100644 validation/as-name.c > > diff --git a/parse.c b/parse.c > index d4886c41c..585b8d184 100644 > --- a/parse.c > +++ b/parse.c > @@ -1094,17 +1094,48 @@ static struct token *attribute_bitwise(struct token *token, struct symbol *attr, > return token; > } > > +static int lookup_address_space(struct ident *ident) > +{ > + static int last_as; > + int i; > + > + for (i = 1; i < ARRAY_SIZE(address_space_names); i++) { Hmm, i = 1 ? Is an address-space number 0 illegal? > + const struct ident *name = address_space_names[i]; > + if (name == ident) > + return i; > + if (!name) { > + address_space_names[i] = ident; > + return last_as = i; > + } > + } > + return ++last_as; Hmm, so the table has overflowed? why are you returning this? > +} > + > static struct token *attribute_address_space(struct token *token, struct symbol *attr, struct decl_state *ctx) > { > struct expression *expr = NULL; > int as; > token = expect(token, '(', "after address_space attribute"); > - token = conditional_expression(token, &expr); > - if (expr) { > - as = const_expression_value(expr); > - if (Waddress_space && as) > - ctx->ctype.as = as; > + switch (token_type(token)) { > + case TOKEN_NUMBER: > + token = primary_expression(token, &expr); > + if (expr->type != EXPR_VALUE) > + goto invalid; > + as = expr->value; > + break; > + case TOKEN_IDENT: > + as = lookup_address_space(token->ident); > + token = token->next; > + break; > + default: > + invalid: > + warning(token->pos, "invalid address space name"); > + as = 0; > + token = token->next; > } > + > + if (Waddress_space && as) > + ctx->ctype.as = as; Hmm, so if -Wno-address_space, or as == 0, ignore address-space processing (ctx->ctype.as stays set to zero?). > token = expect(token, ')', "after address_space attribute"); > return token; > } > diff --git a/validation/as-name.c b/validation/as-name.c > new file mode 100644 > index 000000000..4dd65798d > --- /dev/null > +++ b/validation/as-name.c > @@ -0,0 +1,17 @@ > +#define __user __attribute__((address_space(__user))) > + > +extern void fun(void *addr); > + > +static void foo(void __user *ptr) > +{ > + return fun(ptr); > +} > +/* > + * check-name: as-name attribute > + * > + * check-error-start > +as-name.c:7:20: warning: incorrect type in argument 1 (different address spaces) > +as-name.c:7:20: expected void *addr > +as-name.c:7:20: got void __user *ptr > + * check-error-end > + */ >