aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-16 12:27:42 -0400
committerChristopher Li <sparse@chrisli.org>2014-07-16 14:18:42 -0700
commitb3e9d87c6a98bde0c95bc8badfde75c06661738b (patch)
tree8bc85c989d688090475286eebb1318f0b3538cd8
parent1db35d0a95caee0f0c57e5dc227822381579620d (diff)
downloadsparse-b3e9d87c6a98bde0c95bc8badfde75c06661738b.tar.gz
sparse: make bits_to_bytes round up instead of down
Currently, sparse handles arrays of bools incorrectly. If you declare an array of bools like this: static _Bool boolarray[3] = { [0] = 1, [1] = 1, }; ...you get warnings like this (which are bogus): ./test.c:2:10: warning: Initializer entry defined twice ./test.c:3:10: also defined here The problem is that bits_to_bytes rounds down instead of up, and sparse defaults to _Bool being only 1 bit in size. This causes sparse to think that they sit within the same byte, when they do not. Fix bits_to_bytes to round up instead of down, and fix the call in init_ctype to no longer correct for it. Also add a validation test to ensure that we don't break this in the future. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
-rw-r--r--symbol.c2
-rw-r--r--target.h2
-rw-r--r--validation/initializer-entry-defined-twice.c10
3 files changed, 12 insertions, 2 deletions
diff --git a/symbol.c b/symbol.c
index 4b91abd8..1a3df636 100644
--- a/symbol.c
+++ b/symbol.c
@@ -900,7 +900,7 @@ void init_ctype(void)
struct symbol *sym = ctype->ptr;
unsigned long bit_size = ctype->bit_size ? *ctype->bit_size : -1;
unsigned long maxalign = ctype->maxalign ? *ctype->maxalign : 0;
- unsigned long alignment = bits_to_bytes(bit_size + bits_in_char - 1);
+ unsigned long alignment = bits_to_bytes(bit_size);
if (alignment > maxalign)
alignment = maxalign;
diff --git a/target.h b/target.h
index 1030c7c3..140df3c1 100644
--- a/target.h
+++ b/target.h
@@ -49,7 +49,7 @@ extern int enum_alignment;
static inline int bits_to_bytes(int bits)
{
- return bits >= 0 ? bits / bits_in_char : -1;
+ return bits >= 0 ? (bits + bits_in_char - 1) / bits_in_char : -1;
}
static inline int bytes_to_bits(int bytes)
diff --git a/validation/initializer-entry-defined-twice.c b/validation/initializer-entry-defined-twice.c
index 968e3dd1..8a5bd3a9 100644
--- a/validation/initializer-entry-defined-twice.c
+++ b/validation/initializer-entry-defined-twice.c
@@ -41,6 +41,16 @@ static struct same_offset not_an_error = {
.field1 = { },
.field2 = 0
};
+
+/*
+ * _Bools generally take a whole byte, so ensure that we can initialize
+ * them without spewing a warning.
+ */
+static _Bool boolarray[3] = {
+ [0] = 1,
+ [1] = 1,
+};
+
/*
* check-name: Initializer entry defined twice
*