aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-21 15:01:12 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-07-23 01:40:31 +0200
commitefdefb100d086aaabf20d475c3d1a65cbceeb534 (patch)
tree364d3bb7dd1a389d555dbd24159421e91b44add4
parent4b6723ef4d91fc0859d84208c1896d14477cec1e (diff)
downloadsparse-dev-efdefb100d086aaabf20d475c3d1a65cbceeb534.tar.gz
big-shift: fix evaluation of shift-assign
The right hand side of a shift operation must be of integer type and do the integer promotion and nothing else. More precisely, the RHS and the LFS type doesn't need to match. This is correctly done for plain shifts but not for shift-assigns where the full usual conversion is wrongly applied. Fix this by special casing shifts in evaluate_assign_op() and just apply the integer promotion on the RHS, like done for shifts in evaluate_binop(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--evaluate.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/evaluate.c b/evaluate.c
index 194b9721..7ab7db81 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1325,6 +1325,11 @@ static int evaluate_assign_op(struct expression *expr)
goto Cast;
if (!restricted_value(expr->right, t))
return 1;
+ } else if (op == SPECIAL_SHR_ASSIGN || op == SPECIAL_SHL_ASSIGN) {
+ // shifts do integer promotions, but that's it.
+ unrestrict(expr->right, sclass, &s);
+ target = integer_promotion(s);
+ goto Cast;
} else if (!(sclass & TYPE_RESTRICT))
goto usual;
/* source and target would better be identical restricted */