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
|