From 99c67b31cb34f1821e5037bc79598306733a906a Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 1 Apr 2016 15:51:51 +0000 Subject: [PATCH] [ADT] Make StringMap's tombstone aligned. This avoids undefined behavior when casting pointers to it. Also make sure that we don't cast to a derived StringMapEntry before checking for tombstone, as that may have different alignment requirements. llvm-svn: 265145 --- llvm/include/llvm/ADT/StringMap.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h index ce80484..e593e51 100644 --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/PointerLikeTypeTraits.h" #include #include @@ -95,7 +96,9 @@ protected: public: static StringMapEntryBase *getTombstoneVal() { - return (StringMapEntryBase*)-1; + uintptr_t Val = static_cast(-1); + Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; + return reinterpret_cast(Val); } unsigned getNumBuckets() const { return NumBuckets; } @@ -260,14 +263,15 @@ public: NumItems = RHS.NumItems; NumTombstones = RHS.NumTombstones; for (unsigned I = 0, E = NumBuckets; I != E; ++I) { - MapEntryTy *Bucket = ((MapEntryTy**) RHS.TheTable)[I]; + StringMapEntryBase *Bucket = RHS.TheTable[I]; if (!Bucket || Bucket == getTombstoneVal()) { TheTable[I] = Bucket; continue; } - TheTable[I] = MapEntryTy::Create(Bucket->getKey(), Allocator, - Bucket->getValue()); + TheTable[I] = MapEntryTy::Create( + static_cast(Bucket)->getKey(), Allocator, + static_cast(Bucket)->getValue()); HashTable[I] = RHSHashTable[I]; } -- 2.7.4