[PATCH 09/12] enum: only warn (once) when mixing bitwiseness

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

 



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




[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