diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-12-09 21:45:35 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-12-09 21:45:35 +0100 |
commit | 82dee2e25887f26df7126d6789a419eaf14beb8c (patch) | |
tree | 6d7d985710ab0f0199b23c4a4f420da0aecfff36 | |
parent | faa80ad61505517b48ed0afc86f39fd3ad021b7d (diff) | |
parent | 38dfaa85aef4f1f02f114dffeda02c818d87fe06 (diff) | |
download | sparse-82dee2e25887f26df7126d6789a419eaf14beb8c.tar.gz |
Merge branch 'bitfield-size'
* improve diagnostic messages concerning bitfields
-rw-r--r-- | parse.c | 10 | ||||
-rw-r--r-- | symbol.c | 10 | ||||
-rw-r--r-- | validation/bitfield-sizes.c | 30 |
3 files changed, 40 insertions, 10 deletions
@@ -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; } @@ -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 + */ |