diff options
author | Josh Triplett <josh@joshtriplett.org> | 2009-10-11 22:51:56 +0000 |
---|---|---|
committer | Christopher <sparse@chrisli.org> | 2010-03-28 17:51:36 -0700 |
commit | f09699fa80b3b15b94b3e1878ac6cdfdb48f43ac (patch) | |
tree | e29fe5fb76dbba97a7dad2eda54de4a694c53a51 /parse.c | |
parent | Rename -Wall to Wsparse-all, so it doesn't get turned on unintentionally (diff) | |
download | sparse-f09699fa80b3b15b94b3e1878ac6cdfdb48f43ac.tar.gz sparse-f09699fa80b3b15b94b3e1878ac6cdfdb48f43ac.tar.bz2 sparse-f09699fa80b3b15b94b3e1878ac6cdfdb48f43ac.zip |
New attribute designated_init: mark a struct as requiring designated init
Some structure types provide a set of fields of which most users will
only initialize the subset they care about. Users of these types should
always use designated initializers, to avoid relying on the specific
structure layout. Examples of this type of structure include the many
*_operations structures in Linux, which contain a set of function
pointers; these structures occasionally gain a new field, lose an
obsolete field, or change the function signature for a field.
Add a new attribute designated_init; when used on a struct, it tells
Sparse to warn on any positional initialization of a field in that
struct.
The new flag -Wdesignated-init controls these warnings. Since these
warnings only fire for structures explicitly tagged with the attribute,
enable the warning by default.
Includes documentation and test case.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Christopher Li <sparse@chrisli.org>
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 15 |
1 files changed, 15 insertions, 0 deletions
@@ -64,6 +64,7 @@ typedef struct token *attr_t(struct token *, struct symbol *, static attr_t attribute_packed, attribute_aligned, attribute_modifier, attribute_address_space, attribute_context, + attribute_designated_init, attribute_transparent_union, ignore_attribute, attribute_mode, attribute_force; @@ -319,6 +320,10 @@ static struct symbol_op context_op = { .attribute = attribute_context, }; +static struct symbol_op designated_init_op = { + .attribute = attribute_designated_init, +}; + static struct symbol_op transparent_union_op = { .attribute = attribute_transparent_union, }; @@ -454,6 +459,7 @@ static struct init_keyword { { "address_space",NS_KEYWORD, .op = &address_space_op }, { "mode", NS_KEYWORD, .op = &mode_op }, { "context", NS_KEYWORD, .op = &context_op }, + { "designated_init", NS_KEYWORD, .op = &designated_init_op }, { "__transparent_union__", NS_KEYWORD, .op = &transparent_union_op }, { "noreturn", NS_KEYWORD, MOD_NORETURN, .op = &attr_mod_op }, { "__noreturn__", NS_KEYWORD, MOD_NORETURN, .op = &attr_mod_op }, @@ -1145,6 +1151,15 @@ static struct token *attribute_context(struct token *token, struct symbol *attr, return token; } +static struct token *attribute_designated_init(struct token *token, struct symbol *attr, struct decl_state *ctx) +{ + if (ctx->ctype.base_type && ctx->ctype.base_type->type == SYM_STRUCT) + ctx->ctype.base_type->designated_init = 1; + else + warning(token->pos, "attribute designated_init applied to non-structure type"); + return token; +} + static struct token *attribute_transparent_union(struct token *token, struct symbol *attr, struct decl_state *ctx) { if (Wtransparent_union) |