[clang] [FlowSensitive] [PtrCaching] optionally pass Type to initializer (PR #164030)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 17 16:12:15 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-analysis

Author: Florian Mayer (fmayer)

<details>
<summary>Changes</summary>

This makes it easier to write the initialization function, because the
callee does not have to find out the type again.


---
Full diff: https://github.com/llvm/llvm-project/pull/164030.diff


3 Files Affected:

- (modified) clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h (+18-2) 
- (modified) clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h (+26-4) 
- (modified) clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp (+18) 


``````````diff
diff --git a/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h b/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h
index 6496771ad037e..4e316aaf09bdb 100644
--- a/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h
+++ b/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h
@@ -73,6 +73,10 @@ template <typename Base> class CachedConstAccessorsLattice : public Base {
   ///
   ///  - `Callee` should return a location (return type is a reference type or a
   ///     record type).
+  StorageLocation &getOrCreateConstMethodReturnStorageLocation(
+      const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
+      Environment &Env,
+      llvm::function_ref<void(QualType, StorageLocation &)> Initialize);
   StorageLocation &getOrCreateConstMethodReturnStorageLocation(
       const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
       Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize);
@@ -196,7 +200,8 @@ template <typename Base>
 StorageLocation &
 CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
     const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
-    Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize) {
+    Environment &Env,
+    llvm::function_ref<void(QualType, StorageLocation &)> Initialize) {
   assert(Callee != nullptr);
   QualType Type = Callee->getReturnType();
   assert(!Type.isNull());
@@ -206,13 +211,24 @@ CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
   if (it != ObjMap.end())
     return *it->second;
 
+  auto T = Type.getNonReferenceType();
   StorageLocation &Loc = Env.createStorageLocation(Type.getNonReferenceType());
-  Initialize(Loc);
+  Initialize(T, Loc);
 
   ObjMap.insert({Callee, &Loc});
   return Loc;
 }
 
+template <typename Base>
+StorageLocation &
+CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
+    const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
+    Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize) {
+  return getOrCreateConstMethodReturnStorageLocation(
+      RecordLoc, Callee, Env,
+      [Initialize](QualType T, StorageLocation &Loc) { Initialize(Loc); });
+}
+
 } // namespace dataflow
 } // namespace clang
 
diff --git a/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h b/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h
index e55b83aa845d4..b5bdff2df8ed6 100644
--- a/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h
+++ b/clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h
@@ -91,7 +91,18 @@ template <typename LatticeT>
 void transferSmartPointerLikeCachedDeref(
     const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
     TransferState<LatticeT> &State,
-    llvm::function_ref<void(StorageLocation &)> InitializeLoc);
+    llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc);
+template <typename LatticeT>
+void transferSmartPointerLikeCachedDeref(
+    const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
+    TransferState<LatticeT> &State,
+    llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
+  transferSmartPointerLikeCachedDeref<LatticeT>(
+      DerefExpr, SmartPointerLoc, State,
+      [InitializeLoc](QualType T, StorageLocation &Loc) {
+        InitializeLoc(Loc);
+      });
+}
 
 /// A transfer function for `operator->` (and `get`) calls that can be cached.
 /// Runs the `InitializeLoc` callback to initialize any new StorageLocations.
@@ -103,13 +114,24 @@ template <typename LatticeT>
 void transferSmartPointerLikeCachedGet(
     const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
     TransferState<LatticeT> &State,
-    llvm::function_ref<void(StorageLocation &)> InitializeLoc);
+    llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc);
+template <typename LatticeT>
+void transferSmartPointerLikeCachedGet(
+    const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
+    TransferState<LatticeT> &State,
+    llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
+  transferSmartPointerLikeCachedGet<LatticeT>(
+      GetExpr, SmartPointerLoc, State,
+      [InitializeLoc](QualType T, StorageLocation &Loc) {
+        InitializeLoc(Loc);
+      });
+}
 
 template <typename LatticeT>
 void transferSmartPointerLikeCachedDeref(
     const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
     TransferState<LatticeT> &State,
-    llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
+    llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc) {
   if (State.Env.getStorageLocation(*DerefExpr) != nullptr)
     return;
   if (SmartPointerLoc == nullptr)
@@ -145,7 +167,7 @@ template <typename LatticeT>
 void transferSmartPointerLikeCachedGet(
     const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
     TransferState<LatticeT> &State,
-    llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
+    llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc) {
   if (SmartPointerLoc == nullptr)
     return;
 
diff --git a/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp b/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp
index 67b471e328b5e..5a195ed6cfc32 100644
--- a/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp
@@ -307,5 +307,23 @@ TEST_F(CachedConstAccessorsLatticeTest, ProducesNewValueAfterJoinDistinct) {
   EXPECT_NE(ValAfterJoin2, Val3);
 }
 
+TEST_F(CachedConstAccessorsLatticeTest, TypePassed) {
+  CommonTestInputs Inputs;
+  auto *CE = Inputs.CallRef;
+  RecordStorageLocation Loc(Inputs.SType, RecordStorageLocation::FieldToLoc(),
+                            {});
+
+  LatticeT Lattice;
+
+  const FunctionDecl *Callee = CE->getDirectCallee();
+  auto RetType = Callee->getReturnType().getNonReferenceType();
+  auto CheckedInit = [RetType](QualType T, StorageLocation &) {
+    ASSERT_EQ(T, RetType);
+  };
+  ASSERT_NE(Callee, nullptr);
+  Lattice.getOrCreateConstMethodReturnStorageLocation(Loc, Callee, Env,
+                                                      CheckedInit);
+}
+
 } // namespace
 } // namespace clang::dataflow

``````````

</details>


https://github.com/llvm/llvm-project/pull/164030


More information about the cfe-commits mailing list