https://github.com/DEBADRIBASAK created https://github.com/llvm/llvm-project/pull/166153
This PR adds the implementation for `PrintStats` function in LifetimeSafetyAnalysis class. **Purpose:** This utility function is added to track the expression types with missing origin. While retrieving the origins from origin manager, some expressions show missing origins. Currently these are created on the fly using `getOrCreate` function. For analysing the coverage of the check, it will be necessary to see what kind of expressions have a missing origin. **Approach:** A static map from strings to counts has been added to the `LifetimeSafetyAnalysis` class. The OriginManager also internally tracks the count of missing origins using `ExprTypeToMissingOriginCount` map. After analysing each file, the missing origin stats are accumulated in the LifetimeSafetyAnalysis class, in the `UpdateMissingOriginCount` class. **Example output:** For the file `llvm-project/llvm/lib/Demangle/Demangle.cpp`: ``` *** LifetimeSafety Missing Origin Stats (expression_type : count) : const char[3] : 2 const char[2] : 1 char * : 19 std::string_view : 52 ``` >From 5326b2706673ae2c38f241f54d0edbb59a25c8e2 Mon Sep 17 00:00:00 2001 From: Debadri Basak <[email protected]> Date: Mon, 3 Nov 2025 11:20:48 +0000 Subject: [PATCH] Adding implementation for LifetimeSafetyAnalysis::PrintStats --- .../Analyses/LifetimeSafety/LifetimeSafety.h | 8 ++++++++ .../Analysis/Analyses/LifetimeSafety/Origins.h | 6 ++++++ .../Analysis/LifetimeSafety/LifetimeSafety.cpp | 18 ++++++++++++++++++ clang/lib/Analysis/LifetimeSafety/Origins.cpp | 17 +++++++++++++++++ clang/lib/Sema/AnalysisBasedWarnings.cpp | 3 +++ 5 files changed, 52 insertions(+) diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h index 91ffbb169f947..e5ac4ca0d01c0 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h @@ -23,7 +23,10 @@ #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" namespace clang::lifetimes { @@ -73,7 +76,12 @@ class LifetimeSafetyAnalysis { LiveOriginsAnalysis &getLiveOrigins() const { return *LiveOrigins; } FactManager &getFactManager() { return FactMgr; } + static void PrintStats(llvm::raw_ostream& OS); + + static void UpdateMissingOriginCount(const OriginManager& OM); + private: + static llvm::StringMap<int> MissingOriginMap; AnalysisDeclContext &AC; LifetimeSafetyReporter *Reporter; LifetimeFactory Factory; 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..5ad18ee26c174 100644 --- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp +++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp @@ -23,18 +23,35 @@ #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::MissingOriginMap; + 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::MissingOriginMap) { + OS << expr << " : " << count << '\n'; + } +} + +void LifetimeSafetyAnalysis::UpdateMissingOriginCount(const OriginManager& OM) { + for (const auto& [expr, missing_origin_count] : OM.getMissingOrigins()) { + LifetimeSafetyAnalysis::MissingOriginMap[std::string(expr)] += missing_origin_count; + } +} + void LifetimeSafetyAnalysis::run() { llvm::TimeTraceScope TimeProfile("LifetimeSafetyAnalysis"); @@ -66,6 +83,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..c8570844fe314 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,11 @@ 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 +44,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..ca74c637bb92f 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,6 +3134,7 @@ 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; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
