[llvm] r249689 - Fix UBSan test error from r248897 about left shift of unsigned value.

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 8 06:14:59 PDT 2015


Author: tejohnson
Date: Thu Oct  8 08:14:59 2015
New Revision: 249689

URL: http://llvm.org/viewvc/llvm-project?rev=249689&view=rev
Log:
Fix UBSan test error from r248897 about left shift of unsigned value.

Fixed by masking off the upper bits that we are shifting off before
doing the left shift.

Modified:
    llvm/trunk/include/llvm/Support/Endian.h

Modified: llvm/trunk/include/llvm/Support/Endian.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Endian.h?rev=249689&r1=249688&r2=249689&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Endian.h (original)
+++ llvm/trunk/include/llvm/Support/Endian.h Thu Oct  8 08:14:59 2015
@@ -131,14 +131,22 @@ inline void writeAtBitAlignment(void *me
     // Mask off any existing bits in the upper part of the lower value that
     // we want to replace.
     val[0] &= (1 << startBit) - 1;
-    // Now shift in the new bits
-    val[0] |= value << startBit;
+    unsigned numBitsFirstVal = (sizeof(value_type) * 8) - startBit;
+    unsigned lowerVal = value;
+    if (startBit > 0) {
+      // Mask off the upper bits in the new value that are not going to go into
+      // the lower value. This avoids a left shift of a negative value, which
+      // is undefined behavior.
+      lowerVal &= ((1 << numBitsFirstVal) - 1);
+      // Now shift the new bits into place
+      lowerVal <<= startBit;
+    }
+    val[0] |= lowerVal;
 
     // Mask off any existing bits in the lower part of the upper value that
     // we want to replace.
     val[1] &= ~((1 << startBit) - 1);
     // Next shift the bits that go into the upper value into position.
-    unsigned numBitsFirstVal = (sizeof(value_type) * 8) - startBit;
     unsigned upperVal = value >> numBitsFirstVal;
     // Mask off upper bits after right shift in case of signed type.
     upperVal &= (1 << startBit) - 1;




More information about the llvm-commits mailing list