diff options
| author | Florian Mayer <fmayer@google.com> | 2025-10-17 16:11:37 -0700 |
|---|---|---|
| committer | Florian Mayer <fmayer@google.com> | 2025-10-17 16:11:37 -0700 |
| commit | 69f4dd94804d72f7f44941d5c0b7395b429c4422 (patch) | |
| tree | 7ee6140abc7d8d1c81de6a7598b9c60ef5118fe8 | |
| parent | 01c0cb928a2e9df72fd68942143bf5d4041d38ed (diff) | |
[𝘀𝗽𝗿] changes to main this commit is based onusers/fmayer/spr/main.flowsensitive-ptrcaching-add-issmartpointerlikeconstructor
Created using spr 1.3.7
[skip ci]
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 |
