[PATCH 6/9] enum: only warn (once) when mixing bitwiseness

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

 



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



[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