diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-09-29 17:00:26 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-09-30 03:43:24 +0200 |
commit | f4a90f9a6f569904165d48464615bf60d188fba4 (patch) | |
tree | 5a353aa1a27c507f73382767d431125737489652 | |
parent | 3c748099b5a79d74461c142248920316504c5cb0 (diff) | |
parent | 1a38b82ebc4f41d5cfb3ea69c0924bbb01ba1358 (diff) | |
download | sparse-f4a90f9a6f569904165d48464615bf60d188fba4.tar.gz |
Merge branch 'fix-enum-sign-extend' into tip
In a declaration like:
enum {
a = 0x80000000,
b = -1,
}
the underlying type should be long and b's value should be
0xffffffffffffffff (on a 64-bit machine) but is 0xffffffff.
The fix is in cast_enum_list() to change the the type of the
enumeration after casting its value and not before since
the original type is needed for the cast.
Fixes: 604a148a73af ("enum: fix cast_enum_list()")
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | parse.c | 4 | ||||
-rw-r--r-- | validation/enum-sign-extend.c | 12 |
2 files changed, 13 insertions, 3 deletions
@@ -897,10 +897,8 @@ static void cast_enum_list(struct symbol_list *list, struct symbol *base_type) expr->ctype = &int_ctype; continue; } - expr->ctype = base_type; - if (ctype->bit_size == base_type->bit_size) - continue; cast_value(expr, base_type, expr, ctype); + expr->ctype = base_type; } END_FOR_EACH_PTR(sym); } diff --git a/validation/enum-sign-extend.c b/validation/enum-sign-extend.c new file mode 100644 index 00000000..d852c934 --- /dev/null +++ b/validation/enum-sign-extend.c @@ -0,0 +1,12 @@ +enum num { + a = 0x80000000, + b = -1, +}; + +_Static_assert([typeof(b)] == [long], "type"); +_Static_assert(b == -1L, "value"); + +/* + * check-name: enum-sign-extend + * check-command: sparse -m64 $file + */ |