https://github.com/emaxx-google updated 
https://github.com/llvm/llvm-project/pull/137910

>From b31a3f86d3427405f1182d59c381e90c93e521b8 Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <em...@google.com>
Date: Wed, 30 Apr 2025 00:31:30 +0000
Subject: [PATCH 1/2] [clang] Fix nondeterminism in MemberPointerType

This commit fixes the nondeterminism issue in C++ header module enabled
builds which were observed after
https://github.com/llvm/llvm-project/pull/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.
---
 clang/include/clang/AST/Type.h |  3 ++-
 clang/lib/AST/Type.cpp         | 10 +++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 3e1fb05ad537c..c93cbae767db8 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3602,6 +3602,7 @@ class MemberPointerType : public Type, public 
llvm::FoldingSetNode {
   }
 
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
+  CXXRecordDecl *getCXXRecordDecl() const;
   CXXRecordDecl *getMostRecentCXXRecordDecl() const;
 
   bool isSugared() const;
@@ -3610,7 +3611,7 @@ class MemberPointerType : public Type, public 
llvm::FoldingSetNode {
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getPointeeType(), getQualifier(), 
getMostRecentCXXRecordDecl());
+    Profile(ID, getPointeeType(), getQualifier(), getCXXRecordDecl());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 111a642173418..a149eac7e4555 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -5275,10 +5275,14 @@ void MemberPointerType::Profile(llvm::FoldingSetNodeID 
&ID, QualType Pointee,
     ID.AddPointer(Cls->getCanonicalDecl());
 }
 
+CXXRecordDecl *MemberPointerType::getCXXRecordDecl() const {
+  return dyn_cast<MemberPointerType>(getCanonicalTypeInternal())
+      ->getQualifier()
+      ->getAsRecordDecl();
+}
+
 CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
-  auto *RD = dyn_cast<MemberPointerType>(getCanonicalTypeInternal())
-                 ->getQualifier()
-                 ->getAsRecordDecl();
+  auto *RD = getCXXRecordDecl();
   if (!RD)
     return nullptr;
   return RD->getMostRecentNonInjectedDecl();

>From a8c958e79b7595b1d741b61357e3954af84affdf Mon Sep 17 00:00:00 2001
From: Maksim Ivanov <em...@google.com>
Date: Wed, 30 Apr 2025 14:29:28 +0000
Subject: [PATCH 2/2] add comment

---
 clang/include/clang/AST/Type.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index c93cbae767db8..6d08a2f49f9f9 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -3603,6 +3603,9 @@ class MemberPointerType : public Type, public 
llvm::FoldingSetNode {
 
   NestedNameSpecifier *getQualifier() const { return Qualifier; }
   CXXRecordDecl *getCXXRecordDecl() const;
+  /// Note: this can trigger extra deserialization when external AST sources 
are
+  /// used. Prefer `getCXXRecordDecl()` unless you really need the most recent
+  /// decl.
   CXXRecordDecl *getMostRecentCXXRecordDecl() const;
 
   bool isSugared() const;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to