1*e622996eSKristóf Umann //===--------------------------------------------------------------*- C++ -*--// 2*e622996eSKristóf Umann // 3*e622996eSKristóf Umann // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*e622996eSKristóf Umann // See https://llvm.org/LICENSE.txt for license information. 5*e622996eSKristóf Umann // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*e622996eSKristóf Umann // 7*e622996eSKristóf Umann //===----------------------------------------------------------------------===// 8*e622996eSKristóf Umann 9*e622996eSKristóf Umann #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" 10*e622996eSKristóf Umann #include "clang/StaticAnalyzer/Core/Checker.h" 11*e622996eSKristóf Umann #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" 12*e622996eSKristóf Umann 13*e622996eSKristóf Umann namespace clang { 14*e622996eSKristóf Umann namespace ento { 15*e622996eSKristóf Umann 16*e622996eSKristóf Umann class NoOwnershipChangeVisitor : public NoStateChangeFuncVisitor { 17*e622996eSKristóf Umann protected: 18*e622996eSKristóf Umann // The symbol whose (lack of) ownership change we are interested in. 19*e622996eSKristóf Umann SymbolRef Sym; 20*e622996eSKristóf Umann const CheckerBase &Checker; 21*e622996eSKristóf Umann 22*e622996eSKristóf Umann LLVM_DUMP_METHOD static std::string 23*e622996eSKristóf Umann getFunctionName(const ExplodedNode *CallEnterN); 24*e622996eSKristóf Umann 25*e622996eSKristóf Umann /// Heuristically guess whether the callee intended to free the resource. This 26*e622996eSKristóf Umann /// is done syntactically, because we are trying to argue about alternative 27*e622996eSKristóf Umann /// paths of execution, and as a consequence we don't have path-sensitive 28*e622996eSKristóf Umann /// information. 29*e622996eSKristóf Umann virtual bool doesFnIntendToHandleOwnership(const Decl *Callee, 30*e622996eSKristóf Umann ASTContext &ACtx) = 0; 31*e622996eSKristóf Umann 32*e622996eSKristóf Umann virtual bool hasResourceStateChanged(ProgramStateRef CallEnterState, 33*e622996eSKristóf Umann ProgramStateRef CallExitEndState) = 0; 34*e622996eSKristóf Umann 35*e622996eSKristóf Umann bool wasModifiedInFunction(const ExplodedNode *CallEnterN, 36*e622996eSKristóf Umann const ExplodedNode *CallExitEndN) final; 37*e622996eSKristóf Umann 38*e622996eSKristóf Umann virtual PathDiagnosticPieceRef emitNote(const ExplodedNode *N) = 0; 39*e622996eSKristóf Umann maybeEmitNoteForObjCSelf(PathSensitiveBugReport & R,const ObjCMethodCall & Call,const ExplodedNode * N)40*e622996eSKristóf Umann PathDiagnosticPieceRef maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R, 41*e622996eSKristóf Umann const ObjCMethodCall &Call, 42*e622996eSKristóf Umann const ExplodedNode *N) final { 43*e622996eSKristóf Umann // TODO: Implement. 44*e622996eSKristóf Umann return nullptr; 45*e622996eSKristóf Umann } 46*e622996eSKristóf Umann maybeEmitNoteForCXXThis(PathSensitiveBugReport & R,const CXXConstructorCall & Call,const ExplodedNode * N)47*e622996eSKristóf Umann PathDiagnosticPieceRef maybeEmitNoteForCXXThis(PathSensitiveBugReport &R, 48*e622996eSKristóf Umann const CXXConstructorCall &Call, 49*e622996eSKristóf Umann const ExplodedNode *N) final { 50*e622996eSKristóf Umann // TODO: Implement. 51*e622996eSKristóf Umann return nullptr; 52*e622996eSKristóf Umann } 53*e622996eSKristóf Umann 54*e622996eSKristóf Umann // Set this to final, effectively dispatch to emitNote. 55*e622996eSKristóf Umann PathDiagnosticPieceRef 56*e622996eSKristóf Umann maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call, 57*e622996eSKristóf Umann const ExplodedNode *N) final; 58*e622996eSKristóf Umann 59*e622996eSKristóf Umann public: 60*e622996eSKristóf Umann using OwnerSet = llvm::SmallPtrSet<const MemRegion *, 8>; 61*e622996eSKristóf Umann 62*e622996eSKristóf Umann private: 63*e622996eSKristóf Umann OwnerSet getOwnersAtNode(const ExplodedNode *N); 64*e622996eSKristóf Umann 65*e622996eSKristóf Umann public: NoOwnershipChangeVisitor(SymbolRef Sym,const CheckerBase * Checker)66*e622996eSKristóf Umann NoOwnershipChangeVisitor(SymbolRef Sym, const CheckerBase *Checker) 67*e622996eSKristóf Umann : NoStateChangeFuncVisitor(bugreporter::TrackingKind::Thorough), Sym(Sym), 68*e622996eSKristóf Umann Checker(*Checker) {} 69*e622996eSKristóf Umann Profile(llvm::FoldingSetNodeID & ID)70*e622996eSKristóf Umann void Profile(llvm::FoldingSetNodeID &ID) const override { 71*e622996eSKristóf Umann static int Tag = 0; 72*e622996eSKristóf Umann ID.AddPointer(&Tag); 73*e622996eSKristóf Umann ID.AddPointer(Sym); 74*e622996eSKristóf Umann } 75*e622996eSKristóf Umann }; 76*e622996eSKristóf Umann } // namespace ento 77*e622996eSKristóf Umann } // namespace clang 78