From dd7476cff001cc6970057f4557dbc370453c051f Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Thu, 8 Oct 2015 13:14:59 +0000 Subject: [PATCH] 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 --- include/llvm/Support/Endian.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) 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; -- 2.34.1