aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2007-09-11 03:48:08 +0000
committerOwen Anderson <resistor@mac.com>2007-09-11 03:48:08 +0000
commit0370ace4915d0c1cc31aa6cd8f3da0bdfed1855f (patch)
tree05a4515eb06f716ef1148d6c5dd7ce144129c8dd /include
parent11656fa702ab9c90312d6c3b16cb06d8f60a882a (diff)
downloadexternal_llvm-0370ace4915d0c1cc31aa6cd8f3da0bdfed1855f.zip
external_llvm-0370ace4915d0c1cc31aa6cd8f3da0bdfed1855f.tar.gz
external_llvm-0370ace4915d0c1cc31aa6cd8f3da0bdfed1855f.tar.bz2
Fix non-deterministic behavior in the DenseMap copy constructor.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41831 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/ADT/DenseMap.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 492dd45..fe91240 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -181,7 +181,7 @@ public:
private:
void CopyFrom(const DenseMap& other) {
- if (NumEntries != 0) {
+ if (NumBuckets != 0 && !KeyInfoT::isPod()) {
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
if (P->first != EmptyKey && P->first != TombstoneKey)
@@ -197,8 +197,14 @@ private:
delete[] reinterpret_cast<char*>(Buckets);
Buckets = reinterpret_cast<BucketT*>(new char[sizeof(BucketT) *
other.NumBuckets]);
- memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
+ if (KeyInfoT::isPod())
+ memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT));
+ else
+ for (size_t i = 0; i < other.NumBuckets; ++i) {
+ new (Buckets[i].first) KeyT(other.Buckets[i].first);
+ new (Buckets[i].second) ValueT(other.Buckets[i].second);
+ }
NumBuckets = other.NumBuckets;
}