[llvm] 1047073 - [ADT] Fix FoldingSetIterator::operator* pointer adjustment for multiple inheritance (#219349)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 23:37:23 PDT 2026
Author: Wenju He
Date: 2026-08-28T14:37:18+08:00
New Revision: 10470737d982370b26db924e710246a641606d49
URL: https://github.com/llvm/llvm-project/commit/10470737d982370b26db924e710246a641606d49
DIFF: https://github.com/llvm/llvm-project/commit/10470737d982370b26db924e710246a641606d49.diff
LOG: [ADT] Fix FoldingSetIterator::operator* pointer adjustment for multiple inheritance (#219349)
b7dc8e356b89 replaced the void*->FoldingSetNode*->T* cast in
FoldingSetIteratorImpl::getNode() with a direct void*->T* cast, dropping
the base-to-derived adjustment needed when FoldingSetNode isn't T's
first base. Restore the FoldingSetNode* intermediate cast.
Found via a downstream user with a multiply-inherited FoldingSetNode
type that iterates its FoldingSet directly (via find_if over
begin()/end()), corrupting the dereferenced pointer and crashing.
---------
Co-authored-by: Claude Sonnet 5 <noreply at anthropic.com>
Added:
Modified:
llvm/include/llvm/ADT/FoldingSet.h
llvm/unittests/ADT/FoldingSet.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/FoldingSet.h b/llvm/include/llvm/ADT/FoldingSet.h
index a3b37c44f28f6..c984c00b86fd1 100644
--- a/llvm/include/llvm/ADT/FoldingSet.h
+++ b/llvm/include/llvm/ADT/FoldingSet.h
@@ -619,7 +619,7 @@ template <class T> class FoldingSetIterator : DebugEpochBase::HandleBase {
T &operator*() const {
assert(isHandleInSync() && "invalid iterator access!");
- return *static_cast<T *>(*Bucket);
+ return *static_cast<T *>(static_cast<FoldingSetNode *>(*Bucket));
}
T *operator->() const { return &operator*(); }
diff --git a/llvm/unittests/ADT/FoldingSet.cpp b/llvm/unittests/ADT/FoldingSet.cpp
index ba0b7326e26d4..2556d64bae7a3 100644
--- a/llvm/unittests/ADT/FoldingSet.cpp
+++ b/llvm/unittests/ADT/FoldingSet.cpp
@@ -272,6 +272,23 @@ TEST(FoldingSetTest, Iterator) {
EXPECT_NE(It, ItCopy);
}
+// FoldingSetNode has a non-zero offset here, so operator* must adjust it.
+struct NonEmptyBase {
+ int Dummy = 0;
+};
+
+struct MultiplyInheritedNode : public NonEmptyBase, public FoldingSetNode {
+ void Profile(FoldingSetNodeID &ID) const { ID.AddInteger(0); }
+};
+
+TEST(FoldingSetTest, IteratorMultipleInheritance) {
+ FoldingSet<MultiplyInheritedNode> Set;
+ MultiplyInheritedNode N;
+ Set.InsertNode(&N);
+
+ EXPECT_EQ(&*Set.begin(), &N);
+}
+
TEST(FoldingSetTest, FoldingSetVectorBasic) {
FoldingSetVector<TrivialPair> Vec;
EXPECT_THAT(Vec, IsEmpty());
More information about the llvm-commits
mailing list