RedDocMD created this revision. RedDocMD added reviewers: NoQ, vsavchenko, xazax.hun, teemperor. Herald added subscribers: manas, steakhal, ASDenysPetrov, martong, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware. RedDocMD requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This patch handles all the comparision methods (defined via overloaded operators) on std::unique_ptr. These operators compare the underlying pointers, which makes it difficult to model the result. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D104616 Files: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -68,6 +68,7 @@ bool updateMovedSmartPointers(CheckerContext &C, const MemRegion *ThisRegion, const MemRegion *OtherSmartPtrRegion) const; void handleBoolConversion(const CallEvent &Call, CheckerContext &C) const; + bool handleComparisionOp(const CallEvent &Call, CheckerContext &C) const; using SmartPtrMethodHandlerFn = void (SmartPtrModeling::*)(const CallEvent &Call, CheckerContext &) const; @@ -264,6 +265,9 @@ if (handleAssignOp(Call, C)) return true; + if (handleComparisionOp(Call, C)) + return true; + const SmartPtrMethodHandlerFn *Handler = SmartPtrMethodHandlers.lookup(Call); if (!Handler) return false; @@ -272,6 +276,26 @@ return C.isDifferent(); } +bool SmartPtrModeling::handleComparisionOp(const CallEvent &Call, + CheckerContext &C) const { + const auto *MC = llvm::dyn_cast<CXXMemberOperatorCall>(&Call); + if (!MC) + return false; + const OverloadedOperatorKind OOK = MC->getOverloadedOperator(); + if (!(OOK == OO_Equal || OOK == OO_ExclaimEqual || OOK == OO_Less || + OOK == OO_LessEqual || OOK == OO_Greater || OOK == OO_GreaterEqual || + OOK == OO_Spaceship)) + return false; + + // TODO: We had better put some useful modelling here. + // But the problem is that all these operators act on the raw + // inner pointer (there are special cases for comparision with nullptr). + // So, we are not really comparing the value pointed to by the pointer + // but the *pointer* itself, which is just an address, which is not + // something that symbolic evaluation is concerned about. + return true; +} + void SmartPtrModeling::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState();
Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -68,6 +68,7 @@ bool updateMovedSmartPointers(CheckerContext &C, const MemRegion *ThisRegion, const MemRegion *OtherSmartPtrRegion) const; void handleBoolConversion(const CallEvent &Call, CheckerContext &C) const; + bool handleComparisionOp(const CallEvent &Call, CheckerContext &C) const; using SmartPtrMethodHandlerFn = void (SmartPtrModeling::*)(const CallEvent &Call, CheckerContext &) const; @@ -264,6 +265,9 @@ if (handleAssignOp(Call, C)) return true; + if (handleComparisionOp(Call, C)) + return true; + const SmartPtrMethodHandlerFn *Handler = SmartPtrMethodHandlers.lookup(Call); if (!Handler) return false; @@ -272,6 +276,26 @@ return C.isDifferent(); } +bool SmartPtrModeling::handleComparisionOp(const CallEvent &Call, + CheckerContext &C) const { + const auto *MC = llvm::dyn_cast<CXXMemberOperatorCall>(&Call); + if (!MC) + return false; + const OverloadedOperatorKind OOK = MC->getOverloadedOperator(); + if (!(OOK == OO_Equal || OOK == OO_ExclaimEqual || OOK == OO_Less || + OOK == OO_LessEqual || OOK == OO_Greater || OOK == OO_GreaterEqual || + OOK == OO_Spaceship)) + return false; + + // TODO: We had better put some useful modelling here. + // But the problem is that all these operators act on the raw + // inner pointer (there are special cases for comparision with nullptr). + // So, we are not really comparing the value pointed to by the pointer + // but the *pointer* itself, which is just an address, which is not + // something that symbolic evaluation is concerned about. + return true; +} + void SmartPtrModeling::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { ProgramStateRef State = C.getState();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits