[clang] Adding implementation for missing origin statsitics on LifetimeSafety… (PR #166163)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 3 05:23:57 PST 2025
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 <debadribasak at google.com>
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 <debadribasak at google.com>
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");
More information about the cfe-commits
mailing list