[libcxx-commits] [libcxx] [libc++] Optimize __hash_table::erase(iterator, iterator) (PR #152471)

Aiden Grossman via libcxx-commits libcxx-commits at lists.llvm.org
Mon Sep 15 17:05:43 PDT 2025


boomanaiden154 wrote:

@philnik777 I'm seeing a regression under ASan (use after free after this patch). The following code snippet throws a use-after-free for me in final call to `equal_range`:
```c++
#include <unordered_map>
#include <utility>

typedef std::unordered_multimap<void*, void*> mapType;
typedef std::pair<mapType::iterator, mapType::iterator> erasePair;

int main(int argc, char** argv) {
  mapType map;
  map.insert(mapType::value_type((void*)0x7e4df9645ab8, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9649868, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9649cf0, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df964a200, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df964c700, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df964cad8, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df964cda0, (void*)5));
  // equal_range: 0x7e4df9645ab8
  erasePair pair1 = map.equal_range((void*)0x7e4df9645ab8);
  map.erase(pair1.first, pair1.second);
  map.insert(mapType::value_type((void*)0x7e4df9645f60, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df96505a8, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df964c700, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df964c700, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9649cf0, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9650078, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9652258, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9652638, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df96509d0, (void*)5));
  // equal_range: 0x7e4df9649868
  erasePair pair2 = map.equal_range((void*)0x7e4df9649868);
  map.erase(pair2.first, pair2.second);
  map.insert(mapType::value_type((void*)0x7e4df964def0, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df96598b0, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df965a160, (void*)5));
  // equal_range: 0x7e4df96505a8
  erasePair pair3 = map.equal_range((void*)0x7e4df96505a8);
  map.erase(pair3.first, pair3.second);
  map.insert(mapType::value_type((void*)0x7e4df9653810, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df9666340, (void*)5));
  // equal_range: 0x7e4df964c700
  erasePair pair4 = map.equal_range((void*)0x7e4df964c700);
  map.erase(pair4.first, pair4.second);
  map.insert(mapType::value_type((void*)0x7e4df965a880, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df965a880, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df965a880, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df96680c8, (void*)5));
  // equal_range: 0x7e4df9652258
  erasePair pair5 = map.equal_range((void*)0x7e4df9652258);
  map.erase(pair5.first, pair5.second);
  map.insert(mapType::value_type((void*)0x7e4df9666d98, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df966c608, (void*)5));
  map.insert(mapType::value_type((void*)0x7e4df966c9e0, (void*)5));
  erasePair test_pair = map.equal_range((void*)0x7e4df9649cf0);
  if (test_pair.first == test_pair.second) {
    return 1;
  }
  return 0;
}
```

Are you able to take a look?

https://github.com/llvm/llvm-project/pull/152471


More information about the libcxx-commits mailing list