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 | |
40 | PathDiagnosticPieceRef maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R, |
41 | const ObjCMethodCall &Call, |
42 | const ExplodedNode *N) final { |
43 | // TODO: Implement. |
44 | return nullptr; |
45 | } |
46 | |
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: |
66 | NoOwnershipChangeVisitor(SymbolRef Sym, const CheckerBase *Checker) |
67 | : NoStateChangeFuncVisitor(bugreporter::TrackingKind::Thorough), Sym(Sym), |
68 | Checker(*Checker) {} |
69 | |
70 | void Profile(llvm::FoldingSetNodeID &ID) const override { |
71 | static int Tag = 0; |
72 | ID.AddPointer(Ptr: &Tag); |
73 | ID.AddPointer(Ptr: Sym); |
74 | } |
75 | }; |
76 | } // namespace ento |
77 | } // namespace clang |
78 | |