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