* [PATCH 0/4] fix usual conversion of integers
@ 2020-10-05 23:03 Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 1/4] add builtin type pointer to bool: bool_ptr_ctype Luc Van Oostenryck
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-10-05 23:03 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
The current implementation of the usual conversion doesn't handle
correctly the case of 'long' + 'unsigned int' on a 32-bit arch.
The resulting type is 'unsigned int' instead of 'unsigned long'.
Fix this by following closely the C99's wording.
This now gives the expected result for C89 & C99 on 32 & 64-bit archs
(as tested with the GCC testsuite).
Luc Van Oostenryck (4):
add builtin type pointer to bool: bool_ptr_ctype
fix prototype of __sync_bool_compare_and_swap()
fix evaluation of pointer to bool conversions
fix usual conversion of integers
builtin.c | 2 +-
evaluate.c | 67 ++++++++++++++++--------------
symbol.c | 2 +
symbol.h | 1 +
validation/linear/bool-cast-lp32.c | 1 -
5 files changed, 40 insertions(+), 33 deletions(-)
--
2.28.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] add builtin type pointer to bool: bool_ptr_ctype
2020-10-05 23:03 [PATCH 0/4] fix usual conversion of integers Luc Van Oostenryck
@ 2020-10-05 23:03 ` Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 2/4] fix prototype of __sync_bool_compare_and_swap() Luc Van Oostenryck
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-10-05 23:03 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
This builtin type is needed for __sync_bool_compare_and_swap()'s
prototype.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
symbol.c | 2 ++
symbol.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/symbol.c b/symbol.c
index 7f0c85580f06..d91fd296dd32 100644
--- a/symbol.c
+++ b/symbol.c
@@ -782,6 +782,7 @@ struct symbol bool_ctype, void_ctype, type_ctype,
incomplete_ctype, label_ctype, bad_ctype,
null_ctype;
struct symbol autotype_ctype;
+struct symbol bool_ptr_ctype;
struct symbol int_ptr_ctype, uint_ptr_ctype;
struct symbol long_ptr_ctype, ulong_ptr_ctype;
struct symbol llong_ptr_ctype, ullong_ptr_ctype;
@@ -876,6 +877,7 @@ static const struct ctype_declare {
{ &null_ctype, T_PTR(&void_ctype) },
{ &label_ctype, T_PTR(&void_ctype) },
{ &lazy_ptr_ctype, T_PTR(&void_ctype) },
+ { &bool_ptr_ctype, T_PTR(&bool_ctype) },
{ &int_ptr_ctype, T_PTR(&int_ctype) },
{ &uint_ptr_ctype, T_PTR(&uint_ctype) },
{ &long_ptr_ctype, T_PTR(&long_ctype) },
diff --git a/symbol.h b/symbol.h
index a3ed95678ee5..47550e032589 100644
--- a/symbol.h
+++ b/symbol.h
@@ -298,6 +298,7 @@ extern struct symbol bool_ctype, void_ctype, type_ctype,
incomplete_ctype, label_ctype, bad_ctype,
null_ctype;
extern struct symbol autotype_ctype;
+extern struct symbol bool_ptr_ctype;
extern struct symbol int_ptr_ctype, uint_ptr_ctype;
extern struct symbol long_ptr_ctype, ulong_ptr_ctype;
extern struct symbol llong_ptr_ctype, ullong_ptr_ctype;
--
2.28.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/4] fix prototype of __sync_bool_compare_and_swap()
2020-10-05 23:03 [PATCH 0/4] fix usual conversion of integers Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 1/4] add builtin type pointer to bool: bool_ptr_ctype Luc Van Oostenryck
@ 2020-10-05 23:03 ` Luc Van Oostenryck
2020-10-05 23:04 ` [PATCH 3/4] fix evaluation of pointer to bool conversions Luc Van Oostenryck
2020-10-05 23:04 ` [PATCH 4/4] fix usual conversion of integers Luc Van Oostenryck
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-10-05 23:03 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
The prototype was incomplete and typechecking failed after
some changes in the usual conversions.
So, add the full prototype.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
builtin.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/builtin.c b/builtin.c
index 26b612dc401b..b134754b5831 100644
--- a/builtin.c
+++ b/builtin.c
@@ -607,7 +607,7 @@ static const struct builtin_fn builtins_common[] = {
{ "__sync_add_and_fetch", &int_ctype, 1, { &ptr_ctype }},
{ "__sync_and_and_fetch", &int_ctype, 1, { &ptr_ctype }},
- { "__sync_bool_compare_and_swap", &bool_ctype, 1, { &ptr_ctype }, .op = &sync_compare_and_swap_op},
+ { "__sync_bool_compare_and_swap", &bool_ctype, 1, { &bool_ptr_ctype, &bool_ctype, &bool_ctype }, .op = &sync_compare_and_swap_op},
{ "__sync_fetch_and_add", &int_ctype, 1, { &ptr_ctype }},
{ "__sync_fetch_and_and", &int_ctype, 1, { &ptr_ctype }},
{ "__sync_fetch_and_nand", &int_ctype, 1, { &ptr_ctype }},
--
2.28.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] fix evaluation of pointer to bool conversions
2020-10-05 23:03 [PATCH 0/4] fix usual conversion of integers Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 1/4] add builtin type pointer to bool: bool_ptr_ctype Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 2/4] fix prototype of __sync_bool_compare_and_swap() Luc Van Oostenryck
@ 2020-10-05 23:04 ` Luc Van Oostenryck
2020-10-05 23:04 ` [PATCH 4/4] fix usual conversion of integers Luc Van Oostenryck
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-10-05 23:04 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
The pointer to bool conversion used an indirect intermediate
conversion to an int because the pointer was compared to 0
and not to a null pointer. The final result is the same
but the intermediate conversion generated an unneeded OP_PTRTOU
instruction which made fail some tests.
Fix this by directly comparing to a null pointer of the same
type as the type to convert.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
evaluate.c | 2 ++
validation/linear/bool-cast-lp32.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/evaluate.c b/evaluate.c
index c1ef348a475e..2f3dc06f8ccb 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -2883,6 +2883,8 @@ static struct symbol *cast_to_bool(struct expression *expr)
return NULL;
zero = alloc_const_expression(expr->pos, 0);
+ if (oclass & TYPE_PTR)
+ zero->ctype = otype;
expr->op = SPECIAL_NOTEQUAL;
ctype = usual_conversions(expr->op, old, zero,
oclass, TYPE_NUM, otype, zero->ctype);
diff --git a/validation/linear/bool-cast-lp32.c b/validation/linear/bool-cast-lp32.c
index 44a650f41e7f..7aab31dd34bf 100644
--- a/validation/linear/bool-cast-lp32.c
+++ b/validation/linear/bool-cast-lp32.c
@@ -12,7 +12,6 @@ static _Bool ffun_e(void) { return (_Bool)ffun; }
/*
* check-name: bool-cast-pointer
* check-command: test-linearize -m32 -fdump-ir $file
- * check-known-to-fail
*
* check-output-ignore
* check-output-excludes: ptrtu\\.
--
2.28.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/4] fix usual conversion of integers
2020-10-05 23:03 [PATCH 0/4] fix usual conversion of integers Luc Van Oostenryck
` (2 preceding siblings ...)
2020-10-05 23:04 ` [PATCH 3/4] fix evaluation of pointer to bool conversions Luc Van Oostenryck
@ 2020-10-05 23:04 ` Luc Van Oostenryck
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-10-05 23:04 UTC (permalink / raw)
To: linux-sparse; +Cc: Luc Van Oostenryck
The current implementation of the usual conversion doesn't handle
correctly the case of 'long' + 'unsigned int' on a 32-bit arch.
The resulting type is 'unsigned int' instead of 'unsigned long'.
Fix this by following closely the C99's wording.
This now gives the expected result for C89 & C99 on 32 & 64-bit archs
(as tested with the GCC testsuite).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
evaluate.c | 65 ++++++++++++++++++++++++++++--------------------------
1 file changed, 34 insertions(+), 31 deletions(-)
diff --git a/evaluate.c b/evaluate.c
index 2f3dc06f8ccb..9106aa340649 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -164,49 +164,52 @@ static inline struct symbol *integer_promotion(struct symbol *type)
}
/*
- * integer part of usual arithmetic conversions:
- * integer promotions are applied
- * if left and right are identical, we are done
- * if signedness is the same, convert one with lower rank
- * unless unsigned argument has rank lower than signed one, convert the
- * signed one.
- * if signed argument is bigger than unsigned one, convert the unsigned.
- * otherwise, convert signed.
- *
- * Leaving aside the integer promotions, that is equivalent to
- * if identical, don't convert
- * if left is bigger than right, convert right
- * if right is bigger than left, convert right
- * otherwise, if signedness is the same, convert one with lower rank
- * otherwise convert the signed one.
+ * After integer promotons:
+ * If both types are the same
+ * -> no conversion needed
+ * If the types have the same signedness (their rank must be different)
+ * -> convert to the type of the highest rank
+ * If rank(unsigned type) >= rank(signed type)
+ * -> convert to the unsigned type
+ * If size(signed type) > size(unsigned type)
+ * -> convert to the signed type
+ * Otherwise
+ * -> convert to the unsigned type corresponding to the signed type.
*/
static struct symbol *bigger_int_type(struct symbol *left, struct symbol *right)
{
+ static struct symbol *unsigned_types[] = {
+ [0] = &uint_ctype,
+ [1] = &ulong_ctype,
+ [2] = &ullong_ctype,
+ [3] = &uint128_ctype,
+ };
unsigned long lmod, rmod;
+ struct symbol *stype, *utype;
left = integer_promotion(left);
right = integer_promotion(right);
if (left == right)
- goto left;
-
- if (left->bit_size > right->bit_size)
- goto left;
-
- if (right->bit_size > left->bit_size)
- goto right;
+ return left;
lmod = left->ctype.modifiers;
rmod = right->ctype.modifiers;
- if ((lmod ^ rmod) & MOD_UNSIGNED) {
- if (lmod & MOD_UNSIGNED)
- goto left;
- } else if (left->rank > right->rank)
- goto left;
-right:
- left = right;
-left:
- return left;
+ if (((lmod ^ rmod) & MOD_UNSIGNED) == 0)
+ return (left->rank > right->rank) ? left : right;
+ if (lmod & MOD_UNSIGNED) {
+ utype = left;
+ stype = right;
+ } else {
+ stype = left;
+ utype = right;
+ }
+ if (utype->rank >= stype->rank)
+ return utype;
+ if (stype->bit_size > utype->bit_size)
+ return stype;
+ utype = unsigned_types[stype->rank];
+ return utype;
}
static int same_cast_type(struct symbol *orig, struct symbol *new)
--
2.28.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-10-05 23:04 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-05 23:03 [PATCH 0/4] fix usual conversion of integers Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 1/4] add builtin type pointer to bool: bool_ptr_ctype Luc Van Oostenryck
2020-10-05 23:03 ` [PATCH 2/4] fix prototype of __sync_bool_compare_and_swap() Luc Van Oostenryck
2020-10-05 23:04 ` [PATCH 3/4] fix evaluation of pointer to bool conversions Luc Van Oostenryck
2020-10-05 23:04 ` [PATCH 4/4] fix usual conversion of integers Luc Van Oostenryck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).