Skip to content

Commit b31a3f8

Browse files
committed
[clang] Fix nondeterminism in MemberPointerType
This commit fixes the nondeterminism issue in C++ header module enabled builds which were observed after #132401. The issue was related to the fact that the hash set operation in MemberPointerType::Profile() was triggering getMostRecentDecl(). The root cause seems to be that the latter was leading to the reentrant modification of the hash set, with some probability (likely depending on the actual values of hashes). We haven't been able to come up with a deterministic regression test for this fix.
1 parent d775b91 commit b31a3f8

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

clang/include/clang/AST/Type.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3602,6 +3602,7 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
36023602
}
36033603

36043604
NestedNameSpecifier *getQualifier() const { return Qualifier; }
3605+
CXXRecordDecl *getCXXRecordDecl() const;
36053606
CXXRecordDecl *getMostRecentCXXRecordDecl() const;
36063607

36073608
bool isSugared() const;
@@ -3610,7 +3611,7 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
36103611
}
36113612

36123613
void Profile(llvm::FoldingSetNodeID &ID) {
3613-
Profile(ID, getPointeeType(), getQualifier(), getMostRecentCXXRecordDecl());
3614+
Profile(ID, getPointeeType(), getQualifier(), getCXXRecordDecl());
36143615
}
36153616

36163617
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,

clang/lib/AST/Type.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5275,10 +5275,14 @@ void MemberPointerType::Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
52755275
ID.AddPointer(Cls->getCanonicalDecl());
52765276
}
52775277

5278+
CXXRecordDecl *MemberPointerType::getCXXRecordDecl() const {
5279+
return dyn_cast<MemberPointerType>(getCanonicalTypeInternal())
5280+
->getQualifier()
5281+
->getAsRecordDecl();
5282+
}
5283+
52785284
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
5279-
auto *RD = dyn_cast<MemberPointerType>(getCanonicalTypeInternal())
5280-
->getQualifier()
5281-
->getAsRecordDecl();
5285+
auto *RD = getCXXRecordDecl();
52825286
if (!RD)
52835287
return nullptr;
52845288
return RD->getMostRecentNonInjectedDecl();

0 commit comments

Comments
 (0)