Index: include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- include/clang/StaticAnalyzer/Checkers/Checkers.td +++ include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -300,16 +300,15 @@ 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">; Index: lib/StaticAnalyzer/Checkers/AllocationState.h =================================================================== --- lib/StaticAnalyzer/Checkers/AllocationState.h +++ lib/StaticAnalyzer/Checkers/AllocationState.h @@ -23,8 +23,8 @@ /// 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 getDanglingBufferBRVisitor(SymbolRef Sym); +/// AF_InnerBuffer symbols. +std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym); } // end namespace allocation_state Index: lib/StaticAnalyzer/Checkers/CMakeLists.txt =================================================================== --- lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -27,7 +27,6 @@ CloneChecker.cpp ConversionChecker.cpp CXXSelfAssignmentChecker.cpp - DanglingInternalBufferChecker.cpp DeadStoresChecker.cpp DebugCheckers.cpp DeleteWithNonVirtualDtorChecker.cpp @@ -42,6 +41,7 @@ GenericTaintChecker.cpp GTestChecker.cpp IdenticalExprChecker.cpp + InnerPointerChecker.cpp IteratorChecker.cpp IvarInvalidationChecker.cpp LLVMConventionsChecker.cpp Index: lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp +++ lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp @@ -1,4 +1,4 @@ -//=== DanglingInternalBufferChecker.cpp ---------------------------*- C++ -*--// +//=== InnerPointerChecker.cpp -------------------------------------*- C++ -*--// // // The LLVM Compiler Infrastructure // @@ -44,7 +44,7 @@ namespace { -class DanglingInternalBufferChecker +class InnerPointerChecker : public Checker { CallDescription AppendFn, AssignFn, ClearFn, CStrFn, DataFn, EraseFn, @@ -52,11 +52,11 @@ 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 @@ } }; - 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 @@ // -- 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(&Call)) { OverloadedOperatorKind Opc = MemOpCall->getOriginExpr()->getOperator(); if (Opc == OO_Equal || Opc == OO_PlusEqual) @@ -138,8 +137,8 @@ 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(&Call); if (!ICall) return; @@ -187,8 +186,8 @@ } } -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(); RawPtrMapTy RPM = State->get(); @@ -213,9 +212,10 @@ } std::shared_ptr -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 ento { namespace allocation_state { -std::unique_ptr getDanglingBufferBRVisitor(SymbolRef Sym) { - return llvm::make_unique< - DanglingInternalBufferChecker::DanglingBufferBRVisitor>(Sym); +std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym) { + return llvm::make_unique(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(); + Mgr.registerChecker(); } Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -47,7 +47,7 @@ AF_CXXNewArray, AF_IfNameIndex, AF_Alloca, - AF_InternalBuffer + AF_InnerBuffer }; class RefState { @@ -485,7 +485,7 @@ (!SPrev || !SPrev->isReleased()); assert(!IsReleased || (Stmt && (isa(Stmt) || isa(Stmt))) || - (!Stmt && S->getAllocationFamily() == AF_InternalBuffer)); + (!Stmt && S->getAllocationFamily() == AF_InnerBuffer)); return IsReleased; } @@ -1473,7 +1473,7 @@ 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 @@ 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 @@ } 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 @@ R->addVisitor(llvm::make_unique(Sym)); const RefState *RS = C.getState()->get(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 @@ 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 @@ 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 @@ 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 @@ // Generate the extra diagnostic. PathDiagnosticLocation Pos; if (!S) { - assert(RS->getAllocationFamily() == AF_InternalBuffer); + assert(RS->getAllocationFamily() == AF_InnerBuffer); auto PostImplCall = N->getLocation().getAs(); if (!PostImplCall) return nullptr; @@ -3055,7 +3055,7 @@ ProgramStateRef markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) { - AllocationFamily Family = AF_InternalBuffer; + AllocationFamily Family = AF_InnerBuffer; return State->set(Sym, RefState::getReleased(Family, Origin)); } Index: test/Analysis/inner-pointer.cpp =================================================================== --- test/Analysis/inner-pointer.cpp +++ test/Analysis/inner-pointer.cpp @@ -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 {