[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