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