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
This commit is contained in:
Dale Johannesen 2010-11-19 00:48:58 +00:00
parent cb21d1c9fd
commit c81c7fe643

View File

@ -18,6 +18,7 @@
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/System/Host.h"
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
using namespace llvm; using namespace llvm;
@ -110,18 +111,32 @@ void FoldingSetNodeID::AddString(StringRef String) {
Pos = (Units + 1) * 4; Pos = (Units + 1) * 4;
} else { } else {
// Otherwise do it the hard way. // Otherwise do it the hard way.
for (Pos += 4; Pos <= Size; Pos += 4) { // To be compatible with above bulk transfer, we need to take endianness
unsigned V = ((unsigned char)String[Pos - 4] << 24) | // into account.
((unsigned char)String[Pos - 3] << 16) | if (sys::isBigEndianHost()) {
((unsigned char)String[Pos - 2] << 8) | for (Pos += 4; Pos <= Size; Pos += 4) {
(unsigned char)String[Pos - 1]; unsigned V = ((unsigned char)String[Pos - 4] << 24) |
Bits.push_back(V); ((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. // With the leftover bits.
unsigned V = 0; 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) { switch (Pos - Size) {
case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru. case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru.
case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru. case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru.