aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-12-09 21:45:35 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-12-09 21:45:35 +0100
commit82dee2e25887f26df7126d6789a419eaf14beb8c (patch)
tree6d7d985710ab0f0199b23c4a4f420da0aecfff36
parentfaa80ad61505517b48ed0afc86f39fd3ad021b7d (diff)
parent38dfaa85aef4f1f02f114dffeda02c818d87fe06 (diff)
downloadsparse-82dee2e25887f26df7126d6789a419eaf14beb8c.tar.gz
Merge branch 'bitfield-size'
* improve diagnostic messages concerning bitfields
-rw-r--r--parse.c10
-rw-r--r--symbol.c10
-rw-r--r--validation/bitfield-sizes.c30
3 files changed, 40 insertions, 10 deletions
diff --git a/parse.c b/parse.c
index 6db3cba7..fb05253b 100644
--- a/parse.c
+++ b/parse.c
@@ -1946,12 +1946,9 @@ static struct token *handle_bitfield(struct token *token, struct decl_state *ctx
width = const_expression_value(expr);
bitfield->bit_size = width;
- if (width < 0 || width > INT_MAX) {
- sparse_error(token->pos, "invalid bitfield width, %lld.", width);
- width = -1;
- } else if (*ctx->ident && width == 0) {
- sparse_error(token->pos, "invalid named zero-width bitfield `%s'",
- show_ident(*ctx->ident));
+ if (width < 0 || width > INT_MAX || (*ctx->ident && width == 0)) {
+ sparse_error(token->pos, "bitfield '%s' has invalid width (%lld)",
+ show_ident(*ctx->ident), width);
width = -1;
} else if (*ctx->ident) {
struct symbol *base_type = bitfield->ctype.base_type;
@@ -1972,6 +1969,7 @@ static struct token *handle_bitfield(struct token *token, struct decl_state *ctx
}
bitfield->bit_size = width;
bitfield->endpos = token->pos;
+ bitfield->ident = *ctx->ident;
return token;
}
diff --git a/symbol.c b/symbol.c
index fb14b624..3655cbb7 100644
--- a/symbol.c
+++ b/symbol.c
@@ -254,13 +254,15 @@ static struct symbol * examine_array_type(struct symbol *sym)
static struct symbol *examine_bitfield_type(struct symbol *sym)
{
struct symbol *base_type = examine_base_type(sym);
- unsigned long bit_size, alignment, modifiers;
+ unsigned long alignment, modifiers;
if (!base_type)
return sym;
- bit_size = base_type->bit_size;
- if (sym->bit_size > bit_size)
- warning(sym->pos, "impossible field-width, %d, for this type", sym->bit_size);
+ if (sym->bit_size > base_type->bit_size) {
+ sparse_error(sym->pos, "bitfield '%s' is wider (%d) than its type (%s)",
+ show_ident(sym->ident), sym->bit_size, show_typename(base_type));
+ sym->bit_size = -1;
+ }
alignment = base_type->ctype.alignment;
if (!sym->ctype.alignment)
diff --git a/validation/bitfield-sizes.c b/validation/bitfield-sizes.c
new file mode 100644
index 00000000..9f76d074
--- /dev/null
+++ b/validation/bitfield-sizes.c
@@ -0,0 +1,30 @@
+struct a {
+ int a:31;
+ int b:32;
+ long c:63;
+ long d:64;
+ int x:33; // KO
+ long y:65; // KO
+};
+static struct a a;
+
+struct b {
+ int m1:-1; // KO
+ int x1:2147483648; // KO
+ int :0;
+ int a0:0; // KO
+};
+static struct b b;
+
+/*
+ * check-name: bitfield-sizes
+ * check-command: sparse -m64 $file
+ *
+ * check-error-start
+bitfield-sizes.c:12:18: error: bitfield 'm1' has invalid width (-1)
+bitfield-sizes.c:13:26: error: bitfield 'x1' has invalid width (2147483648)
+bitfield-sizes.c:15:17: error: bitfield 'a0' has invalid width (0)
+bitfield-sizes.c:6:15: error: bitfield 'x' is wider (33) than its type (int)
+bitfield-sizes.c:7:15: error: bitfield 'y' is wider (65) than its type (long)
+ * check-error-end
+ */