diff options
author | Alan Modra <amodra@gmail.com> | 2020-08-26 14:55:39 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-08-26 23:23:44 +0930 |
commit | b2f386b99caeab72eae26ca5bc9024421de145d9 (patch) | |
tree | 1ab995f747d359f51372dd57d166dbdea89d64d1 /gas/expr.c | |
parent | aaf9875ef9252ec42bafac076421cc5ff22965ad (diff) | |
download | gdb-b2f386b99caeab72eae26ca5bc9024421de145d9.zip gdb-b2f386b99caeab72eae26ca5bc9024421de145d9.tar.gz gdb-b2f386b99caeab72eae26ca5bc9024421de145d9.tar.bz2 |
PR26447 UBSAN: expr.c:1936 left shift of negative value
PR 26447
* expr.c (expr <O_left_shift>): Do an unsigned shift.
Diffstat (limited to 'gas/expr.c')
-rw-r--r-- | gas/expr.c | 19 |
1 files changed, 14 insertions, 5 deletions
@@ -1933,12 +1933,21 @@ expr (int rankarg, /* Larger # is higher rank. */ case O_multiply: resultP->X_add_number *= v; break; case O_divide: resultP->X_add_number /= v; break; case O_modulus: resultP->X_add_number %= v; break; - case O_left_shift: resultP->X_add_number <<= v; break; + case O_left_shift: + /* We always use unsigned shifts. According to the ISO + C standard, left shift of a signed type having a + negative value is undefined behaviour, and right + shift of a signed type having negative value is + implementation defined. Left shift of a signed type + when the result overflows is also undefined + behaviour. So don't trigger ubsan warnings or rely + on characteristics of the compiler. */ + resultP->X_add_number + = (valueT) resultP->X_add_number << (valueT) v; + break; case O_right_shift: - /* We always use unsigned shifts, to avoid relying on - characteristics of the compiler used to compile gas. */ - resultP->X_add_number = - (offsetT) ((valueT) resultP->X_add_number >> (valueT) v); + resultP->X_add_number + = (valueT) resultP->X_add_number >> (valueT) v; break; case O_bit_inclusive_or: resultP->X_add_number |= v; break; case O_bit_or_not: resultP->X_add_number |= ~v; break; |