https://github.com/necto updated 
https://github.com/llvm/llvm-project/pull/162839

>From 07bcb966a7b0aed27da7971cbb876885080562e1 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Fri, 10 Oct 2025 13:38:27 +0200
Subject: [PATCH 1/4] [clang][analyzer] Record never-set statistics as empty
 CSV cells

---
 .../analyzer/developer-docs/Statistics.rst    |  2 +-
 .../Core/PathSensitive/EntryPointStats.h      |  2 +-
 .../StaticAnalyzer/Core/EntryPointStats.cpp   | 69 +++++++++++++------
 .../analyzer-stats/entry-point-stats.cpp      | 30 ++++----
 4 files changed, 66 insertions(+), 37 deletions(-)

diff --git a/clang/docs/analyzer/developer-docs/Statistics.rst 
b/clang/docs/analyzer/developer-docs/Statistics.rst
index 4f2484a89a6af..355759d468282 100644
--- a/clang/docs/analyzer/developer-docs/Statistics.rst
+++ b/clang/docs/analyzer/developer-docs/Statistics.rst
@@ -22,7 +22,7 @@ However, note that with ``LLVM_ENABLE_STATS`` disabled, only 
storage of the valu
 If you want to define a statistic only for entry point, EntryPointStats.h has 
four classes at your disposal:
 
 
-- ``UnsignedEPStat`` - an unsigned value assigned at most once per entry 
point. For example: "the number of source characters in an entry-point body".
+- ``UnsignedEPStat`` - an unsigned value assigned at most once per entry 
point. For example: "the number of source characters in an entry-point body". 
If no value is assigned during analysis of an entry point, the corresponding 
CSV cell will be empty.
 - ``CounterEPStat`` - an additive statistic. It starts with 0 and you can add 
to it as many times as needed. For example: "the number of bugs discovered".
 - ``UnsignedMaxEPStat`` - a maximizing statistic. It starts with 0 and when 
you join it with a value, it picks the maximum of the previous value and the 
new one. For example, "the longest execution path of a bug".
 
