Sparse has support for restricted/bitwise types which should in no circonstances mix with any other types. In the kernel, some enums are defined with such bitwise type as initializers; the goal being to have slightly more strict enums. While the semantic of such enums are not very clear, using a mix of bitwise and now bitwise initializers completely defeat the the stricter typing. Issuing an appropriate warnings in such cases (and insure that only one warnings is given per declaration). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- parse.c | 7 +++++++ validation/enum-bitwise-mixed.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 validation/enum-bitwise-mixed.c diff --git a/parse.c b/parse.c index 364dcc553..38e5d3056 100644 --- a/parse.c +++ b/parse.c @@ -841,6 +841,7 @@ static struct token *parse_enum_declaration(struct token *token, struct symbol * unsigned long long lastval = 0; struct symbol *ctype = NULL, *base_type = NULL; Num upper = {-1, 0}, lower = {1, 0}; + int mix_bitwise = 0; parent->examined = 1; parent->ctype.base_type = &int_ctype; @@ -902,6 +903,10 @@ static struct token *parse_enum_declaration(struct token *token, struct symbol * /* nothing */ } else if (is_int_type(base_type) && is_int_type(ctype)) { base_type = &int_ctype; + } else if (is_restricted_type(base_type) != is_restricted_type(ctype)) { + if (!mix_bitwise++) { + warning(expr->pos, "mixed bitwiseness"); + } } else base_type = &bad_ctype; parent->ctype.base_type = base_type; @@ -949,6 +954,8 @@ static struct token *parse_enum_declaration(struct token *token, struct symbol * parent->ctype.modifiers |= (base_type->ctype.modifiers & MOD_UNSIGNED); parent->examined = 0; + if (mix_bitwise) + return token; cast_enum_list(parent->symbol_list, base_type); return token; diff --git a/validation/enum-bitwise-mixed.c b/validation/enum-bitwise-mixed.c new file mode 100644 index 000000000..07d77176c --- /dev/null +++ b/validation/enum-bitwise-mixed.c @@ -0,0 +1,29 @@ +#define __bitwise __attribute__((bitwise)) +#define __force __attribute__((force)) + +typedef long long __bitwise bits; + +enum a { + AR = (__force bits) 0, + AP = 0, + AS = (__force bits) 1, + AQ = 1, +}; +_Static_assert(sizeof(AP) == sizeof(int), "is bad?"); + +enum b { + BP = 0, + BR = (__force bits) 0, + BQ = 1, + BS = (__force bits) 1, +}; +_Static_assert(sizeof(BP) == sizeof(int), "is bad?"); + +/* + * check-name: enum-bitwise-mixed + * + * check-error-start +enum-bitwise-mixed.c:8:14: warning: mixed bitwiseness +enum-bitwise-mixed.c:16:15: warning: mixed bitwiseness + * 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