https://github.com/davidstone created 
https://github.com/llvm/llvm-project/pull/172530

`CFGStmtMap::Build` accepts pointers and returns a pointer to dynamically 
allocated memory. In the one location where the type is actually constructed, 
the pointers are guaranteed to be non-null. By accepting references to 
statically enforce this, we can remove the only way for the construction to 
fail.

By making this change, we also allow our user to decide how they want to own 
the memory (either directly or indirectly). The user does not actually need 
dynamic allocation here, so we replace the `std::unique_ptr` with 
`std::optional`.

This simplifies the code by requiring fewer checks, makes comments on what 
happens redundant because the code can obviously do only one thing, avoids 
potential bugs, and improves performance by allocating less.

>From 65c435c2e939c959c4179d05bd4d51058277b422 Mon Sep 17 00:00:00 2001
From: David Stone <[email protected]>
Date: Tue, 16 Dec 2025 11:15:00 -0700
Subject: [PATCH] [clang][NFC] Use constructor instead of factory function in
 `CFGStmtMap`

`CFGStmtMap::Build` accepts pointers and returns a pointer to dynamically 
allocated memory. In the one location where the type is actually constructed, 
the pointers are guaranteed to be non-null. By accepting references to 
statically enforce this, we can remove the only way for the construction to 
fail.

By making this change, we also allow our user to decide how they want to own 
the memory (either directly or indirectly). The user does not actually need 
dynamic allocation here, so we replace the `std::unique_ptr` with 
`std::optional`.

This simplifies the code by requiring fewer checks, makes comments on what 
happens redundant because the code can obviously do only one thing, avoids 
potential bugs, and improves performance by allocating less.
---
 clang/include/clang/Analysis/AnalysisDeclContext.h |  4 ++--
 clang/include/clang/Analysis/CFGStmtMap.h          |  6 +-----
 clang/lib/Analysis/AnalysisDeclContext.cpp         |  6 +++---
 clang/lib/Analysis/CFGStmtMap.cpp                  | 13 +++----------
 clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp    |  1 -
 5 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/clang/include/clang/Analysis/AnalysisDeclContext.h 
b/clang/include/clang/Analysis/AnalysisDeclContext.h
index 76fb96bacc377..2368b8ed911e7 100644
--- a/clang/include/clang/Analysis/AnalysisDeclContext.h
+++ b/clang/include/clang/Analysis/AnalysisDeclContext.h
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclBase.h"
 #include "clang/Analysis/BodyFarm.h"
 #include "clang/Analysis/CFG.h"
+#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/Analysis/CodeInjector.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/DenseMap.h"
@@ -37,7 +38,6 @@ class ASTContext;
 class BlockDecl;
 class BlockInvocationContext;
 class CFGReverseBlockReachabilityAnalysis;
-class CFGStmtMap;
 class ImplicitParamDecl;
 class LocationContext;
 class LocationContextManager;
@@ -77,7 +77,7 @@ class AnalysisDeclContext {
   const Decl *const D;
 
   std::unique_ptr<CFG> cfg, completeCFG;
-  std::unique_ptr<CFGStmtMap> cfgStmtMap;
+  std::optional<CFGStmtMap> cfgStmtMap;
 
   CFG::BuildOptions cfgBuildOptions;
   CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs = nullptr;
diff --git a/clang/include/clang/Analysis/CFGStmtMap.h 
b/clang/include/clang/Analysis/CFGStmtMap.h
index cde24b9f2b282..c1aa3d2a78bcc 100644
--- a/clang/include/clang/Analysis/CFGStmtMap.h
+++ b/clang/include/clang/Analysis/CFGStmtMap.h
@@ -27,14 +27,10 @@ class CFGStmtMap {
   const ParentMap *PM;
   SMap M;
 
-  CFGStmtMap(const ParentMap *pm, SMap m) : PM(pm), M(std::move(m)) {}
-
   static void Accumulate(SMap &SM, const CFGBlock *B);
 
 public:
-  /// Returns a new CFGMap for the given CFG.  It is the caller's
-  /// responsibility to 'delete' this object when done using it.
-  static CFGStmtMap *Build(const CFG *C, const ParentMap *PM);
+  CFGStmtMap(const CFG &C, const ParentMap &PM);
 
   /// Returns the CFGBlock the specified Stmt* appears in.  For Stmt* that
   /// are terminators, the CFGBlock is the block they appear as a terminator,
diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp 
b/clang/lib/Analysis/AnalysisDeclContext.cpp
index f683b9efc1d1e..6f153e7e65255 100644
--- a/clang/lib/Analysis/AnalysisDeclContext.cpp
+++ b/clang/lib/Analysis/AnalysisDeclContext.cpp
@@ -252,11 +252,11 @@ CFG *AnalysisDeclContext::getUnoptimizedCFG() {
 
 const CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
   if (cfgStmtMap)
-    return cfgStmtMap.get();
+    return &*cfgStmtMap;
 
   if (const CFG *c = getCFG()) {
-    cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
-    return cfgStmtMap.get();
+    cfgStmtMap.emplace(*c, getParentMap());
+    return &*cfgStmtMap;
   }
 
   return nullptr;
diff --git a/clang/lib/Analysis/CFGStmtMap.cpp 
b/clang/lib/Analysis/CFGStmtMap.cpp
index eb42c8663526f..177aa1a7af686 100644
--- a/clang/lib/Analysis/CFGStmtMap.cpp
+++ b/clang/lib/Analysis/CFGStmtMap.cpp
@@ -53,16 +53,9 @@ void CFGStmtMap::Accumulate(SMap &SM, const CFGBlock *B) {
     SM[Term] = B;
 }
 
-CFGStmtMap *CFGStmtMap::Build(const CFG *C, const ParentMap *PM) {
-  if (!C || !PM)
-    return nullptr;
-
-  SMap SM;
-
+CFGStmtMap::CFGStmtMap(const CFG &C, const ParentMap &PM) : PM(&PM) {
   // Walk all blocks, accumulating the block-level expressions, labels,
   // and terminators.
-  for (const CFGBlock *BB : *C)
-    Accumulate(SM, BB);
-
-  return new CFGStmtMap(PM, std::move(SM));
+  for (const CFGBlock *BB : C)
+    Accumulate(M, BB);
 }
diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp 
b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index 53fec3467b835..159555aad4a7e 100644
--- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -16,7 +16,6 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/Stmt.h"
-#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/Basic/LLVM.h"

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

Reply via email to