xref: /llvm-project/clang/lib/StaticAnalyzer/Checkers/NoOwnershipChangeVisitor.h (revision e622996eddfb2826d258b3a3760eed195f97aabe)
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