[PATCH] teach sparse about asm inline

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

 



GCC will soon allow to specifiy 'inline' with asm statements.
This feature has been asked by kernel devs and will most probably
by used for the kernel.

So, teach sparse about this syntax too.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 parse.c                 | 18 ++++++++++++++--
 symbol.h                |  1 +
 validation/asm-inline.c | 46 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 validation/asm-inline.c

diff --git a/parse.c b/parse.c
index d4886c41c..627c70929 100644
--- a/parse.c
+++ b/parse.c
@@ -118,6 +118,12 @@ enum {
 	SNone = 0, STypedef, SAuto, SRegister, SExtern, SStatic, SForced, SMax,
 };
 
+static struct token *asm_modifier(struct token *token, struct statement *stmt)
+{
+	// accept but ignore
+	return token->next;
+}
+
 static struct symbol_op typedef_op = {
 	.type = KW_MODIFIER,
 	.declarator = typedef_specifier,
@@ -126,6 +132,7 @@ static struct symbol_op typedef_op = {
 static struct symbol_op inline_op = {
 	.type = KW_MODIFIER,
 	.declarator = inline_specifier,
+	.asm_stmt = asm_modifier,
 };
 
 static declarator_t noreturn_specifier;
@@ -173,6 +180,7 @@ static struct symbol_op const_op = {
 static struct symbol_op volatile_op = {
 	.type = KW_QUALIFIER,
 	.declarator = volatile_qualifier,
+	.asm_stmt = asm_modifier,
 };
 
 static struct symbol_op restrict_op = {
@@ -2041,8 +2049,14 @@ static struct token *parse_asm_statement(struct token *token, struct statement *
 
 	token = token->next;
 	stmt->type = STMT_ASM;
-	if (match_idents(token, &__volatile___ident, &__volatile_ident, &volatile_ident, NULL)) {
-		token = token->next;
+	while (token_type(token) == TOKEN_IDENT) {
+		struct symbol *s = lookup_keyword(token->ident, NS_TYPEDEF);
+		struct token *next = NULL;
+		if (s && s->op && s->op->asm_stmt)
+			next = s->op->asm_stmt(token, stmt);
+		if (!next)
+			break;
+		token = next;
 	}
 	if (token_type(token) == TOKEN_IDENT && token->ident == &goto_ident) {
 		is_goto = 1;
diff --git a/symbol.h b/symbol.h
index 5a3d7cef5..ad3302277 100644
--- a/symbol.h
+++ b/symbol.h
@@ -121,6 +121,7 @@ struct symbol_op {
 	/* keywords */
 	struct token *(*declarator)(struct token *token, struct decl_state *ctx);
 	struct token *(*statement)(struct token *token, struct statement *stmt);
+	struct token *(*asm_stmt)(struct token *token, struct statement *stmt);
 	struct token *(*toplevel)(struct token *token, struct symbol_list **list);
 	struct token *(*attribute)(struct token *token, struct symbol *attr, struct decl_state *ctx);
 	struct symbol *(*to_mode)(struct symbol *);
diff --git a/validation/asm-inline.c b/validation/asm-inline.c
new file mode 100644
index 000000000..2b86ea98c
--- /dev/null
+++ b/validation/asm-inline.c
@@ -0,0 +1,46 @@
+void foo(void)
+{
+	asm("");
+	asm volatile ("v");
+	asm inline ("i");
+	asm volatile inline ("vi");
+	asm inline volatile ("iv");
+
+	asm goto ("g");
+	asm volatile goto ("vg");
+	asm inline goto ("ig");
+	asm volatile inline goto ("vig");
+	asm inline volatile goto ("ivg");
+
+	asm goto volatile ("gv");
+	asm goto inline ("gi");
+	asm goto volatile inline ("gvi");
+	asm goto inline volatile ("giv");
+	asm volatile goto inline ("vgi");
+	asm inline goto volatile ("giv");
+}
+
+/*
+ * check-name: asm-inline
+ *
+ * check-error-start
+asm-inline.c:15:18: error: Expected ( after asm
+asm-inline.c:15:18: error: got volatile
+asm-inline.c:16:18: error: Expected ( after asm
+asm-inline.c:16:18: error: got inline
+asm-inline.c:17:18: error: Expected ( after asm
+asm-inline.c:17:18: error: got volatile
+asm-inline.c:18:18: error: Expected ( after asm
+asm-inline.c:18:18: error: got inline
+asm-inline.c:19:27: error: Expected ( after asm
+asm-inline.c:19:27: error: got inline
+asm-inline.c:20:25: error: Expected ( after asm
+asm-inline.c:20:25: error: got volatile
+asm-inline.c:15:9: error: need constant string for inline asm
+asm-inline.c:16:9: error: need constant string for inline asm
+asm-inline.c:17:9: error: need constant string for inline asm
+asm-inline.c:18:9: error: need constant string for inline asm
+asm-inline.c:19:9: error: need constant string for inline asm
+asm-inline.c:20:9: error: need constant string for inline asm
+ * 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