From: Teresa Johnson Date: Thu, 8 Oct 2015 13:14:59 +0000 (+0000) Subject: Fix UBSan test error from r248897 about left shift of unsigned value. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dd7476cff001cc6970057f4557dbc370453c051f;p=oota-llvm.git 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249689 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h index b72200e7ba4..7680240deac 100644 --- a/include/llvm/Support/Endian.h +++ b/include/llvm/Support/Endian.h @@ -131,14 +131,22 @@ 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. 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;