loongarch gas resolving constant expressions
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
Commit Message
The test added in commit 4fe96ddaf614 results in an asan complaint:
loongarch-parse.y:225:16: runtime error: left shift of negative value -1
To avoid the complaint, perform left shifts as unsigned (which gives
the same result on 2's complement machines). Do the same for
addition, subtraction and multiplication. Furthermore, warn on
divide/modulus by zero.
OK?
Comments
On 4/16/25 1:14 PM, Alan Modra wrote:
> The test added in commit 4fe96ddaf614 results in an asan complaint:
> loongarch-parse.y:225:16: runtime error: left shift of negative value -1
> To avoid the complaint, perform left shifts as unsigned (which gives
> the same result on 2's complement machines). Do the same for
> addition, subtraction and multiplication. Furthermore, warn on
> divide/modulus by zero.
>
> OK?
We think it's OK. Thanks.
> diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
> index 97055fe42c3..b75040c14b1 100644
> --- a/gas/config/loongarch-parse.y
> +++ b/gas/config/loongarch-parse.y
> @@ -207,29 +207,41 @@ emit_bin (int op)
> switch (op)
> {
> case '*':
> - opr1 = opr1 * opr2;
> + opr1 = (valueT) opr1 * (valueT) opr2;
> break;
> case '/':
> - opr1 = opr1 / opr2;
> + if (opr2 == 0)
> + {
> + as_warn (_("Divide by zero!"));
> + opr1 = 0;
> + }
> + else
> + opr1 = opr1 / opr2;
> break;
> case '%':
> - opr1 = opr1 % opr2;
> + if (opr2 == 0)
> + {
> + as_warn (_("Divide by zero!"));
> + opr1 = 0;
> + }
> + else
> + opr1 = opr1 % opr2;
> break;
> case '+':
> - opr1 = opr1 + opr2;
> + opr1 = (valueT) opr1 + (valueT) opr2;
> break;
> case '-':
> - opr1 = opr1 - opr2;
> + opr1 = (valueT) opr1 - (valueT) opr2;
> break;
> case LEFT_OP:
> - opr1 = opr1 << opr2;
> + opr1 = (valueT) opr1 << opr2;
> break;
> case RIGHT_OP:
> if (opr1 < 0)
> - as_warn(_("Right shift of negative numbers may be changed "
> - "from arithmetic right shift to logical right shift!"));
> - /* Algorithm right shift. */
> - opr1 = (offsetT)opr1 >> (offsetT)opr2;
> + as_warn (_("Right shift of negative numbers may be changed "
> + "from arithmetic right shift to logical right shift!"));
> + /* Arithmetic right shift. */
> + opr1 = opr1 >> opr2;
> break;
> case '<':
> opr1 = opr1 < opr2;
>
@@ -207,29 +207,41 @@ emit_bin (int op)
switch (op)
{
case '*':
- opr1 = opr1 * opr2;
+ opr1 = (valueT) opr1 * (valueT) opr2;
break;
case '/':
- opr1 = opr1 / opr2;
+ if (opr2 == 0)
+ {
+ as_warn (_("Divide by zero!"));
+ opr1 = 0;
+ }
+ else
+ opr1 = opr1 / opr2;
break;
case '%':
- opr1 = opr1 % opr2;
+ if (opr2 == 0)
+ {
+ as_warn (_("Divide by zero!"));
+ opr1 = 0;
+ }
+ else
+ opr1 = opr1 % opr2;
break;
case '+':
- opr1 = opr1 + opr2;
+ opr1 = (valueT) opr1 + (valueT) opr2;
break;
case '-':
- opr1 = opr1 - opr2;
+ opr1 = (valueT) opr1 - (valueT) opr2;
break;
case LEFT_OP:
- opr1 = opr1 << opr2;
+ opr1 = (valueT) opr1 << opr2;
break;
case RIGHT_OP:
if (opr1 < 0)
- as_warn(_("Right shift of negative numbers may be changed "
- "from arithmetic right shift to logical right shift!"));
- /* Algorithm right shift. */
- opr1 = (offsetT)opr1 >> (offsetT)opr2;
+ as_warn (_("Right shift of negative numbers may be changed "
+ "from arithmetic right shift to logical right shift!"));
+ /* Arithmetic right shift. */
+ opr1 = opr1 >> opr2;
break;
case '<':
opr1 = opr1 < opr2;