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