Re: [PATCH v2] parse: handle __cleanup__ attribute

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

 



On Wed, Dec 13, 2023 at 01:14:29PM +0300, Dan Carpenter wrote:
> On Tue, Dec 12, 2023 at 12:39:40PM +0300, Dan Carpenter wrote:
> > > > @@ -2924,6 +2945,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
> > > >  
> > > >  	decl->ctype = ctx.ctype;
> > > >  	decl->ctype.modifiers |= mod;
> > > > +	decl->cleanup = ctx.cleanup;
> > > 
> > > Similarly, the attribute should only be applied to automatic variables,
> > > so this should not be needed/should be detected as an error.
> > > 
> > 
> > Yeah.  There are a couple other "cleanup" lines later in the function
> > that should be deleted as well, I see.
> 
> Hm...  Something went wrong.  When I remove this assignment then the
> cleanup function isn't saved here:

Mmmmhh yes, my bad.
I thought that the parsing functions followed closely the names of the
C grammar in the spec. They largely do but not in this case (they can't
because some context is needed to distinguish between 'declaration' and
'function-definition').

Would the following patch be OK for you when applied on top of your v2?
It contains:
- the attribute can be removed from the list of ignored attributes
- I prefer to add the "attribute_cleanup," on its own line
- I added some checks and a few corresponding testcases
- the s/D("__cleanup__"/D("cleanup"/
- and the removal of 'sym->cleanup = ctx.cleanup;' from typename() which
  I think is still unneeded.

Best regards,
-- Luc


diff --git a/gcc-attr-list.h b/gcc-attr-list.h
index c78001757229..928ea3889e01 100644
--- a/gcc-attr-list.h
+++ b/gcc-attr-list.h
@@ -24,7 +24,6 @@ GCC_ATTR(brk_interrupt)
 GCC_ATTR(callee_pop_aggregate_return)
 GCC_ATTR(cb)
 GCC_ATTR(cdecl)
-GCC_ATTR(cleanup)
 GCC_ATTR(cmse_nonsecure_call)
 GCC_ATTR(cmse_nonsecure_entry)
 GCC_ATTR(cold)
diff --git a/parse.c b/parse.c
index e5b5e6acc062..f868bf63a0f5 100644
--- a/parse.c
+++ b/parse.c
@@ -79,11 +79,11 @@ typedef struct token *attr_t(struct token *, struct symbol *,
 			     struct decl_state *);
 
 static attr_t
-	attribute_packed, attribute_aligned, attribute_cleanup,
-	attribute_modifier,
+	attribute_packed, attribute_aligned, attribute_modifier,
 	attribute_function,
 	attribute_bitwise,
 	attribute_address_space, attribute_context,
+	attribute_cleanup,
 	attribute_designated_init,
 	attribute_transparent_union, ignore_attribute,
 	attribute_mode, attribute_force;
@@ -542,7 +542,7 @@ static struct init_keyword {
 	/* Attributes */
 	D("packed",		&packed_op),
 	D("aligned",		&aligned_op),
-	D("__cleanup__",	&cleanup_op),
+	D("cleanup",		&cleanup_op),
 	D("nocast",		&attr_mod_op,		.mods = MOD_NOCAST),
 	D("noderef",		&attr_mod_op,		.mods = MOD_NODEREF),
 	D("safe",		&attr_mod_op,		.mods = MOD_SAFE),
@@ -1125,10 +1125,18 @@ static struct token *attribute_cleanup(struct token *token, struct symbol *attr,
 	struct expression *expr = NULL;
 
 	if (match_op(token, '(')) {
-		token = parens_expression(token, &expr, "in attribute");
+		token = token->next;
+		if (match_op(token, ')'))
+			sparse_error(token->pos, "an argument is expected for attribute 'cleanup'");
+		else if (token_type(token) != TOKEN_IDENT)
+			sparse_error(token->pos, "argument is not an identifier");
+		token = primary_expression(token, &expr);
 		if (expr && expr->type == EXPR_SYMBOL)
 			ctx->cleanup = expr;
+		return expect(token, ')', "after attribute's argument'");
 	}
+
+	sparse_error(token->pos, "an argument is expected for attribute 'cleanup'");
 	return token;
 }
 
@@ -1984,7 +1992,6 @@ struct token *typename(struct token *token, struct symbol **p, int *forced)
 	token = declarator(token, &ctx);
 	apply_modifiers(token->pos, &ctx);
 	sym->ctype = ctx.ctype;
-	sym->cleanup = ctx.cleanup;
 	sym->endpos = token->pos;
 	class = ctx.storage_class;
 	if (forced)
diff --git a/validation/parsing/attr-cleanup.c b/validation/parsing/attr-cleanup.c
new file mode 100644
index 000000000000..ac64649c2ac1
--- /dev/null
+++ b/validation/parsing/attr-cleanup.c
@@ -0,0 +1,33 @@
+#define __cleanup(F)	__attribute__((__cleanup__(F)))
+
+void fun(int *ptr);
+
+int test(int n);
+int test(int n)
+{
+	int var __attribute__((cleanup(fun))) = 1;
+	int alt __cleanup(fun) = 2;
+	int mis __cleanup(0) = 3;
+	int non __attribute__((cleanup));
+	int mis __attribute__((cleanup()));
+	int two __attribute__((cleanup(fun, fun)));
+
+        for (int i __cleanup(fun) = 0; i < n; i++)
+		;
+
+	var = 5;
+	return 0;
+}
+
+/*
+ * check-name: attr-cleanup
+ * check-command: sparse -Wunknown-attribute $file
+ *
+ * check-error-start
+parsing/attr-cleanup.c:10:17: error: argument is not an identifier
+parsing/attr-cleanup.c:11:39: error: an argument is expected for attribute 'cleanup'
+parsing/attr-cleanup.c:12:40: error: an argument is expected for attribute 'cleanup'
+parsing/attr-cleanup.c:13:43: error: Expected ) after attribute's argument'
+parsing/attr-cleanup.c:13:43: error: got ,
+ * check-error-end
+ */




[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