https://github.com/DEBADRIBASAK updated https://github.com/llvm/llvm-project/pull/166163
>From f3a4e18d0236a1bf2819c981f40737cf78500599 Mon Sep 17 00:00:00 2001 From: Debadri Basak <[email protected]> Date: Mon, 3 Nov 2025 13:11:00 +0000 Subject: [PATCH 1/2] Adding implementation for missing origin statsitics on LifetimeSafetyAnalysis --- .../Analyses/LifetimeSafety/LifetimeSafety.h | 21 +++++++++++++++++++ .../Analyses/LifetimeSafety/Origins.h | 6 ++++++ .../LifetimeSafety/LifetimeSafety.cpp | 5 +++++ clang/lib/Analysis/LifetimeSafety/Origins.cpp | 16 ++++++++++++++ clang/lib/Sema/AnalysisBasedWarnings.cpp | 4 +++- 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h index 91ffbb169f947..4952d84a80369 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h @@ -23,7 +23,11 @@ #include "clang/Analysis/Analyses/LifetimeSafety/Facts.h" #include "clang/Analysis/Analyses/LifetimeSafety/LiveOrigins.h" #include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h" +#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h" #include "clang/Analysis/AnalysisDeclContext.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/raw_ostream.h" +#include <string> namespace clang::lifetimes { @@ -60,6 +64,9 @@ struct LifetimeFactory { /// Running the lifetime safety analysis and querying its results. It /// encapsulates the various dataflow analyses. class LifetimeSafetyAnalysis { +private: + static llvm::StringMap<int> MissingOriginCount; + public: LifetimeSafetyAnalysis(AnalysisDeclContext &AC, LifetimeSafetyReporter *Reporter); @@ -73,6 +80,20 @@ class LifetimeSafetyAnalysis { LiveOriginsAnalysis &getLiveOrigins() const { return *LiveOrigins; } FactManager &getFactManager() { return FactMgr; } + static void PrintStats(llvm::raw_ostream &OS) { + llvm::errs() << "\n*** LifetimeSafety Missing Origin Stats " + "(expression_type : count) :\n"; + for (const auto &[expr, count] : LifetimeSafetyAnalysis::count) { + OS << expr << " : " << count << '\n'; + } + } + + static void UpdateMissingOriginCount(const OriginManager &OM) { + for (const auto &[expr, missing_origin_count] : OM.getMissingOrigins()) { + LifetimeSafetyAnalysis::count[std::string(expr)] += missing_origin_count; + } + } + private: AnalysisDeclContext &AC; LifetimeSafetyReporter *Reporter; diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h index ba138b078b379..231cc60b7e097 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h @@ -16,7 +16,10 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" +#include "clang/AST/TypeBase.h" #include "clang/Analysis/Analyses/LifetimeSafety/Utils.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/raw_ostream.h" namespace clang::lifetimes::internal { @@ -76,6 +79,8 @@ class OriginManager { void dump(OriginID OID, llvm::raw_ostream &OS) const; + const llvm::StringMap<int> getMissingOrigins() const; + private: OriginID getNextOriginID() { return NextOriginID++; } @@ -85,6 +90,7 @@ class OriginManager { llvm::SmallVector<Origin> AllOrigins; llvm::DenseMap<const clang::ValueDecl *, OriginID> DeclToOriginID; llvm::DenseMap<const clang::Expr *, OriginID> ExprToOriginID; + llvm::StringMap<int> ExprTypeToMissingOriginCount; }; } // namespace clang::lifetimes::internal diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp index 00c7ed90503e7..a76fdd2535d97 100644 --- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp +++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp @@ -23,14 +23,18 @@ #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TimeProfiler.h" +#include "llvm/Support/raw_ostream.h" #include <memory> namespace clang::lifetimes { namespace internal { +llvm::StringMap<int> LifetimeSafetyAnalysis::MissingOriginCount; + LifetimeSafetyAnalysis::LifetimeSafetyAnalysis(AnalysisDeclContext &AC, LifetimeSafetyReporter *Reporter) : AC(AC), Reporter(Reporter) {} @@ -66,6 +70,7 @@ void LifetimeSafetyAnalysis::run() { LiveOrigins->dump(llvm::dbgs(), FactMgr.getTestPoints())); runLifetimeChecker(*LoanPropagation, *LiveOrigins, FactMgr, AC, Reporter); + UpdateMissingOriginCount(FactMgr.getOriginMgr()); } } // namespace internal diff --git a/clang/lib/Analysis/LifetimeSafety/Origins.cpp b/clang/lib/Analysis/LifetimeSafety/Origins.cpp index ea51a75324e06..abe067a829cb7 100644 --- a/clang/lib/Analysis/LifetimeSafety/Origins.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Origins.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/Analyses/LifetimeSafety/Origins.h" +#include "clang/AST/TypeBase.h" +#include "llvm/ADT/StringMap.h" namespace clang::lifetimes::internal { @@ -22,6 +24,10 @@ void OriginManager::dump(OriginID OID, llvm::raw_ostream &OS) const { OS << ")"; } +const llvm::StringMap<int> OriginManager::getMissingOrigins() const { + return ExprTypeToMissingOriginCount; +} + Origin &OriginManager::addOrigin(OriginID ID, const clang::ValueDecl &D) { AllOrigins.emplace_back(ID, &D); return AllOrigins.back(); @@ -37,6 +43,16 @@ OriginID OriginManager::get(const Expr &E) { auto It = ExprToOriginID.find(&E); if (It != ExprToOriginID.end()) return It->second; + + // if the expression has no specific origin, increment the missing origin + // counter. + const QualType ExprType = E.getType(); + auto CountIt = ExprTypeToMissingOriginCount.find(ExprType.getAsString()); + if (CountIt == ExprTypeToMissingOriginCount.end()) { + ExprTypeToMissingOriginCount[ExprType.getAsString()] = 1; + } else { + CountIt->second++; + } // If the expression itself has no specific origin, and it's a reference // to a declaration, its origin is that of the declaration it refers to. // For pointer types, where we don't pre-emptively create an origin for the diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 140b709dbb651..009994e189220 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -30,6 +30,7 @@ #include "clang/Analysis/Analyses/CalledOnceCheck.h" #include "clang/Analysis/Analyses/Consumed.h" #include "clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h" +#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h" #include "clang/Analysis/Analyses/ReachableCode.h" #include "clang/Analysis/Analyses/ThreadSafety.h" #include "clang/Analysis/Analyses/UninitializedValues.h" @@ -53,6 +54,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> #include <deque> #include <iterator> @@ -3132,8 +3134,8 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings( } void clang::sema::AnalysisBasedWarnings::PrintStats() const { + clang::lifetimes::internal::LifetimeSafetyAnalysis::PrintStats(llvm::errs()); llvm::errs() << "\n*** Analysis Based Warnings Stats:\n"; - unsigned NumCFGsBuilt = NumFunctionsAnalyzed - NumFunctionsWithBadCFGs; unsigned AvgCFGBlocksPerFunction = !NumCFGsBuilt ? 0 : NumCFGBlocks/NumCFGsBuilt; >From fa85d2da89acec96c6c31f3d0e2dd009b6286054 Mon Sep 17 00:00:00 2001 From: Debadri Basak <[email protected]> Date: Mon, 3 Nov 2025 13:23:42 +0000 Subject: [PATCH 2/2] Minor refactoring of the static functions --- .../Analyses/LifetimeSafety/LifetimeSafety.h | 14 ++------------ .../lib/Analysis/LifetimeSafety/LifetimeSafety.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h index 4952d84a80369..7490df90a3282 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h @@ -80,19 +80,9 @@ class LifetimeSafetyAnalysis { LiveOriginsAnalysis &getLiveOrigins() const { return *LiveOrigins; } FactManager &getFactManager() { return FactMgr; } - static void PrintStats(llvm::raw_ostream &OS) { - llvm::errs() << "\n*** LifetimeSafety Missing Origin Stats " - "(expression_type : count) :\n"; - for (const auto &[expr, count] : LifetimeSafetyAnalysis::count) { - OS << expr << " : " << count << '\n'; - } - } + static void PrintStats(llvm::raw_ostream &OS); - static void UpdateMissingOriginCount(const OriginManager &OM) { - for (const auto &[expr, missing_origin_count] : OM.getMissingOrigins()) { - LifetimeSafetyAnalysis::count[std::string(expr)] += missing_origin_count; - } - } + static void UpdateMissingOriginCount(const OriginManager &OM); private: AnalysisDeclContext &AC; diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp index a76fdd2535d97..828c08d1cbeed 100644 --- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp +++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp @@ -39,6 +39,19 @@ LifetimeSafetyAnalysis::LifetimeSafetyAnalysis(AnalysisDeclContext &AC, LifetimeSafetyReporter *Reporter) : AC(AC), Reporter(Reporter) {} +void LifetimeSafetyAnalysis::PrintStats(llvm::raw_ostream &OS) { + llvm::errs() << "\n*** LifetimeSafety Missing Origin Stats " + "(expression_type : count) :\n"; + for (const auto &[expr, count] : LifetimeSafetyAnalysis::MissingOriginCount) { + OS << expr << " : " << count << '\n'; + } + } + +void LifetimeSafetyAnalysis::UpdateMissingOriginCount(const OriginManager &OM) { + for (const auto &[expr, missing_origin_count] : OM.getMissingOrigins()) { + LifetimeSafetyAnalysis::MissingOriginCount[std::string(expr)] += missing_origin_count; + } + } void LifetimeSafetyAnalysis::run() { llvm::TimeTraceScope TimeProfile("LifetimeSafetyAnalysis"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