diff --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h
index 389f17d36e65a..0a45deb33fcc9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h
@@ -85,7 +85,7 @@ class UnsignedEPStat : public EntryPointStat {
 
 public:
   explicit UnsignedEPStat(llvm::StringLiteral Name);
-  unsigned value() const { return Value.value_or(0); }
+  std::optional<unsigned> value() const { return Value; }
   void reset() { Value.reset(); }
   void set(unsigned V) {
     assert(!Value.has_value());
diff --git a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp 
b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
index abfb176d6384d..33f5ccf6002ba 100644
--- a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
+++ b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
@@ -24,15 +24,21 @@ using namespace ento;
 
 namespace {
 struct Registry {
+  std::vector<UnsignedEPStat *> ExplicitlySetStats;
+  std::vector<UnsignedMaxEPStat *> MaxStats;
   std::vector<CounterEPStat *> CounterStats;
-  std::vector<UnsignedMaxEPStat *> UnsignedMaxStats;
-  std::vector<UnsignedEPStat *> UnsignedStats;
 
   bool IsLocked = false;
 
   struct Snapshot {
     const Decl *EntryPoint;
-    std::vector<unsigned> UnsignedStatValues;
+    // Explicitly set statistics may not have a value set, so they are separate
+    // from other unsigned statistics
+    std::vector<std::optional<unsigned>> ExplicitlySetStatValues;
+    // These are counting and maximizing statistics that initialize to 0, which
+    // is meaningful even if they are never updated, so their value is always
+    // present.
+    std::vector<unsigned> MaxOrCountStatValues;
 
     void dumpAsCSV(llvm::raw_ostream &OS) const;
   };
@@ -46,9 +52,12 @@ static llvm::ManagedStatic<Registry> StatsRegistry;
 
 namespace {
 template <typename Callback> void enumerateStatVectors(const Callback &Fn) {
+  // This order is important, it matches the order of the Snapshot fields:
+  // - ExplicitlySetStatValues
+  Fn(StatsRegistry->ExplicitlySetStats);
+  // - MaxOrCountStatValues
+  Fn(StatsRegistry->MaxStats);
   Fn(StatsRegistry->CounterStats);
-  Fn(StatsRegistry->UnsignedMaxStats);
-  Fn(StatsRegistry->UnsignedStats);
 }
 } // namespace
 
@@ -101,30 +110,37 @@ UnsignedMaxEPStat::UnsignedMaxEPStat(llvm::StringLiteral 
Name)
     : EntryPointStat(Name) {
   assert(!StatsRegistry->IsLocked);
   assert(!isRegistered(Name));
-  StatsRegistry->UnsignedMaxStats.push_back(this);
+  StatsRegistry->MaxStats.push_back(this);
 }
 
 UnsignedEPStat::UnsignedEPStat(llvm::StringLiteral Name)
     : EntryPointStat(Name) {
   assert(!StatsRegistry->IsLocked);
   assert(!isRegistered(Name));
-  StatsRegistry->UnsignedStats.push_back(this);
+  StatsRegistry->ExplicitlySetStats.push_back(this);
 }
 
-static std::vector<unsigned> consumeUnsignedStats() {
-  std::vector<unsigned> Result;
-  Result.reserve(StatsRegistry->CounterStats.size() +
-                 StatsRegistry->UnsignedMaxStats.size() +
-                 StatsRegistry->UnsignedStats.size());
-  for (auto *M : StatsRegistry->CounterStats) {
+static std::vector<std::optional<unsigned>>
+consumeExplicitlySetStats() {
+  std::vector<std::optional<unsigned>> Result;
+  Result.reserve(StatsRegistry->ExplicitlySetStats.size());
+  for (auto *M : StatsRegistry->ExplicitlySetStats) {
     Result.push_back(M->value());
     M->reset();
   }
-  for (auto *M : StatsRegistry->UnsignedMaxStats) {
+  return Result;
+}
+
+static std::vector<unsigned> consumeMaxAndCounterStats() {
+  std::vector<unsigned> Result;
+  Result.reserve(StatsRegistry->CounterStats.size() +
+                 StatsRegistry->MaxStats.size());
+  // Order is important, it must match the order in enumerateStatVectors
+  for (auto *M : StatsRegistry->MaxStats) {
     Result.push_back(M->value());
     M->reset();
   }
-  for (auto *M : StatsRegistry->UnsignedStats) {
+  for (auto *M : StatsRegistry->CounterStats) {
     Result.push_back(M->value());
     M->reset();
   }
@@ -150,20 +166,33 @@ static std::string getUSR(const Decl *D) {
 }
 
 void Registry::Snapshot::dumpAsCSV(llvm::raw_ostream &OS) const {
+  auto printAsUnsignOpt = [&OS](std::optional<unsigned> U) {
+    OS << (U.has_value() ? std::to_string(*U) : "");
+  };
+  auto commaIfNeeded = [&OS](const auto &Vec1, const auto &Vec2) {
+    if (!Vec1.empty() && !Vec2.empty())
+      OS << ",";
+  };
+  auto printAsUnsigned = [&OS](unsigned U) { OS << U; };
+
   OS << '"';
   llvm::printEscapedString(getUSR(EntryPoint), OS);
   OS << "\",\"";
   OS << StatsRegistry->EscapedCPPFileName << "\",\"";
   llvm::printEscapedString(
       clang::AnalysisDeclContext::getFunctionName(EntryPoint), OS);
-  OS << "\"";
-  OS << (UnsignedStatValues.empty() ? "" : ",");
-  llvm::interleave(UnsignedStatValues, OS, [&OS](unsigned U) { OS << U; }, 
",");
+  OS << "\",";
+  llvm::interleave(ExplicitlySetStatValues, OS, printAsUnsignOpt, ",");
+  commaIfNeeded(ExplicitlySetStatValues, MaxOrCountStatValues);
+  llvm::interleave(MaxOrCountStatValues, OS, printAsUnsigned, ",");
 }
 
 void EntryPointStat::takeSnapshot(const Decl *EntryPoint) {
-  auto UnsignedValues = consumeUnsignedStats();
-  StatsRegistry->Snapshots.push_back({EntryPoint, std::move(UnsignedValues)});
+  auto ExplicitlySetValues = consumeExplicitlySetStats();
+  auto MaxOrCounterValues = consumeMaxAndCounterStats();
+  StatsRegistry->Snapshots.push_back({EntryPoint,
+                                      std::move(ExplicitlySetValues),
+                                      std::move(MaxOrCounterValues)});
 }
 
 void EntryPointStat::dumpStatsAsCSV(llvm::StringRef FileName) {
diff --git a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp 
b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
index 9cbe04550a8d3..0e9b4895554e9 100644
--- a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
+++ b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
@@ -6,8 +6,15 @@
 //
 // CHECK:      {
 // CHECK-NEXT:   "c:@F@fib#i#": {
-// CHECK-NEXT:     "File": "{{.*}}entry-point-stats.cpp",
+// CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
 // CHECK-NEXT:     "DebugName": "fib(unsigned int)",
+// CHECK-NEXT:     "PathRunningTime": "",
+// CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
+// CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
+// CHECK-NEXT:     "MaxQueueSize": "{{[0-9]+}}",
+// CHECK-NEXT:     "MaxReachableSize": "{{[0-9]+}}",
+// CHECK-NEXT:     "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}",
+// CHECK-NEXT:     "MaxValidBugClassSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumBlocks": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumBlocksUnreachable": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumCTUSteps": "{{[0-9]+}}",
@@ -33,18 +40,18 @@
 // CHECK-NEXT:     "NumTimesZ3SpendsTooMuchTimeOnASingleEQClass": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumTimesZ3TimedOut": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumZ3QueriesDone": "{{[0-9]+}}",
-// CHECK-NEXT:     "TimeSpentSolvingZ3Queries": "{{[0-9]+}}",
+// CHECK-NEXT:     "TimeSpentSolvingZ3Queries": "{{[0-9]+}}"
+// CHECK-NEXT:   },
+// CHECK-NEXT:   "c:@F@main#I#**C#": {
+// CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
+// CHECK-NEXT:     "DebugName": "main(int, char **)",
+// CHECK-NEXT:     "PathRunningTime": "",
 // CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxQueueSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxReachableSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxValidBugClassSize": "{{[0-9]+}}",
-// CHECK-NEXT:     "PathRunningTime": "{{[0-9]+}}"
-// CHECK-NEXT:   },
-// CHECK-NEXT:   "c:@F@main#I#**C#": {
-// CHECK-NEXT:     "File": "{{.*}}entry-point-stats.cpp",
-// CHECK-NEXT:     "DebugName": "main(int, char **)",
 // CHECK-NEXT:     "NumBlocks": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumBlocksUnreachable": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumCTUSteps": "{{[0-9]+}}",
@@ -70,14 +77,7 @@
 // CHECK-NEXT:     "NumTimesZ3SpendsTooMuchTimeOnASingleEQClass": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumTimesZ3TimedOut": "{{[0-9]+}}",
 // CHECK-NEXT:     "NumZ3QueriesDone": "{{[0-9]+}}",
-// CHECK-NEXT:     "TimeSpentSolvingZ3Queries": "{{[0-9]+}}",
-// CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
-// CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
-// CHECK-NEXT:     "MaxQueueSize": "{{[0-9]+}}",
-// CHECK-NEXT:     "MaxReachableSize": "{{[0-9]+}}",
-// CHECK-NEXT:     "MaxTimeSpentSolvingZ3Queries": "{{[0-9]+}}",
-// CHECK-NEXT:     "MaxValidBugClassSize": "{{[0-9]+}}",
-// CHECK-NEXT:     "PathRunningTime": "{{[0-9]+}}"
+// CHECK-NEXT:     "TimeSpentSolvingZ3Queries": "{{[0-9]+}}"
 // CHECK-NEXT:   }
 // CHECK-NEXT: }
 // CHECK-NOT: non_entry_point

>From ab54bbd48bb66824d5cf666c84d22dc7b3c47b22 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Fri, 10 Oct 2025 13:39:24 +0200
Subject: [PATCH 2/4] Fix path running time per entry point recording

---
 clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp   | 5 ++++-
 clang/test/Analysis/analyzer-stats/entry-point-stats.cpp | 4 ++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp 
b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index cf01e2f37c662..e97004f1bbe52 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -39,6 +39,7 @@
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cmath>
 #include <memory>
 #include <utility>
 
@@ -142,7 +143,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
     DigestAnalyzerOptions();
 
     if (Opts.AnalyzerDisplayProgress || Opts.PrintStats ||
-        Opts.ShouldSerializeStats) {
+        Opts.ShouldSerializeStats || !Opts.DumpEntryPointStatsToCSV.empty()) {
       AnalyzerTimers = std::make_unique<llvm::TimerGroup>(
           "analyzer", "Analyzer timers");
       SyntaxCheckTimer = std::make_unique<llvm::Timer>(
@@ -788,6 +789,8 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
     ExprEngineTimer->stopTimer();
     llvm::TimeRecord ExprEngineEndTime = ExprEngineTimer->getTotalTime();
     ExprEngineEndTime -= ExprEngineStartTime;
+    PathRunningTime.set(static_cast<unsigned>(
+        std::lround(ExprEngineEndTime.getWallTime() * 1000)));
     DisplayTime(ExprEngineEndTime);
   }
 
diff --git a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp 
b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
index 0e9b4895554e9..feaf92a8043ca 100644
--- a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
+++ b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
@@ -8,7 +8,7 @@
 // CHECK-NEXT:   "c:@F@fib#i#": {
 // CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
 // CHECK-NEXT:     "DebugName": "fib(unsigned int)",
-// CHECK-NEXT:     "PathRunningTime": "",
+// CHECK-NEXT:     "PathRunningTime": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxQueueSize": "{{[0-9]+}}",
@@ -45,7 +45,7 @@
 // CHECK-NEXT:   "c:@F@main#I#**C#": {
 // CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
 // CHECK-NEXT:     "DebugName": "main(int, char **)",
-// CHECK-NEXT:     "PathRunningTime": "",
+// CHECK-NEXT:     "PathRunningTime": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxQueueSize": "{{[0-9]+}}",

>From f83589b5cfec72114451ed08b5a0315960338bd0 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Fri, 10 Oct 2025 14:47:30 +0200
Subject: [PATCH 3/4] Add a test case demonstrating the use of explicitly set
 unsigned stats

---
 .../clang/StaticAnalyzer/Checkers/Checkers.td |  4 ++
 .../StaticAnalyzer/Checkers/CMakeLists.txt    |  1 +
 .../Checkers/UnsignedStatTesterChecker.cpp    | 59 +++++++++++++++++++
 .../analyzer-stats/entry-point-stats.cpp      | 19 +++++-
 4 files changed, 82 insertions(+), 1 deletion(-)
 create mode 100644 
clang/lib/StaticAnalyzer/Checkers/UnsignedStatTesterChecker.cpp

diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 4473c54d8d6e3..0db6794b2310a 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -1502,6 +1502,10 @@ def TaintTesterChecker : Checker<"TaintTest">,
   HelpText<"Mark tainted symbols as such.">,
   Documentation<NotDocumented>;
 
+def UnsignedStatTesterChecker : Checker<"UnsignedStatTester">,
+  HelpText<"Test checker for demonstrating UnsignedEPStat usage.">,
+  Documentation<NotDocumented>;
+
 // This checker *technically* depends on SteamChecker, but we don't allow
 // dependency checkers to emit diagnostics, and a debug checker isn't worth
 // the chore needed to create a modeling portion on its own. Since this checker
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt 
b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 29d2c4512d470..f70ae1a3e8a96 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -125,6 +125,7 @@ add_clang_library(clangStaticAnalyzerCheckers
   UninitializedObject/UninitializedPointee.cpp
   UnixAPIChecker.cpp
   UnreachableCodeChecker.cpp
+  UnsignedStatTesterChecker.cpp
   VforkChecker.cpp
   VLASizeChecker.cpp
   VAListChecker.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnsignedStatTesterChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/UnsignedStatTesterChecker.cpp
new file mode 100644
index 0000000000000..a302f506a285a
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/UnsignedStatTesterChecker.cpp
@@ -0,0 +1,59 @@
+//== UnsignedStatTesterChecker.cpp --------------------------- -*- C++ -*--=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker demonstrates the use of UnsignedEPStat for per-entry-point
+// statistics. It conditionally sets a statistic based on the entry point name.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/EntryPointStats.h"
+
+using namespace clang;
+using namespace ento;
+
+#define DEBUG_TYPE "UnsignedStatTester"
+
+static UnsignedEPStat DemoStat("DemoStat");
+
+namespace {
+class UnsignedStatTesterChecker : public Checker<check::BeginFunction> {
+public:
+  void checkBeginFunction(CheckerContext &C) const;
+};
+} // namespace
+
+void UnsignedStatTesterChecker::checkBeginFunction(CheckerContext &C) const {
+  const Decl *D = C.getLocationContext()->getDecl();
+  if (!D)
+    return;
+
+  std::string Name =
+      D->getAsFunction() ? D->getAsFunction()->getNameAsString() : "";
+
+  // Conditionally set the statistic based on the function name
+  if (Name == "func_one") {
+    DemoStat.set(1);
+  } else if (Name == "func_two") {
+    DemoStat.set(2);
+  } else if (Name == "func_three") {
+    DemoStat.set(3);
+  }
+  // For any other function (e.g., "func_none"), don't set the statistic
+}
+
+void ento::registerUnsignedStatTesterChecker(CheckerManager &mgr) {
+  mgr.registerChecker<UnsignedStatTesterChecker>();
+}
+
+bool ento::shouldRegisterUnsignedStatTesterChecker(const CheckerManager &mgr) {
+  return true;
+}
diff --git a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp 
b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
index feaf92a8043ca..395d2b2fefa65 100644
--- a/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
+++ b/clang/test/Analysis/analyzer-stats/entry-point-stats.cpp
@@ -1,5 +1,5 @@
 // REQUIRES: asserts
-// RUN: %clang_analyze_cc1 -analyzer-checker=core \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.UnsignedStatTester \
 // RUN:    -analyzer-config dump-entry-point-stats-to-csv="%t.csv" \
 // RUN:    -verify %s
 // RUN: %csv2json "%t.csv" | FileCheck --check-prefix=CHECK %s
@@ -8,6 +8,7 @@
 // CHECK-NEXT:   "c:@F@fib#i#": {
 // CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
 // CHECK-NEXT:     "DebugName": "fib(unsigned int)",
+// CHECK-NEXT:     "DemoStat": "",
 // CHECK-NEXT:     "PathRunningTime": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
@@ -42,9 +43,22 @@
 // CHECK-NEXT:     "NumZ3QueriesDone": "{{[0-9]+}}",
 // CHECK-NEXT:     "TimeSpentSolvingZ3Queries": "{{[0-9]+}}"
 // CHECK-NEXT:   },
+// CHECK-NEXT:   "c:@F@func_one#": {
+// CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
+// CHECK-NEXT:     "DebugName": "func_one()",
+// CHECK:          "DemoStat": "1",
+//             .... not interesting statistics
+// CHECK:        },
+// CHECK-NEXT:   "c:@F@func_two#": {
+// CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
+// CHECK-NEXT:     "DebugName": "func_two()",
+// CHECK:          "DemoStat": "2",
+//             .... not interesting statistics
+// CHECK:        },
 // CHECK-NEXT:   "c:@F@main#I#**C#": {
 // CHECK-NEXT:     "File": "{{.*}}/entry-point-stats.cpp",
 // CHECK-NEXT:     "DebugName": "main(int, char **)",
+// CHECK-NEXT:     "DemoStat": "",
 // CHECK-NEXT:     "PathRunningTime": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxBugClassSize": "{{[0-9]+}}",
 // CHECK-NEXT:     "MaxCFGSize": "{{[0-9]+}}",
@@ -102,3 +116,6 @@ int main(int argc, char **argv) {
   int i = non_entry_point(argc);
   return i;
 }
+
+void func_one() {}
+void func_two() {}

>From 22ce0fbee6d4f22b5b41dc1f469c4dcf4f2bcc2f Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <[email protected]>
Date: Fri, 10 Oct 2025 15:04:02 +0200
Subject: [PATCH 4/4] [NFC] Fix code formatting

---
 clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp 
b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
index 33f5ccf6002ba..ce25b23651ed4 100644
--- a/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
+++ b/clang/lib/StaticAnalyzer/Core/EntryPointStats.cpp
@@ -120,8 +120,7 @@ UnsignedEPStat::UnsignedEPStat(llvm::StringLiteral Name)
   StatsRegistry->ExplicitlySetStats.push_back(this);
 }
 
-static std::vector<std::optional<unsigned>>
-consumeExplicitlySetStats() {
+static std::vector<std::optional<unsigned>> consumeExplicitlySetStats() {
   std::vector<std::optional<unsigned>> Result;
   Result.reserve(StatsRegistry->ExplicitlySetStats.size());
   for (auto *M : StatsRegistry->ExplicitlySetStats) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to