Fix LLVM_REVERSE_ITERATION
authorChris Bieneman <chris.bieneman@me.com>
Mon, 20 Apr 2020 21:50:20 +0000 (16:50 -0500)
committerChris Bieneman <chris.bieneman@me.com>
Mon, 20 Apr 2020 22:30:31 +0000 (17:30 -0500)
A recent change (4e86e5eedc6), broke `LLVM_REVERSE_ITERATION` for DenseMaps by adding an assert. It is valid to de-reference and increment one step behind `End` when reverse iteration is enabled because `End` is actually the start of the pointer bucket.

llvm/include/llvm/ADT/DenseMap.h

index df4f020..60f32f7 100644 (file)
@@ -1200,16 +1200,20 @@ public:
 
   reference operator*() const {
     assert(isHandleInSync() && "invalid iterator access!");
-    assert(Ptr != End && "dereferencing end() iterator");
-    if (shouldReverseIterate<KeyT>())
+    if (shouldReverseIterate<KeyT>()) {
+      assert(Ptr != End[-1] && "dereferencing end() iterator");
       return Ptr[-1];
+    }
+    assert(Ptr != End && "dereferencing end() iterator");
     return *Ptr;
   }
   pointer operator->() const {
     assert(isHandleInSync() && "invalid iterator access!");
-    assert(Ptr != End && "dereferencing end() iterator");
-    if (shouldReverseIterate<KeyT>())
+    if (shouldReverseIterate<KeyT>()) {
+      assert(Ptr != End[-1] && "dereferencing end() iterator");
       return &(Ptr[-1]);
+    }
+    assert(Ptr != End && "dereferencing end() iterator");
     return Ptr;
   }
 
@@ -1230,12 +1234,13 @@ public:
 
   inline DenseMapIterator& operator++() {  // Preincrement
     assert(isHandleInSync() && "invalid iterator access!");
-    assert(Ptr != End && "incrementing end() iterator");
     if (shouldReverseIterate<KeyT>()) {
+      assert(Ptr != End[-1] && "dereferencing end() iterator");
       --Ptr;
       RetreatPastEmptyBuckets();
       return *this;
     }
+    assert(Ptr != End && "incrementing end() iterator");
     ++Ptr;
     AdvancePastEmptyBuckets();
     return *this;