diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp index c789a8dbcca1..92eef20d2daa 100644 --- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -48,9 +48,8 @@ class SmartPtrModeling public: // Whether the checker should model for null dereferences of smart pointers. - DefaultBool ModelSmartPtrDereference; + bool ModelSmartPtrDereference = false; bool evalCall(const CallEvent &Call, CheckerContext &C) const; - void checkPreCall(const CallEvent &Call, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; ProgramStateRef checkRegionChanges(ProgramStateRef State, @@ -71,7 +70,8 @@ private: bool handleMoveCtr(const CallEvent &Call, CheckerContext &C, const MemRegion *ThisRegion) const; bool updateMovedSmartPointers(CheckerContext &C, const MemRegion *ThisRegion, - const MemRegion *OtherSmartPtrRegion) const; + const MemRegion *OtherSmartPtrRegion, + const CallEvent &Call) const; void handleBoolConversion(const CallEvent &Call, CheckerContext &C) const; bool handleComparisionOp(const CallEvent &Call, CheckerContext &C) const; bool handleOstreamOperator(const CallEvent &Call, CheckerContext &C) const; @@ -379,11 +379,13 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call, if (!ThisRegion) return false; + QualType ThisType = cast<CXXMethodDecl>(Call.getDecl())->getThisType(); + if (CC->getDecl()->isMoveConstructor()) return handleMoveCtr(Call, C, ThisRegion); if (Call.getNumArgs() == 0) { - auto NullVal = C.getSValBuilder().makeNull(); + auto NullVal = C.getSValBuilder().makeNullWithType(ThisType); State = State->set<TrackedRegionMap>(ThisRegion, NullVal); C.addTransition( @@ -640,7 +642,8 @@ void SmartPtrModeling::handleRelease(const CallEvent &Call, *InnerPointVal); } - auto ValueToUpdate = C.getSValBuilder().makeNull(); + QualType ThisType = cast<CXXMethodDecl>(Call.getDecl())->getThisType(); + auto ValueToUpdate = C.getSValBuilder().makeNullWithType(ThisType); State = State->set<TrackedRegionMap>(ThisRegion, ValueToUpdate); C.addTransition(State, C.getNoteTag([ThisRegion](PathSensitiveBugReport &BR, @@ -738,13 +741,15 @@ bool SmartPtrModeling::handleAssignOp(const CallEvent &Call, if (!ThisRegion) return false; + QualType ThisType = cast<CXXMethodDecl>(Call.getDecl())->getThisType(); + const MemRegion *OtherSmartPtrRegion = OC->getArgSVal(0).getAsRegion(); // In case of 'nullptr' or '0' assigned if (!OtherSmartPtrRegion) { bool AssignedNull = Call.getArgSVal(0).isZeroConstant(); if (!AssignedNull) return false; - auto NullVal = C.getSValBuilder().makeNull(); + auto NullVal = C.getSValBuilder().makeNullWithType(ThisType); State = State->set<TrackedRegionMap>(ThisRegion, NullVal); C.addTransition(State, C.getNoteTag([ThisRegion](PathSensitiveBugReport &BR, llvm::raw_ostream &OS) { @@ -758,7 +763,7 @@ bool SmartPtrModeling::handleAssignOp(const CallEvent &Call, return true; } - return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion); + return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion, Call); } bool SmartPtrModeling::handleMoveCtr(const CallEvent &Call, CheckerContext &C, @@ -767,17 +772,19 @@ bool SmartPtrModeling::handleMoveCtr(const CallEvent &Call, CheckerContext &C, if (!OtherSmartPtrRegion) return false; - return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion); + return updateMovedSmartPointers(C, ThisRegion, OtherSmartPtrRegion, Call); } bool SmartPtrModeling::updateMovedSmartPointers( CheckerContext &C, const MemRegion *ThisRegion, - const MemRegion *OtherSmartPtrRegion) const { + const MemRegion *OtherSmartPtrRegion, const CallEvent &Call) const { ProgramStateRef State = C.getState(); + QualType ThisType = cast<CXXMethodDecl>(Call.getDecl())->getThisType(); const auto *OtherInnerPtr = State->get<TrackedRegionMap>(OtherSmartPtrRegion); if (OtherInnerPtr) { State = State->set<TrackedRegionMap>(ThisRegion, *OtherInnerPtr); - auto NullVal = C.getSValBuilder().makeNull(); + + auto NullVal = C.getSValBuilder().makeNullWithType(ThisType); State = State->set<TrackedRegionMap>(OtherSmartPtrRegion, NullVal); bool IsArgValNull = OtherInnerPtr->isZeroConstant(); @@ -803,7 +810,8 @@ bool SmartPtrModeling::updateMovedSmartPointers( } else { // In case we dont know anything about value we are moving from // remove the entry from map for which smart pointer got moved to. - auto NullVal = C.getSValBuilder().makeNull(); + // For unique_ptr<A>, Ty will be 'A*'. + auto NullVal = C.getSValBuilder().makeNullWithType(ThisType); State = State->remove<TrackedRegionMap>(ThisRegion); State = State->set<TrackedRegionMap>(OtherSmartPtrRegion, NullVal); C.addTransition(State, C.getNoteTag([OtherSmartPtrRegion, @@ -830,6 +838,8 @@ void SmartPtrModeling::handleBoolConversion(const CallEvent &Call, const MemRegion *ThisRegion = cast<CXXInstanceCall>(&Call)->getCXXThisVal().getAsRegion(); + QualType ThisType = cast<CXXMethodDecl>(Call.getDecl())->getThisType(); + SVal InnerPointerVal; if (const auto *InnerValPtr = State->get<TrackedRegionMap>(ThisRegion)) { InnerPointerVal = *InnerValPtr; @@ -868,7 +878,7 @@ void SmartPtrModeling::handleBoolConversion(const CallEvent &Call, std::tie(NotNullState, NullState) = State->assume(InnerPointerVal.castAs<DefinedOrUnknownSVal>()); - auto NullVal = C.getSValBuilder().makeNull(); + auto NullVal = C.getSValBuilder().makeNullWithType(ThisType); // Explicitly tracking the region as null. NullState = NullState->set<TrackedRegionMap>(ThisRegion, NullVal); |
