summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Mayer <fmayer@google.com>2025-10-17 16:11:37 -0700
committerFlorian Mayer <fmayer@google.com>2025-10-17 16:11:37 -0700
commit69f4dd94804d72f7f44941d5c0b7395b429c4422 (patch)
tree7ee6140abc7d8d1c81de6a7598b9c60ef5118fe8
parent01c0cb928a2e9df72fd68942143bf5d4041d38ed (diff)
[𝘀𝗽𝗿] changes to main this commit is based onusers/fmayer/spr/main.flowsensitive-ptrcaching-add-issmartpointerlikeconstructor
Created using spr 1.3.7 [skip ci]
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h20
-rw-r--r--clang/include/clang/Analysis/FlowSensitive/SmartPointerAccessorCaching.h30
-rw-r--r--clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp18
3 files changed, 62 insertions, 6 deletions
diff --git a/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h b/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h
index 6496771ad037..4e316aaf09bd 100644
--- a/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h
+++ b/clang/include/clang/Analysis/FlowSensitive/CachedConstAccessorsLattice.h
@@ -75,6 +75,10 @@ public:
/// 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);
void clearConstMethodReturnValues(const RecordStorageLocation &RecordLoc) {
@@ -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 e55b83aa845d..b5bdff2df8ed 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 67b471e328b5..5a195ed6cfc3 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