The branch stable/13 has been updated by ivy:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=fbaab13732809e02dc30e9aef15fac230aed4464

commit fbaab13732809e02dc30e9aef15fac230aed4464
Author:     Lexi Winter <i...@freebsd.org>
AuthorDate: 2025-06-25 17:12:02 +0000
Commit:     Lexi Winter <i...@freebsd.org>
CommitDate: 2025-06-30 22:27:40 +0000

    contrib/llvm-project: fix clang crash compiling modules
    
    clang++ may crash when compiling certain C++20 modules.  Backport the
    fix from LLVM upstream.
    
    This fixes LLVM bug 102684:
    https://github.com/llvm/llvm-project/issues/102684.
    
    PR:     287803
    MFC after:      3 days
    Obtained from:  https://github.com/llvm/llvm-project/pull/102855
    Reviewed by:    kevans, dim
    Approved by:    kevans (mentor)
    Differential Revision:  https://reviews.freebsd.org/D51041
    
    (cherry picked from commit 55dfaeae8e9aa95f0b724d90ad2423ca1b623142)
---
 .../include/clang/Frontend/MultiplexConsumer.h     |  1 +
 .../Serialization/ASTDeserializationListener.h     |  2 +
 .../clang/include/clang/Serialization/ASTReader.h  |  3 +
 .../clang/include/clang/Serialization/ASTWriter.h  |  1 +
 .../clang/lib/Frontend/MultiplexConsumer.cpp       |  5 ++
 .../clang/lib/Serialization/ASTReader.cpp          | 91 +++++++++++++++++-----
 .../clang/lib/Serialization/ASTWriter.cpp          |  6 ++
 7 files changed, 91 insertions(+), 18 deletions(-)

diff --git 
a/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h 
b/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h
index e49e3392d1f3..3a7670d7a51a 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -36,6 +36,7 @@ public:
   void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
   void TypeRead(serialization::TypeIdx Idx, QualType T) override;
   void DeclRead(GlobalDeclID ID, const Decl *D) override;
+  void PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) override;
   void SelectorRead(serialization::SelectorID iD, Selector Sel) override;
   void MacroDefinitionRead(serialization::PreprocessedEntityID,
                            MacroDefinitionRecord *MD) override;
diff --git 
a/contrib/llvm-project/clang/include/clang/Serialization/ASTDeserializationListener.h
 
b/contrib/llvm-project/clang/include/clang/Serialization/ASTDeserializationListener.h
index 1d81a9ae3fe2..ea96faa07c19 100644
--- 
a/contrib/llvm-project/clang/include/clang/Serialization/ASTDeserializationListener.h
+++ 
b/contrib/llvm-project/clang/include/clang/Serialization/ASTDeserializationListener.h
@@ -45,6 +45,8 @@ public:
   virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { }
   /// A decl was deserialized from the AST file.
   virtual void DeclRead(GlobalDeclID ID, const Decl *D) {}
+  /// A predefined decl was built during the serialization.
+  virtual void PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) {}
   /// A selector was read from the AST file.
   virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {}
   /// A macro definition was read from the AST file.
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h 
b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h
index 671520a3602b..82f32e843d63 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h
@@ -1541,6 +1541,9 @@ private:
   std::pair<ModuleFile *, unsigned>
   translateTypeIDToIndex(serialization::TypeID ID) const;
 
+  /// Get a predefined Decl from ASTContext.
+  Decl *getPredefinedDecl(PredefinedDeclIDs ID);
+
 public:
   /// Load the AST file and validate its contents against the given
   /// Preprocessor.
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h 
b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h
index 700f0ad00111..10a50b711043 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h
@@ -869,6 +869,7 @@ private:
   void IdentifierRead(serialization::IdentifierID ID, IdentifierInfo *II) 
override;
   void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
   void TypeRead(serialization::TypeIdx Idx, QualType T) override;
+  void PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) override;
   void SelectorRead(serialization::SelectorID ID, Selector Sel) override;
   void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
                            MacroDefinitionRecord *MD) override;
diff --git a/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp 
b/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp
index 651c55aeed54..2158d176d189 100644
--- a/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp
+++ b/contrib/llvm-project/clang/lib/Frontend/MultiplexConsumer.cpp
@@ -58,6 +58,11 @@ void 
MultiplexASTDeserializationListener::DeclRead(GlobalDeclID ID,
     Listeners[i]->DeclRead(ID, D);
 }
 
+void 
MultiplexASTDeserializationListener::PredefinedDeclBuilt(PredefinedDeclIDs ID, 
const Decl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->PredefinedDeclBuilt(ID, D);
+}
+
 void MultiplexASTDeserializationListener::SelectorRead(
     serialization::SelectorID ID, Selector Sel) {
   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp 
b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
index 29aec144aec1..2d8f5a801f0e 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
@@ -7741,7 +7741,10 @@ SourceLocation 
ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
   return Loc;
 }
 
