Index: source/Utility/ConstString.cpp =================================================================== --- source/Utility/ConstString.cpp +++ source/Utility/ConstString.cpp @@ -119,11 +119,15 @@ const uint8_t h = hash(demangled); llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - // Make string pool entry with the mangled counterpart already set - StringPoolEntryType &entry = - *m_string_pools[h] - .m_string_map.insert(std::make_pair(demangled, mangled_ccstr)) - .first; + StringPool &map = m_string_pools[h].m_string_map; + assert((map.find(demangled) == map.end() || strlen(map[demangled]) == 0 || + map[demangled] == mangled_ccstr) && + "The demangled string must have a unique counterpart or otherwise " + "it must be empty"); + + // Make or update string pool entry with the mangled counterpart + StringPoolEntryType &entry = *map.try_emplace(demangled).first; + entry.second = mangled_ccstr; // Extract the const version of the demangled_cstr demangled_ccstr = entry.getKeyData(); Index: unittests/Utility/ConstStringTest.cpp =================================================================== --- unittests/Utility/ConstStringTest.cpp +++ unittests/Utility/ConstStringTest.cpp @@ -18,25 +18,41 @@ } TEST(ConstStringTest, MangledCounterpart) { - ConstString foo("foo"); + ConstString uvw("uvw"); ConstString counterpart; - EXPECT_FALSE(foo.GetMangledCounterpart(counterpart)); + EXPECT_FALSE(uvw.GetMangledCounterpart(counterpart)); EXPECT_EQ("", counterpart.GetStringRef()); - ConstString bar; - bar.SetStringWithMangledCounterpart("bar", foo); - EXPECT_EQ("bar", bar.GetStringRef()); + ConstString xyz; + xyz.SetStringWithMangledCounterpart("xyz", uvw); + EXPECT_EQ("xyz", xyz.GetStringRef()); - EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); - EXPECT_EQ("foo", counterpart.GetStringRef()); + EXPECT_TRUE(xyz.GetMangledCounterpart(counterpart)); + EXPECT_EQ("uvw", counterpart.GetStringRef()); - EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); - EXPECT_EQ("bar", counterpart.GetStringRef()); + EXPECT_TRUE(uvw.GetMangledCounterpart(counterpart)); + EXPECT_EQ("xyz", counterpart.GetStringRef()); +} + +TEST(ConstStringTest, UpdateMangledCounterpart) { + { // Init counterpart with empty string + ConstString some1; + some1.SetStringWithMangledCounterpart("some", ConstString("")); + } + { // Update counterpart to "one" + ConstString some2; + some2.SetStringWithMangledCounterpart("some", ConstString("one")); + } + { // Check counterpart is "one" + ConstString counterpart; + EXPECT_TRUE(ConstString("some").GetMangledCounterpart(counterpart)); + EXPECT_EQ("one", counterpart.GetStringRef()); + } } TEST(ConstStringTest, FromMidOfBufferStringRef) { // StringRef's into bigger buffer: no null termination - const char *buffer = "foobarbaz"; + const char *buffer = "abcdefghi"; llvm::StringRef foo_ref(buffer, 3); llvm::StringRef bar_ref(buffer + 3, 3); @@ -44,14 +60,14 @@ ConstString bar; bar.SetStringWithMangledCounterpart(bar_ref, foo); - EXPECT_EQ("bar", bar.GetStringRef()); + EXPECT_EQ("def", bar.GetStringRef()); ConstString counterpart; EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); - EXPECT_EQ("foo", counterpart.GetStringRef()); + EXPECT_EQ("abc", counterpart.GetStringRef()); EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); - EXPECT_EQ("bar", counterpart.GetStringRef()); + EXPECT_EQ("def", counterpart.GetStringRef()); } TEST(ConstStringTest, NullAndEmptyStates) {