aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-08-06 00:07:49 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-08-06 18:30:44 +0200
commitc2a5bd264187f42564b7055bce4cf72a7985cbc5 (patch)
treeb055e335373510a6ff76e974727d44b433718113
parentf01f79df0512ef16dc1ae681edf75e6924a8cf2e (diff)
downloadsparse-c2a5bd264187f42564b7055bce4cf72a7985cbc5.tar.gz
shift-assign: restrict shift count to unsigned int
After the RHS of shift-assigns had been integer-promoted, both gcc & clang seems to restrict it to an unsigned int. This only make a difference when the shift count is negative and would it make it UB. Better to have the same generated code, so make the same here. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--evaluate.c5
-rw-r--r--validation/linear/shift-assign2.c1
2 files changed, 5 insertions, 1 deletions
diff --git a/evaluate.c b/evaluate.c
index 6d8ecd7f..a9adc72f 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1348,6 +1348,11 @@ static int evaluate_assign_op(struct expression *expr)
unrestrict(expr->right, sclass, &s);
source = integer_promotion(s);
expr->right = cast_to(expr->right, source);
+
+ // both gcc & clang seems to do this, so ...
+ if (target->bit_size > source->bit_size)
+ expr->right = cast_to(expr->right, &uint_ctype);
+
goto Cast;
} else if (!(sclass & TYPE_RESTRICT))
goto usual;
diff --git a/validation/linear/shift-assign2.c b/validation/linear/shift-assign2.c
index 30d74376..9990ac38 100644
--- a/validation/linear/shift-assign2.c
+++ b/validation/linear/shift-assign2.c
@@ -13,7 +13,6 @@ u64 u64s32(u64 a, s32 b) { a >>= b; return a; }
/*
* check-name: shift-assign2
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-start
s64s16: