diff mbox series

[v3,4/5] as-name: allow ident as address_space

Message ID 20181210010928.86457-5-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show
Series display address spaces by name | expand

Commit Message

Luc Van Oostenryck Dec. 10, 2018, 1:09 a.m. UTC
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@linux-foundation.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 parse.c              | 34 ++++++++++++++++++++++++++--------
 validation/as-name.c | 17 +++++++++++++++++
 2 files changed, 43 insertions(+), 8 deletions(-)
 create mode 100644 validation/as-name.c
diff mbox series

Patch

diff --git a/parse.c b/parse.c
index af60549f5..d0385f34c 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 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
+ */