PR26447 UBSAN: expr.c:1936 left shift of negative value
authorAlan Modra <amodra@gmail.com>
Wed, 26 Aug 2020 05:25:39 +0000 (14:55 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 26 Aug 2020 13:53:44 +0000 (23:23 +0930)
PR 26447
* expr.c (expr <O_left_shift>): Do an unsigned shift.

gas/ChangeLog
gas/expr.c

index 4e367a4dade743075a219b24b822a134ae77a104..cfa087ed6ac9c6ceeb7680df185b7273c6f7278f 100644 (file)
@@ -1,3 +1,10 @@
+2020-08-26  Alan Modra  <amodra@gmail.com>
+
+       PR 26447
+       * expr.c (expr <O_left_shift>): Do an unsigned shift.
+
+2020-08-25  Alan Modra  <amodra@gmail.com>
+
 2020-08-26  David Faust  <david.faust@oracle.com>
 
        * config/tc-bpf.c: Add option -mxbpf to select xbpf isa.
@@ -9,7 +16,7 @@
 
 2020-08-25  Alan Modra  <amodra@gmail.com>
 
-       PR26501
+       PR 26501
        * gas/config/tc-tic54x.c (tic54x_undefined_symbol): Properly treat
        misc_symbol_hash entries without values.
 
index 23a6a003b9c82ac9a3ed42682c0e2bf845564be3..7c002c0d964990c193c6e254abc085ff47bb1242 100644 (file)
@@ -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;