As an extension to the standard C types, parse supports bitwise types (also called 'restricted') which should in no circonstances mix with other types. In the kernel, some enums are defined with such bitwise types as initializers; the goal being to have slightly more strict enums. While the semantic of such enums is not very clear, using a mix of bitwise and not-bitwise initializers completely defeats the desired stricter typing. Attract some attention to such mixed initialization by issuing a single warning for each such declarations. 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 34a70b447..ac8c0aadf 100644 --- a/parse.c +++ b/parse.c @@ -854,6 +854,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; @@ -915,6 +916,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; @@ -962,6 +967,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.18.0