[PATCH 2/6] context: fix parsing of attribute 'context'

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

 



Currently the parsing of the attribute 'context' is rather
complex and uses a loop which allows 1, 2, 3 or more arguments.
But the the real syntax is only correct for 2 or 3 arguments.

Furthermore the parsing mixes calls to expect() with its own
error reporting. This is a problem because if the error has first
been reported by expect(), the returned token is 'bad_token'
which has no position so you can have error logs like:
	test.c:1:43: error: Expected ( after context attribute
	test.c:1:43: error: got )
	builtin:0:0: error: expected context input/output values
But the 'builtin:0.0' should really be 'test.c:1.43' or, even better,
there shouldn't be a double error reporting.

Fix this by simplifying the parsing and only support 2 or 3 args.
Also, make the error messages slightly more explicit about the
nature of the error.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 parse.c                   | 45 +++++++++++----------------------------
 validation/attr-context.c | 40 ++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 32 deletions(-)
 create mode 100644 validation/attr-context.c

diff --git a/parse.c b/parse.c
index d94c53a22..68cdeb226 100644
--- a/parse.c
+++ b/parse.c
@@ -1133,43 +1133,24 @@ static struct token *attribute_context(struct token *token, struct symbol *attr,
 {
 	struct context *context = alloc_context();
 	struct expression *args[3];
-	int argc = 0;
+	int idx = 0;
 
 	token = expect(token, '(', "after context attribute");
-	while (!match_op(token, ')')) {
-		struct expression *expr = NULL;
-		token = conditional_expression(token, &expr);
-		if (!expr)
-			break;
-		if (argc < 3)
-			args[argc++] = expr;
-		if (!match_op(token, ','))
-			break;
+	token = conditional_expression(token, &args[0]);
+	token = expect(token, ',', "after context 1st argument");
+	token = conditional_expression(token, &args[1]);
+	if (match_op(token, ',')) {
 		token = token->next;
-	}
-
-	switch(argc) {
-	case 0:
-		sparse_error(token->pos, "expected context input/output values");
-		break;
-	case 1:
-		context->in = get_expression_value(args[0]);
-		break;
-	case 2:
-		context->in = get_expression_value(args[0]);
-		context->out = get_expression_value(args[1]);
-		break;
-	case 3:
+		token = conditional_expression(token, &args[2]);
+		token = expect(token, ')', "after context 3rd argument");
 		context->context = args[0];
-		context->in = get_expression_value(args[1]);
-		context->out = get_expression_value(args[2]);
-		break;
+		idx++;
+	} else {
+		token = expect(token, ')', "after context 2nd argument");
 	}
-
-	if (argc)
-		add_ptr_list(&ctx->ctype.contexts, context);
-
-	token = expect(token, ')', "after context attribute");
+	context->in =  get_expression_value(args[idx++]);
+	context->out = get_expression_value(args[idx++]);
+	add_ptr_list(&ctx->ctype.contexts, context);
 	return token;
 }
 
diff --git a/validation/attr-context.c b/validation/attr-context.c
new file mode 100644
index 000000000..00e54c668
--- /dev/null
+++ b/validation/attr-context.c
@@ -0,0 +1,40 @@
+static void a(void) __attribute__((context));		// KO
+static void b(void) __attribute__((context()));		// KO
+static void c(void) __attribute__((context 1));		// KO
+static void d(void) __attribute__((context 1,2));	// KO
+static void e(void) __attribute__((context (1)));	// !!!!
+static void f(void) __attribute__((context(0)));	// !!!!
+static void g(void) __attribute__((context(0,1,2,3)));	// KO
+
+static void h(void) __attribute__((context (1,2)));	// OK
+static void i(void) __attribute__((context(0,1)));	// OK
+static void j(void) __attribute__((context(0,1,2)));	// OK
+
+extern int u, v;
+static void x(void) __attribute__((context(0,1,v)));
+static void y(void) __attribute__((context(0,u,1)));
+static void z(void) __attribute__((context(0,u)));
+
+/*
+ * check-name: attr-context
+ *
+ * check-error-start
+attr-context.c:1:43: error: Expected ( after context attribute
+attr-context.c:1:43: error: got )
+attr-context.c:2:44: error: Expected , after context 1st argument
+attr-context.c:2:44: error: got )
+attr-context.c:3:44: error: Expected ( after context attribute
+attr-context.c:3:44: error: got 1
+attr-context.c:4:44: error: Expected ( after context attribute
+attr-context.c:4:44: error: got 1
+attr-context.c:5:46: error: Expected , after context 1st argument
+attr-context.c:5:46: error: got )
+attr-context.c:6:45: error: Expected , after context 1st argument
+attr-context.c:6:45: error: got )
+attr-context.c:7:49: error: Expected ) after context 3rd argument
+attr-context.c:7:49: error: got ,
+attr-context.c:14:48: error: bad constant expression
+attr-context.c:15:46: error: bad constant expression
+attr-context.c:16:46: error: bad constant expression
+ * check-error-end
+ */
-- 
2.17.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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