-static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) {
+Decl *ASTReader::getPredefinedDecl(PredefinedDeclIDs ID) {
+  assert(ContextObj && "reading predefined decl without AST context");
+  ASTContext &Context = *ContextObj;
+  Decl *NewLoaded = nullptr;
   switch (ID) {
   case PREDEF_DECL_NULL_ID:
     return nullptr;
@@ -7750,54 +7753,106 @@ static Decl *getPredefinedDecl(ASTContext &Context, 
PredefinedDeclIDs ID) {
     return Context.getTranslationUnitDecl();
 
   case PREDEF_DECL_OBJC_ID_ID:
-    return Context.getObjCIdDecl();
+    if (Context.ObjCIdDecl)
+      return Context.ObjCIdDecl;
+    NewLoaded = Context.getObjCIdDecl();
+    break;
 
   case PREDEF_DECL_OBJC_SEL_ID:
-    return Context.getObjCSelDecl();
+    if (Context.ObjCSelDecl)
+      return Context.ObjCSelDecl;
+    NewLoaded = Context.getObjCSelDecl();
+    break;
 
   case PREDEF_DECL_OBJC_CLASS_ID:
-    return Context.getObjCClassDecl();
+    if (Context.ObjCClassDecl)
+      return Context.ObjCClassDecl;
+    NewLoaded = Context.getObjCClassDecl();
+    break;
 
   case PREDEF_DECL_OBJC_PROTOCOL_ID:
-    return Context.getObjCProtocolDecl();
+    if (Context.ObjCProtocolClassDecl)
+      return Context.ObjCProtocolClassDecl;
+    NewLoaded = Context.getObjCProtocolDecl();
+    break;
 
   case PREDEF_DECL_INT_128_ID:
-    return Context.getInt128Decl();
+    if (Context.Int128Decl)
+      return Context.Int128Decl;
+    NewLoaded = Context.getInt128Decl();
+    break;
 
   case PREDEF_DECL_UNSIGNED_INT_128_ID:
-    return Context.getUInt128Decl();
+    if (Context.UInt128Decl)
+      return Context.UInt128Decl;
+    NewLoaded = Context.getUInt128Decl();
+    break;
 
   case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
-    return Context.getObjCInstanceTypeDecl();
+    if (Context.ObjCInstanceTypeDecl)
+      return Context.ObjCInstanceTypeDecl;
+    NewLoaded = Context.getObjCInstanceTypeDecl();
+    break;
 
   case PREDEF_DECL_BUILTIN_VA_LIST_ID:
-    return Context.getBuiltinVaListDecl();
+    if (Context.BuiltinVaListDecl)
+      return Context.BuiltinVaListDecl;
+    NewLoaded = Context.getBuiltinVaListDecl();
+    break;
 
   case PREDEF_DECL_VA_LIST_TAG:
-    return Context.getVaListTagDecl();
+    if (Context.VaListTagDecl)
+      return Context.VaListTagDecl;
+    NewLoaded = Context.getVaListTagDecl();
+    break;
 
   case PREDEF_DECL_BUILTIN_MS_VA_LIST_ID:
-    return Context.getBuiltinMSVaListDecl();
+    if (Context.BuiltinMSVaListDecl)
+      return Context.BuiltinMSVaListDecl;
+    NewLoaded = Context.getBuiltinMSVaListDecl();
+    break;
 
   case PREDEF_DECL_BUILTIN_MS_GUID_ID:
+    // ASTContext::getMSGuidTagDecl won't create MSGuidTagDecl conditionally.
     return Context.getMSGuidTagDecl();
 
   case PREDEF_DECL_EXTERN_C_CONTEXT_ID:
-    return Context.getExternCContextDecl();
+    if (Context.ExternCContext)
+      return Context.ExternCContext;
+    NewLoaded = Context.getExternCContextDecl();
+    break;
 
   case PREDEF_DECL_MAKE_INTEGER_SEQ_ID:
-    return Context.getMakeIntegerSeqDecl();
+    if (Context.MakeIntegerSeqDecl)
+      return Context.MakeIntegerSeqDecl;
+    NewLoaded = Context.getMakeIntegerSeqDecl();
+    break;
 
   case PREDEF_DECL_CF_CONSTANT_STRING_ID:
-    return Context.getCFConstantStringDecl();
+    if (Context.CFConstantStringTypeDecl)
+      return Context.CFConstantStringTypeDecl;
+    NewLoaded = Context.getCFConstantStringDecl();
+    break;
 
   case PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID:
-    return Context.getCFConstantStringTagDecl();
+    if (Context.CFConstantStringTagDecl)
+      return Context.CFConstantStringTagDecl;
+    NewLoaded = Context.getCFConstantStringTagDecl();
+    break;
 
   case PREDEF_DECL_TYPE_PACK_ELEMENT_ID:
-    return Context.getTypePackElementDecl();
+    if (Context.TypePackElementDecl)
+      return Context.TypePackElementDecl;
+    NewLoaded = Context.getTypePackElementDecl();
+    break;
   }
-  llvm_unreachable("PredefinedDeclIDs unknown enum value");
+
+  assert(NewLoaded && "Failed to load predefined decl?");
+
+  if (DeserializationListener)
+    DeserializationListener->PredefinedDeclBuilt(ID, NewLoaded);
+
+  return NewLoaded;
 }
 
 unsigned ASTReader::translateGlobalDeclIDToIndex(GlobalDeclID GlobalID) const {
@@ -7814,7 +7869,7 @@ Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) {
   assert(ContextObj && "reading decl with no AST context");
 
   if (ID < NUM_PREDEF_DECL_IDS) {
-    Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID);
+    Decl *D = getPredefinedDecl((PredefinedDeclIDs)ID);
     if (D) {
       // Track that we have merged the declaration with ID \p ID into the
       // pre-existing predefined declaration \p D.
diff --git a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp 
b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
index cb63dec92e33..e907ddb88949 100644
--- a/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
+++ b/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
@@ -6757,6 +6757,12 @@ void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
     StoredIdx = Idx;
 }
 
+void ASTWriter::PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) {
+  assert(D->isCanonicalDecl() && "predefined decl is not canonical");
+  DeclIDs[D] = LocalDeclID(ID);
+  PredefinedDecls.insert(D);
+}
+
 void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
   // Always keep the highest ID. See \p TypeRead() for more information.
   SelectorID &StoredID = SelectorIDs[S];

Reply via email to