[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