The kernel is soon going to start using the __cleanup__ attribute so we need to add support for it in Sparse. This patch is a bit ugly, but it gives me the minimum that I need to make Smatch work and hopefully it's the starts the conversation about how to do this correctly. Signed-off-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx> --- parse.c | 24 +++++++++++++++++++++++- symbol.h | 2 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/parse.c b/parse.c index 3d6fef7cb011..185a4c7f7cfb 100644 --- a/parse.c +++ b/parse.c @@ -79,7 +79,8 @@ typedef struct token *attr_t(struct token *, struct symbol *, struct decl_state *); static attr_t - attribute_packed, attribute_aligned, attribute_modifier, + attribute_packed, attribute_aligned, attribute_cleanup, + attribute_modifier, attribute_function, attribute_bitwise, attribute_address_space, attribute_context, @@ -361,6 +362,10 @@ static struct symbol_op aligned_op = { .attribute = attribute_aligned, }; +static struct symbol_op cleanup_op = { + .attribute = attribute_cleanup, +}; + static struct symbol_op attr_mod_op = { .attribute = attribute_modifier, }; @@ -537,6 +542,7 @@ static struct init_keyword { /* Attributes */ D("packed", &packed_op), D("aligned", &aligned_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), @@ -1114,6 +1120,18 @@ static struct token *attribute_aligned(struct token *token, struct symbol *attr, return token; } +static struct token *attribute_cleanup(struct token *token, struct symbol *attr, struct decl_state *ctx) +{ + struct expression *expr = NULL; + + if (match_op(token, '(')) { + token = parens_expression(token, &expr, "in attribute"); + if (expr && expr->type == EXPR_SYMBOL) + ctx->cleanup = expr; + } + return token; +} + static void apply_mod(struct position *pos, unsigned long *mods, unsigned long mod) { if (*mods & mod & ~MOD_DUP_OK) @@ -1910,6 +1928,7 @@ static struct token *declaration_list(struct token *token, struct symbol_list ** decl->ctype = ctx.ctype; decl->ctype.modifiers |= mod; + decl->cleanup = ctx.cleanup; decl->endpos = token->pos; add_symbol(list, decl); if (!match_op(token, ',')) @@ -1964,6 +1983,7 @@ 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) @@ -2924,6 +2944,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis decl->ctype = ctx.ctype; decl->ctype.modifiers |= mod; + decl->cleanup = ctx.cleanup; decl->endpos = token->pos; /* Just a type declaration? */ @@ -3048,6 +3069,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis apply_modifiers(token->pos, &ctx); decl->ctype = ctx.ctype; decl->ctype.modifiers |= mod; + decl->cleanup = ctx.cleanup; decl->endpos = token->pos; if (!ident) { sparse_error(token->pos, "expected identifier name in type definition"); diff --git a/symbol.h b/symbol.h index 5270fcd73a10..88130c15d4bd 100644 --- a/symbol.h +++ b/symbol.h @@ -107,6 +107,7 @@ struct decl_state { struct ctype ctype; struct ident **ident; struct symbol_op *mode; + struct expression *cleanup; unsigned long f_modifiers; // function attributes unsigned long storage_class; unsigned char prefer_abstract; @@ -204,6 +205,7 @@ struct symbol { struct statement *inline_stmt; struct symbol_list *inline_symbol_list; struct expression *initializer; + struct expression *cleanup; struct entrypoint *ep; struct symbol *definition; }; -- 2.39.2