https://github.com/RIscRIpt updated https://github.com/llvm/llvm-project/pull/181367
>From b13d48cd827f2eed3fdc3c1eef7d0495a6f8bd70 Mon Sep 17 00:00:00 2001 From: Richard Dzenis <[email protected]> Date: Fri, 13 Feb 2026 15:46:24 +0200 Subject: [PATCH 1/6] [clang][StaticAnalyzer] Fix static init in findKnownClass Prior to this patch two threads running in findKnownClass could result in a race condition. --- .../Checkers/BasicObjCFoundationChecks.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index e682c4ef80896..0c48d77679226 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -70,16 +70,12 @@ enum FoundationClass { static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID, bool IncludeSuperclasses = true) { - static llvm::StringMap<FoundationClass> Classes; - if (Classes.empty()) { - Classes["NSArray"] = FC_NSArray; - Classes["NSDictionary"] = FC_NSDictionary; - Classes["NSEnumerator"] = FC_NSEnumerator; - Classes["NSNull"] = FC_NSNull; - Classes["NSOrderedSet"] = FC_NSOrderedSet; - Classes["NSSet"] = FC_NSSet; - Classes["NSString"] = FC_NSString; - } + static llvm::StringMap<FoundationClass> Classes{ + {"NSArray", FC_NSArray}, {"NSDictionary", FC_NSDictionary}, + {"NSEnumerator", FC_NSEnumerator}, {"NSNull", FC_NSNull}, + {"NSOrderedSet", FC_NSOrderedSet}, {"NSSet", FC_NSSet}, + {"NSString", FC_NSString}, + }; // FIXME: Should we cache this at all? FoundationClass result = Classes.lookup(ID->getIdentifier()->getName()); >From 53df8baa67bc7e4dffb8232d4fe936e5d312720f Mon Sep 17 00:00:00 2001 From: Richard Dzenis <[email protected]> Date: Fri, 13 Feb 2026 15:51:41 +0200 Subject: [PATCH 2/6] [clang][CodeGen] Correctly restore diagnostic handler in HandleTranslationUnit Prior to this patch an early exit from HandleTranslationUnit could result in not restoring previous diagnostic handler. --- clang/lib/CodeGen/CodeGenAction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index a5ef4ac9d361d..29dcabd1b0971 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -248,6 +248,8 @@ void BackendConsumer::HandleTranslationUnit(ASTContext &C) { LLVMContext &Ctx = getModule()->getContext(); std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler = Ctx.getDiagnosticHandler(); + llvm::scope_exit RestoreDiagnosticHandler( + [&]() { Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); }); Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>( CodeGenOpts, this)); @@ -311,8 +313,6 @@ void BackendConsumer::HandleTranslationUnit(ASTContext &C) { C.getTargetInfo().getDataLayoutString(), getModule(), Action, FS, std::move(AsmOutStream), this); - Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); - if (OptRecordFile) OptRecordFile->keep(); } >From af2c8d2a30d3e6484a565743c054996e083b9870 Mon Sep 17 00:00:00 2001 From: Richard Dzenis <[email protected]> Date: Thu, 12 Feb 2026 20:07:16 +0200 Subject: [PATCH 3/6] [clang][Stmt] Fix StmtClassNameTable array initialization Prior to this patch there was a race condition when two threads check `if (Initialized)` at the same time. --- clang/lib/AST/Stmt.cpp | 43 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 5b745dd3c43f5..5715546d31dbe 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -57,26 +57,19 @@ using namespace clang; #define ABSTRACT_STMT(STMT) #include "clang/AST/StmtNodes.inc" -static struct StmtClassNameTable { +struct StmtClassNameTable { const char *Name; unsigned Counter; unsigned Size; -} StmtClassInfo[Stmt::lastStmtConstant+1]; +}; static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) { - static bool Initialized = false; - if (Initialized) - return StmtClassInfo[E]; - - // Initialize the table on the first use. - Initialized = true; + static StmtClassNameTable stmtClassInfo[Stmt::lastStmtConstant + 1] = { #define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) \ - StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \ - StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS); +#define STMT(CLASS, PARENT) {#CLASS, 0, sizeof(CLASS)}, #include "clang/AST/StmtNodes.inc" - - return StmtClassInfo[E]; + }; + return stmtClassInfo[E]; } void *Stmt::operator new(size_t bytes, const ASTContext& C, @@ -85,7 +78,7 @@ void *Stmt::operator new(size_t bytes, const ASTContext& C, } const char *Stmt::getStmtClassName() const { - return getStmtInfoTableEntry((StmtClass) StmtBits.sClass).Name; + return getStmtInfoTableEntry(static_cast<StmtClass>(StmtBits.sClass)).Name; } // Check that no statement / expression class is polymorphic. LLVM style RTTI @@ -113,19 +106,25 @@ void Stmt::PrintStats() { unsigned sum = 0; llvm::errs() << "\n*** Stmt/Expr Stats:\n"; for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { - if (StmtClassInfo[i].Name == nullptr) continue; - sum += StmtClassInfo[i].Counter; + StmtClassNameTable &entry = + getStmtInfoTableEntry(static_cast<Stmt::StmtClass>(i)); + if (entry.Name == nullptr) + continue; + sum += entry.Counter; } llvm::errs() << " " << sum << " stmts/exprs total.\n"; sum = 0; for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { - if (StmtClassInfo[i].Name == nullptr) continue; - if (StmtClassInfo[i].Counter == 0) continue; - llvm::errs() << " " << StmtClassInfo[i].Counter << " " - << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size - << " each (" << StmtClassInfo[i].Counter*StmtClassInfo[i].Size + StmtClassNameTable &entry = + getStmtInfoTableEntry(static_cast<Stmt::StmtClass>(i)); + if (entry.Name == nullptr) + continue; + if (entry.Counter == 0) + continue; + llvm::errs() << " " << entry.Counter << " " << entry.Name << ", " + << entry.Size << " each (" << entry.Counter * entry.Size << " bytes)\n"; - sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size; + sum += entry.Counter * entry.Size; } llvm::errs() << "Total bytes = " << sum << "\n"; >From 139a461214436e61187dbe2df4ad6d48b4fcd264 Mon Sep 17 00:00:00 2001 From: Richard Dzenis <[email protected]> Date: Thu, 12 Feb 2026 20:27:30 +0200 Subject: [PATCH 4/6] [clang][ParsedAttrInfo] Fix race condition in getAttributePluginInstances Prior to this patch two threads could enter under if (empty()) check. --- clang/lib/Basic/ParsedAttrInfo.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/lib/Basic/ParsedAttrInfo.cpp b/clang/lib/Basic/ParsedAttrInfo.cpp index 16fa314b642b9..d5b17b34b6e3a 100644 --- a/clang/lib/Basic/ParsedAttrInfo.cpp +++ b/clang/lib/Basic/ParsedAttrInfo.cpp @@ -20,13 +20,16 @@ using namespace clang; LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry) +static std::list<std::unique_ptr<ParsedAttrInfo>> instantiateEntries() { + std::list<std::unique_ptr<ParsedAttrInfo>> Instances; + for (const auto &It : ParsedAttrInfoRegistry::entries()) + Instances.emplace_back(It.instantiate()); + return Instances; +} + const std::list<std::unique_ptr<ParsedAttrInfo>> & clang::getAttributePluginInstances() { - static llvm::ManagedStatic<std::list<std::unique_ptr<ParsedAttrInfo>>> - PluginAttrInstances; - if (PluginAttrInstances->empty()) - for (const auto &It : ParsedAttrInfoRegistry::entries()) - PluginAttrInstances->emplace_back(It.instantiate()); - - return *PluginAttrInstances; + static std::list<std::unique_ptr<ParsedAttrInfo>> Instances = + instantiateEntries(); + return Instances; } >From 067184ee614dca2b521996fd9f65731c1bfbcfff Mon Sep 17 00:00:00 2001 From: Richard Dzenis <[email protected]> Date: Fri, 13 Feb 2026 17:03:08 +0200 Subject: [PATCH 5/6] fixup! [clang][StaticAnalyzer] Fix static init in findKnownClass --- clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp index 0c48d77679226..f226f80aa441f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp @@ -70,7 +70,7 @@ enum FoundationClass { static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID, bool IncludeSuperclasses = true) { - static llvm::StringMap<FoundationClass> Classes{ + static const llvm::StringMap<FoundationClass> Classes{ {"NSArray", FC_NSArray}, {"NSDictionary", FC_NSDictionary}, {"NSEnumerator", FC_NSEnumerator}, {"NSNull", FC_NSNull}, {"NSOrderedSet", FC_NSOrderedSet}, {"NSSet", FC_NSSet}, >From a723ab26a9968e1bc96f1fe4be106bbf7fe0d22b Mon Sep 17 00:00:00 2001 From: Richard Dzenis <[email protected]> Date: Fri, 13 Feb 2026 17:31:04 +0200 Subject: [PATCH 6/6] fixup! [clang][Stmt] Fix StmtClassNameTable array initialization Co-authored-by: Javier Lopez-Gomez <[email protected]> --- clang/lib/AST/Stmt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 5715546d31dbe..2793fb763f5d0 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -106,7 +106,7 @@ void Stmt::PrintStats() { unsigned sum = 0; llvm::errs() << "\n*** Stmt/Expr Stats:\n"; for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { - StmtClassNameTable &entry = + const StmtClassNameTable &entry = getStmtInfoTableEntry(static_cast<Stmt::StmtClass>(i)); if (entry.Name == nullptr) continue; @@ -115,7 +115,7 @@ void Stmt::PrintStats() { llvm::errs() << " " << sum << " stmts/exprs total.\n"; sum = 0; for (int i = 0; i != Stmt::lastStmtConstant+1; i++) { - StmtClassNameTable &entry = + const StmtClassNameTable &entry = getStmtInfoTableEntry(static_cast<Stmt::StmtClass>(i)); if (entry.Name == nullptr) continue; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
