diff options
author | Alan Modra <amodra@gmail.com> | 2025-04-16 07:12:46 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-04-18 18:36:39 +0930 |
commit | f04146a96be59b603ca36eac0bb4f244bc29c7af (patch) | |
tree | b5e3bc49b3f60ae536908db0755d853f1e9c1856 | |
parent | 637e0dfb04a6d3b0453c88f696ce053d978140e6 (diff) | |
download | binutils-f04146a96be59b603ca36eac0bb4f244bc29c7af.zip binutils-f04146a96be59b603ca36eac0bb4f244bc29c7af.tar.gz binutils-f04146a96be59b603ca36eac0bb4f244bc29c7af.tar.bz2 |
loongarch gas resolving constant expressions
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.
-rw-r--r-- | gas/config/loongarch-parse.y | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y index 97055fe..b75040c 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; |