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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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              | 34 ++++++++++++++++++++++++++--------
 validation/as-name.c | 17 +++++++++++++++++
 2 files changed, 43 insertions(+), 8 deletions(-)
 create mode 100644 validation/as-name.c

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
+ */
-- 
2.19.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux