summaryrefslogtreecommitdiffstats
path: root/llvm/unittests
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2018-03-21 22:23:59 +0000
committerZachary Turner <zturner@google.com>2018-03-21 22:23:59 +0000
commiteb629994554a05a4d3e59d6b5c09d312416d096e (patch)
tree9bcb30216f509396fede9fea725a74b394e78cc5 /llvm/unittests
parentecb178bb356fc058a51bbda0d083068b5d83ba2b (diff)
downloadbcm5719-llvm-eb629994554a05a4d3e59d6b5c09d312416d096e.tar.gz
bcm5719-llvm-eb629994554a05a4d3e59d6b5c09d312416d096e.zip
[PDB] Don't ignore bucket 0 when writing the PDB string table.
The hash table is a list of buckets, and the *value* stored in the bucket cannot be 0 since that is reserved. However, the code here was incorrectly skipping over the 0'th bucket entirely. The 0'th bucket is perfectly fine, just none of these buckets can contain the value 0. As a result, whenever there was a string where hash(S) % Size was equal to 0, we would write the value in the next bucket instead. We never caught this in our tests due to *another* bug, which is that we would iterate the entire list of buckets looking for the value, only using the hash value as a starting point. However, the real algorithm stops when it finds 0 in a bucket since it takes that to mean "the item is not in the hash table". The unit test is updated to carefully construct a set of hash values that will cause one item to hash to 0 mod bucket count, and the reader is also updated to return an error indicating that the item is not found when it encounters a 0 bucket. llvm-svn: 328162
Diffstat (limited to 'llvm/unittests')
-rw-r--r--llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp48
1 files changed, 37 insertions, 11 deletions
diff --git a/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp b/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
index 0efc2c6411b..bf08ab20923 100644
--- a/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
+++ b/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
@@ -27,10 +27,29 @@ class StringTableBuilderTest : public ::testing::Test {};
TEST_F(StringTableBuilderTest, Simple) {
// Create /names table contents.
PDBStringTableBuilder Builder;
- EXPECT_EQ(1U, Builder.insert("foo"));
- EXPECT_EQ(5U, Builder.insert("bar"));
- EXPECT_EQ(1U, Builder.insert("foo"));
- EXPECT_EQ(9U, Builder.insert("baz"));
+
+ // This test case is carefully constructed to ensure that at least one
+ // string gets bucketed into slot 0, *and* to ensure that at least one
+ // has a hash collision at the end of the bucket list so it has to
+ // wrap around.
+ uint32_t FooID = Builder.insert("foo");
+ uint32_t BarID = Builder.insert("bar");
+ uint32_t BazID = Builder.insert("baz");
+ uint32_t BuzzID = Builder.insert("buzz");
+ uint32_t BazzID = Builder.insert("bazz");
+ uint32_t BarrID = Builder.insert("barr");
+
+ // Re-inserting the same item should return the same id.
+ EXPECT_EQ(FooID, Builder.insert("foo"));
+ EXPECT_EQ(BarID, Builder.insert("bar"));
+ EXPECT_EQ(BazID, Builder.insert("baz"));
+ EXPECT_EQ(BuzzID, Builder.insert("buzz"));
+ EXPECT_EQ(BazzID, Builder.insert("bazz"));
+ EXPECT_EQ(BarrID, Builder.insert("barr"));
+
+ // Each ID should be distinct.
+ std::set<uint32_t> Distinct{FooID, BarID, BazID, BuzzID, BazzID, BarrID};
+ EXPECT_EQ(6U, Distinct.size());
std::vector<uint8_t> Buffer(Builder.calculateSerializedSize());
MutableBinaryByteStream OutStream(Buffer, little);
@@ -43,13 +62,20 @@ TEST_F(StringTableBuilderTest, Simple) {
PDBStringTable Table;
EXPECT_THAT_ERROR(Table.reload(Reader), Succeeded());
- EXPECT_EQ(3U, Table.getNameCount());
+ EXPECT_EQ(6U, Table.getNameCount());
EXPECT_EQ(1U, Table.getHashVersion());
- EXPECT_THAT_EXPECTED(Table.getStringForID(1), HasValue("foo"));
- EXPECT_THAT_EXPECTED(Table.getStringForID(5), HasValue("bar"));
- EXPECT_THAT_EXPECTED(Table.getStringForID(9), HasValue("baz"));
- EXPECT_THAT_EXPECTED(Table.getIDForString("foo"), HasValue(1U));
- EXPECT_THAT_EXPECTED(Table.getIDForString("bar"), HasValue(5U));
- EXPECT_THAT_EXPECTED(Table.getIDForString("baz"), HasValue(9U));
+ EXPECT_THAT_EXPECTED(Table.getStringForID(FooID), HasValue("foo"));
+ EXPECT_THAT_EXPECTED(Table.getStringForID(BarID), HasValue("bar"));
+ EXPECT_THAT_EXPECTED(Table.getStringForID(BazID), HasValue("baz"));
+ EXPECT_THAT_EXPECTED(Table.getStringForID(BuzzID), HasValue("buzz"));
+ EXPECT_THAT_EXPECTED(Table.getStringForID(BazzID), HasValue("bazz"));
+ EXPECT_THAT_EXPECTED(Table.getStringForID(BarrID), HasValue("barr"));
+
+ EXPECT_THAT_EXPECTED(Table.getIDForString("foo"), HasValue(FooID));
+ EXPECT_THAT_EXPECTED(Table.getIDForString("bar"), HasValue(BarID));
+ EXPECT_THAT_EXPECTED(Table.getIDForString("baz"), HasValue(BazID));
+ EXPECT_THAT_EXPECTED(Table.getIDForString("buzz"), HasValue(BuzzID));
+ EXPECT_THAT_EXPECTED(Table.getIDForString("bazz"), HasValue(BazzID));
+ EXPECT_THAT_EXPECTED(Table.getIDForString("barr"), HasValue(BarrID));
}
OpenPOWER on IntegriCloud