Fix another UBSan test error from r248897 and follow on fix r249689
[oota-llvm.git] / include / llvm / Support / Endian.h
index 7680240deac81f8fbde40491d8dcec395e0dcf73..b98ff5ede77398c2bb7777d19fd20033d68d6bf4 100644 (file)
@@ -78,6 +78,9 @@ inline void write(void *memory, value_type value) {
          sizeof(value_type));
 }
 
          sizeof(value_type));
 }
 
+template <typename value_type>
+using make_unsigned_t = typename std::make_unsigned<value_type>::type;
+
 /// Read a value of a particular endianness from memory, for a location
 /// that starts at the given bit offset within the first byte.
 template <typename value_type, endianness endian, std::size_t alignment>
 /// Read a value of a particular endianness from memory, for a location
 /// that starts at the given bit offset within the first byte.
 template <typename value_type, endianness endian, std::size_t alignment>
@@ -96,13 +99,15 @@ inline value_type readAtBitAlignment(const void *memory, uint64_t startBit) {
     val[1] = byte_swap<value_type, endian>(val[1]);
 
     // Shift bits from the lower value into place.
     val[1] = byte_swap<value_type, endian>(val[1]);
 
     // Shift bits from the lower value into place.
-    unsigned lowerVal = val[0] >> startBit;
+    make_unsigned_t<value_type> lowerVal = val[0] >> startBit;
     // Mask off upper bits after right shift in case of signed type.
     // Mask off upper bits after right shift in case of signed type.
-    unsigned numBitsFirstVal = (sizeof(value_type) * 8) - startBit;
-    lowerVal &= (1 << numBitsFirstVal) - 1;
+    make_unsigned_t<value_type> numBitsFirstVal =
+        (sizeof(value_type) * 8) - startBit;
+    lowerVal &= ((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1;
 
     // Get the bits from the upper value.
 
     // Get the bits from the upper value.
-    unsigned upperVal = val[1] & ((1 << startBit) - 1);
+    make_unsigned_t<value_type> upperVal =
+        val[1] & (((make_unsigned_t<value_type>)1 << startBit) - 1);
     // Shift them in to place.
     upperVal <<= numBitsFirstVal;
 
     // Shift them in to place.
     upperVal <<= numBitsFirstVal;
 
@@ -130,14 +135,15 @@ inline void writeAtBitAlignment(void *memory, value_type value,
 
     // Mask off any existing bits in the upper part of the lower value that
     // we want to replace.
 
     // Mask off any existing bits in the upper part of the lower value that
     // we want to replace.
-    val[0] &= (1 << startBit) - 1;
-    unsigned numBitsFirstVal = (sizeof(value_type) * 8) - startBit;
-    unsigned lowerVal = value;
+    val[0] &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
+    make_unsigned_t<value_type> numBitsFirstVal =
+        (sizeof(value_type) * 8) - startBit;
+    make_unsigned_t<value_type> 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.
     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);
+      lowerVal &= (((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1);
       // Now shift the new bits into place
       lowerVal <<= startBit;
     }
       // Now shift the new bits into place
       lowerVal <<= startBit;
     }
@@ -145,11 +151,11 @@ inline void writeAtBitAlignment(void *memory, value_type value,
 
     // Mask off any existing bits in the lower part of the upper value that
     // we want to replace.
 
     // Mask off any existing bits in the lower part of the upper value that
     // we want to replace.
-    val[1] &= ~((1 << startBit) - 1);
+    val[1] &= ~(((make_unsigned_t<value_type>)1 << startBit) - 1);
     // Next shift the bits that go into the upper value into position.
     // Next shift the bits that go into the upper value into position.
-    unsigned upperVal = value >> numBitsFirstVal;
+    make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal;
     // Mask off upper bits after right shift in case of signed type.
     // Mask off upper bits after right shift in case of signed type.
-    upperVal &= (1 << startBit) - 1;
+    upperVal &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
     val[1] |= upperVal;
 
     // Finally, rewrite values.
     val[1] |= upperVal;
 
     // Finally, rewrite values.