#include "Move.h"
#include "clang/AST/Attr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "llvm/ADT/StringSet.h"
usingnamespaceclang;
usingnamespaceento;
namespace {
struct RegionState { … };
}
namespace {
class MoveChecker
: public Checker<check::PreCall, check::PostCall,
check::DeadSymbols, check::RegionChanges> { … };
}
REGISTER_MAP_WITH_PROGRAMSTATE(…) …
namespace clang {
namespace ento {
namespace move {
bool isMovedFrom(ProgramStateRef State, const MemRegion *Region) { … }
}
}
}
static ProgramStateRef removeFromState(ProgramStateRef State,
const MemRegion *Region) { … }
static bool isAnyBaseRegionReported(ProgramStateRef State,
const MemRegion *Region) { … }
static const MemRegion *unwrapRValueReferenceIndirection(const MemRegion *MR) { … }
PathDiagnosticPieceRef
MoveChecker::MovedBugVisitor::VisitNode(const ExplodedNode *N,
BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
const ExplodedNode *MoveChecker::getMoveLocation(const ExplodedNode *N,
const MemRegion *Region,
CheckerContext &C) const { … }
void MoveChecker::modelUse(ProgramStateRef State, const MemRegion *Region,
const CXXRecordDecl *RD, MisuseKind MK,
CheckerContext &C) const { … }
ExplodedNode *MoveChecker::tryToReportBug(const MemRegion *Region,
const CXXRecordDecl *RD,
CheckerContext &C,
MisuseKind MK) const { … }
void MoveChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const { … }
bool MoveChecker::isMoveSafeMethod(const CXXMethodDecl *MethodDec) const { … }
bool MoveChecker::isStateResetMethod(const CXXMethodDecl *MethodDec) const { … }
bool MoveChecker::isInMoveSafeContext(const LocationContext *LC) const { … }
bool MoveChecker::belongsTo(const CXXRecordDecl *RD,
const llvm::StringSet<> &Set) const { … }
MoveChecker::ObjectKind
MoveChecker::classifyObject(const MemRegion *MR,
const CXXRecordDecl *RD) const { … }
void MoveChecker::explainObject(llvm::raw_ostream &OS, const MemRegion *MR,
const CXXRecordDecl *RD, MisuseKind MK) const { … }
void MoveChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { … }
void MoveChecker::checkDeadSymbols(SymbolReaper &SymReaper,
CheckerContext &C) const { … }
ProgramStateRef MoveChecker::checkRegionChanges(
ProgramStateRef State, const InvalidatedSymbols *Invalidated,
ArrayRef<const MemRegion *> RequestedRegions,
ArrayRef<const MemRegion *> InvalidatedRegions,
const LocationContext *LCtx, const CallEvent *Call) const { … }
void MoveChecker::printState(raw_ostream &Out, ProgramStateRef State,
const char *NL, const char *Sep) const { … }
void ento::registerMoveChecker(CheckerManager &mgr) { … }
bool ento::shouldRegisterMoveChecker(const CheckerManager &mgr) { … }