The branch main has been updated by ivy: URL: https://cgit.FreeBSD.org/src/commit/?id=55dfaeae8e9aa95f0b724d90ad2423ca1b623142
commit 55dfaeae8e9aa95f0b724d90ad2423ca1b623142 Author: Lexi Winter <i...@freebsd.org> AuthorDate: 2025-06-25 17:12:02 +0000 Commit: Lexi Winter <i...@freebsd.org> CommitDate: 2025-06-25 17:12:02 +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 --- .../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];