diff options
author | Dale Johannesen <dalej@apple.com> | 2010-11-19 00:48:58 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2010-11-19 00:48:58 +0000 |
commit | c81c7fe643e91bc6ed817bf5e17379b74e161b91 (patch) | |
tree | fe55619b9715c5e68b78b3a797c2e15b51daea3a /lib/Support | |
parent | cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0 (diff) | |
download | external_llvm-c81c7fe643e91bc6ed817bf5e17379b74e161b91.zip external_llvm-c81c7fe643e91bc6ed817bf5e17379b74e161b91.tar.gz external_llvm-c81c7fe643e91bc6ed817bf5e17379b74e161b91.tar.bz2 |
Aligned and unaligned copies of the same string
were not hashing to the same value. Analysis
and patch by Frits van Bommel!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119770 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/FoldingSet.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp index 29b5952..11a1de4 100644 --- a/lib/Support/FoldingSet.cpp +++ b/lib/Support/FoldingSet.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include "llvm/System/Host.h" #include <cassert> #include <cstring> using namespace llvm; @@ -110,18 +111,32 @@ void FoldingSetNodeID::AddString(StringRef String) { Pos = (Units + 1) * 4; } else { // Otherwise do it the hard way. - for (Pos += 4; Pos <= Size; Pos += 4) { - unsigned V = ((unsigned char)String[Pos - 4] << 24) | - ((unsigned char)String[Pos - 3] << 16) | - ((unsigned char)String[Pos - 2] << 8) | - (unsigned char)String[Pos - 1]; - Bits.push_back(V); + // To be compatible with above bulk transfer, we need to take endianness + // into account. + if (sys::isBigEndianHost()) { + for (Pos += 4; Pos <= Size; Pos += 4) { + unsigned V = ((unsigned char)String[Pos - 4] << 24) | + ((unsigned char)String[Pos - 3] << 16) | + ((unsigned char)String[Pos - 2] << 8) | + (unsigned char)String[Pos - 1]; + Bits.push_back(V); + } + } else { + assert(sys::isLittleEndianHost() && "Unexpected host endianness"); + for (Pos += 4; Pos <= Size; Pos += 4) { + unsigned V = ((unsigned char)String[Pos - 1] << 24) | + ((unsigned char)String[Pos - 2] << 16) | + ((unsigned char)String[Pos - 3] << 8) | + (unsigned char)String[Pos - 4]; + Bits.push_back(V); + } } } // With the leftover bits. unsigned V = 0; - // Pos will have overshot size by 4 - #bytes left over. + // Pos will have overshot size by 4 - #bytes left over. + // No need to take endianness into account here - this is always executed. switch (Pos - Size) { case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru. case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru. |