aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-29 17:00:26 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-30 03:43:24 +0200
commitf4a90f9a6f569904165d48464615bf60d188fba4 (patch)
tree5a353aa1a27c507f73382767d431125737489652
parent3c748099b5a79d74461c142248920316504c5cb0 (diff)
parent1a38b82ebc4f41d5cfb3ea69c0924bbb01ba1358 (diff)
downloadsparse-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.c4
-rw-r--r--validation/enum-sign-extend.c12
2 files changed, 13 insertions, 3 deletions
diff --git a/parse.c b/parse.c
index f291e247..b01c876e 100644
--- a/parse.c
+++ b/parse.c
@@ -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
+ */