[PATCH] "Initializer entry defined twice" should not trigger with zero-size fields

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

 



If a field of a structure has size 0 (which happens with an empty struct), the
subsequent field will have the same offset.  Assigning to both thus triggers
the "Initializer entry defined twice" error, which should not happen.  Change
verify_nonoverlapping to not warn about overlaps where the first field has
size 0.

Add a validation file (validation/initializer-entry-defined-twice.c) for this
warning, which covers two cases where it should trigger (same struct field
twice; two fields of a union) and this case where it should not.

This fixes numerous warnings in Linux which triggered on initialization
of structs containing empty structs; for example, this happens when
raw_spinlock_t has no members, spinlock_t has no members other than a
raw_spinlock_t, and a structure initializer initializes a spinlock_t
(with SPIN_LOCK_UNLOCKED or SPIN_LOCK_LOCKED) followed by other fields.

Signed-off-by: Josh Triplett <josh@xxxxxxxxxxxxxxx>
---
 expand.c                                     |   10 ++----
 validation/initializer-entry-defined-twice.c |   43 ++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/expand.c b/expand.c
index 1539446..58d41f9 100644
--- a/expand.c
+++ b/expand.c
@@ -872,12 +872,10 @@ static void verify_nonoverlapping(struct
 	struct expression *b;
 
 	FOR_EACH_PTR(*list, b) {
-		if (a) {
-			if (bit_offset(a) == bit_offset(b)) {
-				sparse_error(a->pos, "Initializer entry defined twice");
-				info(b->pos, "  also defined here");
-				return;
-			}
+		if (a && a->ctype->bit_size && bit_offset(a) == bit_offset(b)) {
+			sparse_error(a->pos, "Initializer entry defined twice");
+			info(b->pos, "  also defined here");
+			return;
 		}
 		a = b;
 	} END_FOR_EACH_PTR(b);
diff --git a/validation/initializer-entry-defined-twice.c b/validation/initializer-entry-defined-twice.c
new file mode 100644
index 0000000..80434f1
--- /dev/null
+++ b/validation/initializer-entry-defined-twice.c
@@ -0,0 +1,43 @@
+/* Tests for the "Initializer entry defined twice" warning. */
+
+/* Initializing a struct field twice should trigger the warning. */
+struct normal {
+	int field1;
+	int field2;
+};
+
+struct normal struct_error = {
+	.field1 = 0,
+	.field1 = 0
+};
+
+/* Initializing two different fields of a union should trigger the warning. */
+struct has_union {
+	int x;
+	union {
+		int a;
+		int b;
+	} y;
+	int z;
+};
+
+struct has_union union_error = {
+	.y = {
+		.a = 0,
+		.b = 0
+	}
+};
+
+/* Empty structures can make two fields have the same offset in a struct.
+ * Initialzing both should not trigger the warning. */
+struct empty { };
+
+struct same_offset {
+	struct empty field1;
+	int field2;
+};
+
+struct same_offset not_an_error = {
+	.field1 = { },
+	.field2 = 0
+};
-- 
1.4.1.1


-
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