[analyzer] Rename DanglingInternalBufferChecker to InnerPointerChecker.
Differential Revision: https://reviews.llvm.org/D49553 llvm-svn: 337559
This commit is contained in:
parent
8342126c4e
commit
88ad704b5b
|
@ -300,16 +300,15 @@ def VirtualCallChecker : Checker<"VirtualCall">,
|
|||
|
||||
let ParentPackage = CplusplusAlpha in {
|
||||
|
||||
def DanglingInternalBufferChecker : Checker<"DanglingInternalBuffer">,
|
||||
HelpText<"Check for internal raw pointers of C++ standard library containers "
|
||||
"used after deallocation">,
|
||||
DescFile<"DanglingInternalBufferChecker.cpp">;
|
||||
|
||||
def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
|
||||
HelpText<"Reports destructions of polymorphic objects with a non-virtual "
|
||||
"destructor in their base class">,
|
||||
DescFile<"DeleteWithNonVirtualDtorChecker.cpp">;
|
||||
|
||||
def InnerPointerChecker : Checker<"InnerPointer">,
|
||||
HelpText<"Check for inner pointers of C++ containers used after re/deallocation">,
|
||||
DescFile<"InnerPointerChecker.cpp">;
|
||||
|
||||
def IteratorRangeChecker : Checker<"IteratorRange">,
|
||||
HelpText<"Check for iterators used outside their valid ranges">,
|
||||
DescFile<"IteratorChecker.cpp">;
|
||||
|
|
|
@ -23,8 +23,8 @@ ProgramStateRef markReleased(ProgramStateRef State, SymbolRef Sym,
|
|||
|
||||
/// This function provides an additional visitor that augments the bug report
|
||||
/// with information relevant to memory errors caused by the misuse of
|
||||
/// AF_InternalBuffer symbols.
|
||||
std::unique_ptr<BugReporterVisitor> getDanglingBufferBRVisitor(SymbolRef Sym);
|
||||
/// AF_InnerBuffer symbols.
|
||||
std::unique_ptr<BugReporterVisitor> getInnerPointerBRVisitor(SymbolRef Sym);
|
||||
|
||||
} // end namespace allocation_state
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ add_clang_library(clangStaticAnalyzerCheckers
|
|||
CloneChecker.cpp
|
||||
ConversionChecker.cpp
|
||||
CXXSelfAssignmentChecker.cpp
|
||||
DanglingInternalBufferChecker.cpp
|
||||
DeadStoresChecker.cpp
|
||||
DebugCheckers.cpp
|
||||
DeleteWithNonVirtualDtorChecker.cpp
|
||||
|
@ -42,6 +41,7 @@ add_clang_library(clangStaticAnalyzerCheckers
|
|||
GenericTaintChecker.cpp
|
||||
GTestChecker.cpp
|
||||
IdenticalExprChecker.cpp
|
||||
InnerPointerChecker.cpp
|
||||
IteratorChecker.cpp
|
||||
IvarInvalidationChecker.cpp
|
||||
LLVMConventionsChecker.cpp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//=== DanglingInternalBufferChecker.cpp ---------------------------*- C++ -*--//
|
||||
//=== InnerPointerChecker.cpp -------------------------------------*- C++ -*--//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -44,7 +44,7 @@ struct ProgramStateTrait<PtrSet> : public ProgramStatePartialTrait<PtrSet> {
|
|||
|
||||
namespace {
|
||||
|
||||
class DanglingInternalBufferChecker
|
||||
class InnerPointerChecker
|
||||
: public Checker<check::DeadSymbols, check::PostCall> {
|
||||
|
||||
CallDescription AppendFn, AssignFn, ClearFn, CStrFn, DataFn, EraseFn,
|
||||
|
@ -52,11 +52,11 @@ class DanglingInternalBufferChecker
|
|||
ShrinkToFitFn, SwapFn;
|
||||
|
||||
public:
|
||||
class DanglingBufferBRVisitor : public BugReporterVisitor {
|
||||
class InnerPointerBRVisitor : public BugReporterVisitor {
|
||||
SymbolRef PtrToBuf;
|
||||
|
||||
public:
|
||||
DanglingBufferBRVisitor(SymbolRef Sym) : PtrToBuf(Sym) {}
|
||||
InnerPointerBRVisitor(SymbolRef Sym) : PtrToBuf(Sym) {}
|
||||
|
||||
static void *getTag() {
|
||||
static int Tag = 0;
|
||||
|
@ -84,7 +84,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
DanglingInternalBufferChecker()
|
||||
InnerPointerChecker()
|
||||
: AppendFn("append"), AssignFn("assign"), ClearFn("clear"),
|
||||
CStrFn("c_str"), DataFn("data"), EraseFn("erase"), InsertFn("insert"),
|
||||
PopBackFn("pop_back"), PushBackFn("push_back"), ReplaceFn("replace"),
|
||||
|
@ -121,8 +121,7 @@ public:
|
|||
// -- Calling non-const member functions, except operator[], at, front, back,
|
||||
// begin, rbegin, end, and rend."
|
||||
//
|
||||
bool DanglingInternalBufferChecker::mayInvalidateBuffer(
|
||||
const CallEvent &Call) const {
|
||||
bool InnerPointerChecker::mayInvalidateBuffer(const CallEvent &Call) const {
|
||||
if (const auto *MemOpCall = dyn_cast<CXXMemberOperatorCall>(&Call)) {
|
||||
OverloadedOperatorKind Opc = MemOpCall->getOriginExpr()->getOperator();
|
||||
if (Opc == OO_Equal || Opc == OO_PlusEqual)
|
||||
|
@ -138,8 +137,8 @@ bool DanglingInternalBufferChecker::mayInvalidateBuffer(
|
|||
Call.isCalled(SwapFn));
|
||||
}
|
||||
|
||||
void DanglingInternalBufferChecker::checkPostCall(const CallEvent &Call,
|
||||
CheckerContext &C) const {
|
||||
void InnerPointerChecker::checkPostCall(const CallEvent &Call,
|
||||
CheckerContext &C) const {
|
||||
const auto *ICall = dyn_cast<CXXInstanceCall>(&Call);
|
||||
if (!ICall)
|
||||
return;
|
||||
|
@ -187,8 +186,8 @@ void DanglingInternalBufferChecker::checkPostCall(const CallEvent &Call,
|
|||
}
|
||||
}
|
||||
|
||||
void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||
CheckerContext &C) const {
|
||||
void InnerPointerChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
||||
CheckerContext &C) const {
|
||||
ProgramStateRef State = C.getState();
|
||||
PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>();
|
||||
RawPtrMapTy RPM = State->get<RawPtrMap>();
|
||||
|
@ -213,9 +212,10 @@ void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
|||
}
|
||||
|
||||
std::shared_ptr<PathDiagnosticPiece>
|
||||
DanglingInternalBufferChecker::DanglingBufferBRVisitor::VisitNode(
|
||||
const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
|
||||
BugReport &BR) {
|
||||
InnerPointerChecker::InnerPointerBRVisitor::VisitNode(const ExplodedNode *N,
|
||||
const ExplodedNode *PrevN,
|
||||
BugReporterContext &BRC,
|
||||
BugReport &BR) {
|
||||
|
||||
if (!isSymbolTracked(N->getState(), PtrToBuf) ||
|
||||
isSymbolTracked(PrevN->getState(), PtrToBuf))
|
||||
|
@ -238,16 +238,15 @@ namespace clang {
|
|||
namespace ento {
|
||||
namespace allocation_state {
|
||||
|
||||
std::unique_ptr<BugReporterVisitor> getDanglingBufferBRVisitor(SymbolRef Sym) {
|
||||
return llvm::make_unique<
|
||||
DanglingInternalBufferChecker::DanglingBufferBRVisitor>(Sym);
|
||||
std::unique_ptr<BugReporterVisitor> getInnerPointerBRVisitor(SymbolRef Sym) {
|
||||
return llvm::make_unique<InnerPointerChecker::InnerPointerBRVisitor>(Sym);
|
||||
}
|
||||
|
||||
} // end namespace allocation_state
|
||||
} // end namespace ento
|
||||
} // end namespace clang
|
||||
|
||||
void ento::registerDanglingInternalBufferChecker(CheckerManager &Mgr) {
|
||||
void ento::registerInnerPointerChecker(CheckerManager &Mgr) {
|
||||
registerNewDeleteChecker(Mgr);
|
||||
Mgr.registerChecker<DanglingInternalBufferChecker>();
|
||||
Mgr.registerChecker<InnerPointerChecker>();
|
||||
}
|
|
@ -47,7 +47,7 @@ enum AllocationFamily {
|
|||
AF_CXXNewArray,
|
||||
AF_IfNameIndex,
|
||||
AF_Alloca,
|
||||
AF_InternalBuffer
|
||||
AF_InnerBuffer
|
||||
};
|
||||
|
||||
class RefState {
|
||||
|
@ -485,7 +485,7 @@ private:
|
|||
(!SPrev || !SPrev->isReleased());
|
||||
assert(!IsReleased ||
|
||||
(Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt))) ||
|
||||
(!Stmt && S->getAllocationFamily() == AF_InternalBuffer));
|
||||
(!Stmt && S->getAllocationFamily() == AF_InnerBuffer));
|
||||
return IsReleased;
|
||||
}
|
||||
|
||||
|
@ -1473,7 +1473,7 @@ void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
|
|||
case AF_CXXNew: os << "'new'"; return;
|
||||
case AF_CXXNewArray: os << "'new[]'"; return;
|
||||
case AF_IfNameIndex: os << "'if_nameindex()'"; return;
|
||||
case AF_InternalBuffer: os << "container-specific allocator"; return;
|
||||
case AF_InnerBuffer: os << "container-specific allocator"; return;
|
||||
case AF_Alloca:
|
||||
case AF_None: llvm_unreachable("not a deallocation expression");
|
||||
}
|
||||
|
@ -1486,7 +1486,7 @@ void MallocChecker::printExpectedDeallocName(raw_ostream &os,
|
|||
case AF_CXXNew: os << "'delete'"; return;
|
||||
case AF_CXXNewArray: os << "'delete[]'"; return;
|
||||
case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
|
||||
case AF_InternalBuffer: os << "container-specific deallocator"; return;
|
||||
case AF_InnerBuffer: os << "container-specific deallocator"; return;
|
||||
case AF_Alloca:
|
||||
case AF_None: llvm_unreachable("suspicious argument");
|
||||
}
|
||||
|
@ -1662,8 +1662,8 @@ MallocChecker::getCheckIfTracked(AllocationFamily Family,
|
|||
}
|
||||
case AF_CXXNew:
|
||||
case AF_CXXNewArray:
|
||||
// FIXME: Add new CheckKind for AF_InternalBuffer.
|
||||
case AF_InternalBuffer: {
|
||||
// FIXME: Add new CheckKind for AF_InnerBuffer.
|
||||
case AF_InnerBuffer: {
|
||||
if (IsALeakCheck) {
|
||||
if (ChecksEnabled[CK_NewDeleteLeaksChecker])
|
||||
return CK_NewDeleteLeaksChecker;
|
||||
|
@ -1995,8 +1995,8 @@ void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
|
|||
R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
|
||||
|
||||
const RefState *RS = C.getState()->get<RegionState>(Sym);
|
||||
if (RS->getAllocationFamily() == AF_InternalBuffer)
|
||||
R->addVisitor(allocation_state::getDanglingBufferBRVisitor(Sym));
|
||||
if (RS->getAllocationFamily() == AF_InnerBuffer)
|
||||
R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym));
|
||||
|
||||
C.emitReport(std::move(R));
|
||||
}
|
||||
|
@ -2870,7 +2870,7 @@ std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
|
|||
const Stmt *S = PathDiagnosticLocation::getStmt(N);
|
||||
// When dealing with containers, we sometimes want to give a note
|
||||
// even if the statement is missing.
|
||||
if (!S && (!RS || RS->getAllocationFamily() != AF_InternalBuffer))
|
||||
if (!S && (!RS || RS->getAllocationFamily() != AF_InnerBuffer))
|
||||
return nullptr;
|
||||
|
||||
const LocationContext *CurrentLC = N->getLocationContext();
|
||||
|
@ -2903,7 +2903,7 @@ std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
|
|||
StackHintGeneratorForSymbol *StackHint = nullptr;
|
||||
SmallString<256> Buf;
|
||||
llvm::raw_svector_ostream OS(Buf);
|
||||
|
||||
|
||||
if (Mode == Normal) {
|
||||
if (isAllocated(RS, RSPrev, S)) {
|
||||
Msg = "Memory is allocated";
|
||||
|
@ -2919,7 +2919,7 @@ std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
|
|||
case AF_IfNameIndex:
|
||||
Msg = "Memory is released";
|
||||
break;
|
||||
case AF_InternalBuffer: {
|
||||
case AF_InnerBuffer: {
|
||||
OS << "Inner pointer invalidated by call to ";
|
||||
if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) {
|
||||
OS << "destructor";
|
||||
|
@ -3011,7 +3011,7 @@ std::shared_ptr<PathDiagnosticPiece> MallocChecker::MallocBugVisitor::VisitNode(
|
|||
// Generate the extra diagnostic.
|
||||
PathDiagnosticLocation Pos;
|
||||
if (!S) {
|
||||
assert(RS->getAllocationFamily() == AF_InternalBuffer);
|
||||
assert(RS->getAllocationFamily() == AF_InnerBuffer);
|
||||
auto PostImplCall = N->getLocation().getAs<PostImplicitCall>();
|
||||
if (!PostImplCall)
|
||||
return nullptr;
|
||||
|
@ -3055,7 +3055,7 @@ namespace allocation_state {
|
|||
|
||||
ProgramStateRef
|
||||
markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) {
|
||||
AllocationFamily Family = AF_InternalBuffer;
|
||||
AllocationFamily Family = AF_InnerBuffer;
|
||||
return State->set<RegionState>(Sym, RefState::getReleased(Family, Origin));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.DanglingInternalBuffer %s -analyzer-output=text -verify
|
||||
//RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.InnerPointer %s -analyzer-output=text -verify
|
||||
|
||||
namespace std {
|
||||
|
Loading…
Reference in New Issue