Make sure ImmutableSet never inserts Tombstone/Entry into DenseMap.
authorAnna Zaks <ganna@apple.com>
Tue, 20 Mar 2012 22:56:27 +0000 (22:56 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 20 Mar 2012 22:56:27 +0000 (22:56 +0000)
ImmutAVLTree uses random unsigned values as keys into a DenseMap,
which could possibly happen to be the same value as the Tombstone or
Entry keys in the DenseMap.

Test case is hard to come up with. We randomly get failures on the
internal static analyzer bot, which most likely hits this issue
(hard to be 100% sure without the full stack).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153148 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/ImmutableSet.h

index 2926462fa81bd2bc4268c0d27a590f292049ae2b..89b164819d37412ef432f10902e6e4cc8a8f8d16 100644 (file)
@@ -347,7 +347,7 @@ public:
       if (prev)
         prev->next = next;
       else
-        factory->Cache[computeDigest()] = next;
+        factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
     }
     
     // We need to clear the mutability bit in case we are
@@ -429,6 +429,11 @@ protected:
   TreeTy*         getRight(TreeTy* T) const { return T->getRight(); }
   value_type_ref  getValue(TreeTy* T) const { return T->value; }
 
+  // Make sure the index is not the Tombstone or Entry key of the DenseMap.
+  static inline unsigned maskCacheIndex(unsigned I) {
+       return (I & ~0x02);
+  }
+
   unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
     unsigned hl = getHeight(L);
     unsigned hr = getHeight(R);
@@ -611,7 +616,7 @@ public:
     // Search the hashtable for another tree with the same digest, and
     // if find a collision compare those trees by their contents.
     unsigned digest = TNew->computeDigest();
-    TreeTy *&entry = Cache[digest];
+    TreeTy *&entry = Cache[maskCacheIndex(digest)];
     do {
       if (!entry)
         break;