aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--parse.c34
-rw-r--r--validation/as-name.c17
2 files changed, 43 insertions, 8 deletions
diff --git a/parse.c b/parse.c
index 3fef7b6b..4739d39c 100644
--- a/parse.c
+++ b/parse.c
@@ -1098,6 +1098,8 @@ static struct ident *numerical_address_space(int asn)
{
char buff[32];
+ if (!asn)
+ return NULL;
sprintf(buff, "<asn:%d>", asn);
return built_in_ident(buff);
}
@@ -1105,15 +1107,31 @@ static struct ident *numerical_address_space(int asn)
static struct token *attribute_address_space(struct token *token, struct symbol *attr, struct decl_state *ctx)
{
struct expression *expr = NULL;
- int as;
+ struct ident *as = NULL;
+ struct token *next;
+
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 = numerical_address_space(as);
- }
- token = expect(token, ')', "after address_space attribute");
+ switch (token_type(token)) {
+ case TOKEN_NUMBER:
+ next = primary_expression(token, &expr);
+ if (expr->type != EXPR_VALUE)
+ goto invalid;
+ as = numerical_address_space(expr->value);
+ break;
+ case TOKEN_IDENT:
+ next = token->next;
+ as = token->ident;
+ break;
+ default:
+ next = token->next;
+ invalid:
+ as = NULL;
+ warning(token->pos, "invalid address space name");
+ }
+
+ if (Waddress_space && as)
+ ctx->ctype.as = as;
+ token = expect(next, ')', "after address_space attribute");
return token;
}
diff --git a/validation/as-name.c b/validation/as-name.c
new file mode 100644
index 00000000..4dd65798
--- /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
+ */