diff options
author | 2023-03-02 10:03:38 -0800 | |
---|---|---|
committer | 2023-03-02 10:04:18 -0800 | |
commit | d51d3cf3feacf836f1acfe6c97c10978077599ab (patch) | |
tree | 66375048493b39def4527ae286a929cf0521d29f /absl/container/internal/raw_hash_set_test.cc | |
parent | 4ae8771a314abe8b0e85cee3be3ead30451c63e7 (diff) |
Use multiple empty generations so that we can detect when iterators from different empty hashtables are compared.
PiperOrigin-RevId: 513568915
Change-Id: I3f387d0bae0e86749dff540e4fdd5037304ac975
Diffstat (limited to 'absl/container/internal/raw_hash_set_test.cc')
-rw-r--r-- | absl/container/internal/raw_hash_set_test.cc | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index c13b6757..c46a5939 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -2309,6 +2309,7 @@ TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) { } // ptr will become invalidated on rehash. const int64_t* ptr = &*it; + (void)ptr; // erase decreases size but does not decrease reserved growth so the next // insertion still invalidates iterators. @@ -2319,8 +2320,9 @@ TEST(Iterator, InvalidUseWithReserveCrashesWithSanitizers) { EXPECT_DEATH_IF_SUPPORTED(*it, kInvalidIteratorDeathMessage); EXPECT_DEATH_IF_SUPPORTED(void(it == t.begin()), kInvalidIteratorDeathMessage); - EXPECT_DEATH_IF_SUPPORTED(std::cout << *ptr, - "heap-use-after-free|use-of-uninitialized-value"); +#ifdef ABSL_HAVE_ADDRESS_SANITIZER + EXPECT_DEATH_IF_SUPPORTED(std::cout << *ptr, "heap-use-after-free"); +#endif } TEST(Table, ReservedGrowthUpdatesWhenTableDoesntGrow) { @@ -2338,6 +2340,22 @@ TEST(Table, ReservedGrowthUpdatesWhenTableDoesntGrow) { EXPECT_EQ(*it, 0); } +TEST(Table, GenerationInfoResetsOnClear) { + if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled."; + if (kMsvc) GTEST_SKIP() << "MSVC doesn't support | in regexp."; + + IntTable t; + for (int i = 0; i < 1000; ++i) t.insert(i); + t.reserve(t.size() + 100); + + t.clear(); + + t.insert(0); + auto it = t.begin(); + t.insert(1); + EXPECT_DEATH_IF_SUPPORTED(*it, kInvalidIteratorDeathMessage); +} + TEST(Table, InvalidReferenceUseCrashesWithSanitizers) { if (!SwisstableGenerationsEnabled()) GTEST_SKIP() << "Generations disabled."; #ifdef ABSL_HAVE_MEMORY_SANITIZER @@ -2362,11 +2380,13 @@ TEST(Iterator, InvalidComparisonDifferentTables) { IntTable t1, t2; IntTable::iterator default_constructed_iter; - // TODO(b/254649633): Currently, we can't detect when end iterators from - // different empty tables are compared. If we allocate generations separately - // from control bytes, then we could do so. - // EXPECT_DEATH_IF_SUPPORTED(void(t1.end() == t2.end()), - // "Invalid iterator comparison.*empty hashtable"); + // We randomly use one of N empty generations for generations from empty + // hashtables. In general, we won't always detect when iterators from + // different empty hashtables are compared, but in this test case, we + // should deterministically detect the error due to our randomness yielding + // consecutive random generations. + EXPECT_DEATH_IF_SUPPORTED(void(t1.end() == t2.end()), + "Invalid iterator comparison.*empty hashtables"); EXPECT_DEATH_IF_SUPPORTED(void(t1.end() == default_constructed_iter), "Invalid iterator comparison.*default-constructed"); t1.insert(0); |