Author: rkovacs Date: Fri Jul 20 08:14:49 2018 New Revision: 337559 URL: http://llvm.org/viewvc/llvm-project?rev=337559&view=rev Log: [analyzer] Rename DanglingInternalBufferChecker to InnerPointerChecker.
Differential Revision: https://reviews.llvm.org/D49553 Added: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp - copied, changed from r337555, cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp cfe/trunk/test/Analysis/inner-pointer.cpp - copied, changed from r337555, cfe/trunk/test/Analysis/dangling-internal-buffer.cpp Removed: cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp cfe/trunk/test/Analysis/dangling-internal-buffer.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=337559&r1=337558&r2=337559&view=diff ============================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Fri Jul 20 08:14:49 2018 @@ -300,16 +300,15 @@ def VirtualCallChecker : Checker<"Virtua 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">; Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h?rev=337559&r1=337558&r2=337559&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h Fri Jul 20 08:14:49 2018 @@ -23,8 +23,8 @@ ProgramStateRef markReleased(ProgramStat /// 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 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=337559&r1=337558&r2=337559&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Fri Jul 20 08:14:49 2018 @@ -27,7 +27,6 @@ add_clang_library(clangStaticAnalyzerChe CloneChecker.cpp ConversionChecker.cpp CXXSelfAssignmentChecker.cpp - DanglingInternalBufferChecker.cpp DeadStoresChecker.cpp DebugCheckers.cpp DeleteWithNonVirtualDtorChecker.cpp @@ -42,6 +41,7 @@ add_clang_library(clangStaticAnalyzerChe GenericTaintChecker.cpp GTestChecker.cpp IdenticalExprChecker.cpp + InnerPointerChecker.cpp IteratorChecker.cpp IvarInvalidationChecker.cpp LLVMConventionsChecker.cpp Removed: cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=337558&view=auto ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp (removed) @@ -1,253 +0,0 @@ -//=== DanglingInternalBufferChecker.cpp ---------------------------*- C++ -*--// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a check that marks a raw pointer to a C++ container's -// inner buffer released when the object is destroyed. This information can -// be used by MallocChecker to detect use-after-free problems. -// -//===----------------------------------------------------------------------===// - -#include "AllocationState.h" -#include "ClangSACheckers.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" - -using namespace clang; -using namespace ento; - -using PtrSet = llvm::ImmutableSet<SymbolRef>; - -// Associate container objects with a set of raw pointer symbols. -REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap, const MemRegion *, PtrSet) - -// This is a trick to gain access to PtrSet's Factory. -namespace clang { -namespace ento { -template <> -struct ProgramStateTrait<PtrSet> : public ProgramStatePartialTrait<PtrSet> { - static void *GDMIndex() { - static int Index = 0; - return &Index; - } -}; -} // end namespace ento -} // end namespace clang - -namespace { - -class DanglingInternalBufferChecker - : public Checker<check::DeadSymbols, check::PostCall> { - - CallDescription AppendFn, AssignFn, ClearFn, CStrFn, DataFn, EraseFn, - InsertFn, PopBackFn, PushBackFn, ReplaceFn, ReserveFn, ResizeFn, - ShrinkToFitFn, SwapFn; - -public: - class DanglingBufferBRVisitor : public BugReporterVisitor { - SymbolRef PtrToBuf; - - public: - DanglingBufferBRVisitor(SymbolRef Sym) : PtrToBuf(Sym) {} - - static void *getTag() { - static int Tag = 0; - return &Tag; - } - - void Profile(llvm::FoldingSetNodeID &ID) const override { - ID.AddPointer(getTag()); - } - - std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N, - const ExplodedNode *PrevN, - BugReporterContext &BRC, - BugReport &BR) override; - - // FIXME: Scan the map once in the visitor's constructor and do a direct - // lookup by region. - bool isSymbolTracked(ProgramStateRef State, SymbolRef Sym) { - RawPtrMapTy Map = State->get<RawPtrMap>(); - for (const auto Entry : Map) { - if (Entry.second.contains(Sym)) - return true; - } - return false; - } - }; - - DanglingInternalBufferChecker() - : AppendFn("append"), AssignFn("assign"), ClearFn("clear"), - CStrFn("c_str"), DataFn("data"), EraseFn("erase"), InsertFn("insert"), - PopBackFn("pop_back"), PushBackFn("push_back"), ReplaceFn("replace"), - ReserveFn("reserve"), ResizeFn("resize"), - ShrinkToFitFn("shrink_to_fit"), SwapFn("swap") {} - - /// Check whether the function called on the container object is a - /// member function that potentially invalidates pointers referring - /// to the objects's internal buffer. - bool mayInvalidateBuffer(const CallEvent &Call) const; - - /// Record the connection between the symbol returned by c_str() and the - /// corresponding string object region in the ProgramState. Mark the symbol - /// released if the string object is destroyed. - void checkPostCall(const CallEvent &Call, CheckerContext &C) const; - - /// Clean up the ProgramState map. - void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; -}; - -} // end anonymous namespace - -// [string.require] -// -// "References, pointers, and iterators referring to the elements of a -// basic_string sequence may be invalidated by the following uses of that -// basic_string object: -// -// -- TODO: As an argument to any standard library function taking a reference -// to non-const basic_string as an argument. For example, as an argument to -// non-member functions swap(), operator>>(), and getline(), or as an argument -// to basic_string::swap(). -// -// -- Calling non-const member functions, except operator[], at, front, back, -// begin, rbegin, end, and rend." -// -bool DanglingInternalBufferChecker::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) - return true; - return false; - } - return (isa<CXXDestructorCall>(Call) || Call.isCalled(AppendFn) || - Call.isCalled(AssignFn) || Call.isCalled(ClearFn) || - Call.isCalled(EraseFn) || Call.isCalled(InsertFn) || - Call.isCalled(PopBackFn) || Call.isCalled(PushBackFn) || - Call.isCalled(ReplaceFn) || Call.isCalled(ReserveFn) || - Call.isCalled(ResizeFn) || Call.isCalled(ShrinkToFitFn) || - Call.isCalled(SwapFn)); -} - -void DanglingInternalBufferChecker::checkPostCall(const CallEvent &Call, - CheckerContext &C) const { - const auto *ICall = dyn_cast<CXXInstanceCall>(&Call); - if (!ICall) - return; - - SVal Obj = ICall->getCXXThisVal(); - const auto *ObjRegion = dyn_cast_or_null<TypedValueRegion>(Obj.getAsRegion()); - if (!ObjRegion) - return; - - auto *TypeDecl = ObjRegion->getValueType()->getAsCXXRecordDecl(); - if (TypeDecl->getName() != "basic_string") - return; - - ProgramStateRef State = C.getState(); - - if (Call.isCalled(CStrFn) || Call.isCalled(DataFn)) { - SVal RawPtr = Call.getReturnValue(); - if (SymbolRef Sym = RawPtr.getAsSymbol(/*IncludeBaseRegions=*/true)) { - // Start tracking this raw pointer by adding it to the set of symbols - // associated with this container object in the program state map. - PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>(); - const PtrSet *SetPtr = State->get<RawPtrMap>(ObjRegion); - PtrSet Set = SetPtr ? *SetPtr : F.getEmptySet(); - assert(C.wasInlined || !Set.contains(Sym)); - Set = F.add(Set, Sym); - State = State->set<RawPtrMap>(ObjRegion, Set); - C.addTransition(State); - } - return; - } - - if (mayInvalidateBuffer(Call)) { - if (const PtrSet *PS = State->get<RawPtrMap>(ObjRegion)) { - // Mark all pointer symbols associated with the deleted object released. - const Expr *Origin = Call.getOriginExpr(); - for (const auto Symbol : *PS) { - // NOTE: `Origin` may be null, and will be stored so in the symbol's - // `RefState` in MallocChecker's `RegionState` program state map. - State = allocation_state::markReleased(State, Symbol, Origin); - } - State = State->remove<RawPtrMap>(ObjRegion); - C.addTransition(State); - return; - } - } -} - -void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper &SymReaper, - CheckerContext &C) const { - ProgramStateRef State = C.getState(); - PtrSet::Factory &F = State->getStateManager().get_context<PtrSet>(); - RawPtrMapTy RPM = State->get<RawPtrMap>(); - for (const auto Entry : RPM) { - if (!SymReaper.isLiveRegion(Entry.first)) { - // Due to incomplete destructor support, some dead regions might - // remain in the program state map. Clean them up. - State = State->remove<RawPtrMap>(Entry.first); - } - if (const PtrSet *OldSet = State->get<RawPtrMap>(Entry.first)) { - PtrSet CleanedUpSet = *OldSet; - for (const auto Symbol : Entry.second) { - if (!SymReaper.isLive(Symbol)) - CleanedUpSet = F.remove(CleanedUpSet, Symbol); - } - State = CleanedUpSet.isEmpty() - ? State->remove<RawPtrMap>(Entry.first) - : State->set<RawPtrMap>(Entry.first, CleanedUpSet); - } - } - C.addTransition(State); -} - -std::shared_ptr<PathDiagnosticPiece> -DanglingInternalBufferChecker::DanglingBufferBRVisitor::VisitNode( - const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, - BugReport &BR) { - - if (!isSymbolTracked(N->getState(), PtrToBuf) || - isSymbolTracked(PrevN->getState(), PtrToBuf)) - return nullptr; - - const Stmt *S = PathDiagnosticLocation::getStmt(N); - if (!S) - return nullptr; - - SmallString<256> Buf; - llvm::raw_svector_ostream OS(Buf); - OS << "Dangling inner pointer obtained here"; - PathDiagnosticLocation Pos(S, BRC.getSourceManager(), - N->getLocationContext()); - return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(), true, - nullptr); -} - -namespace clang { -namespace ento { -namespace allocation_state { - -std::unique_ptr<BugReporterVisitor> getDanglingBufferBRVisitor(SymbolRef Sym) { - return llvm::make_unique< - DanglingInternalBufferChecker::DanglingBufferBRVisitor>(Sym); -} - -} // end namespace allocation_state -} // end namespace ento -} // end namespace clang - -void ento::registerDanglingInternalBufferChecker(CheckerManager &Mgr) { - registerNewDeleteChecker(Mgr); - Mgr.registerChecker<DanglingInternalBufferChecker>(); -} Copied: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (from r337555, cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp) URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?p2=cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp&p1=cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp&r1=337555&r2=337559&rev=337559&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Fri Jul 20 08:14:49 2018 @@ -1,4 +1,4 @@ -//=== DanglingInternalBufferChecker.cpp ---------------------------*- C++ -*--// +//=== InnerPointerChecker.cpp -------------------------------------*- C++ -*--// // // The LLVM Compiler Infrastructure // @@ -44,7 +44,7 @@ struct ProgramStateTrait<PtrSet> : publi 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::mayI 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::chec } } -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::chec } 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>(); } Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=337559&r1=337558&r2=337559&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Fri Jul 20 08:14:49 2018 @@ -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::printExpectedAllocNa 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::printExpectedDealloc 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(Allocat } 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(C 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> Mal 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> Mal 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> Mal 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> Mal // 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)); } Removed: cfe/trunk/test/Analysis/dangling-internal-buffer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dangling-internal-buffer.cpp?rev=337558&view=auto ============================================================================== --- cfe/trunk/test/Analysis/dangling-internal-buffer.cpp (original) +++ cfe/trunk/test/Analysis/dangling-internal-buffer.cpp (removed) @@ -1,291 +0,0 @@ -//RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.DanglingInternalBuffer %s -analyzer-output=text -verify - -namespace std { - -typedef int size_type; - -template <typename CharT> -class basic_string { -public: - basic_string(); - basic_string(const CharT *s); - - ~basic_string(); - void clear(); - - basic_string &operator=(const basic_string &str); - basic_string &operator+=(const basic_string &str); - - const CharT *c_str() const; - const CharT *data() const; - CharT *data(); - - basic_string &append(size_type count, CharT ch); - basic_string &assign(size_type count, CharT ch); - basic_string &erase(size_type index, size_type count); - basic_string &insert(size_type index, size_type count, CharT ch); - basic_string &replace(size_type pos, size_type count, const basic_string &str); - void pop_back(); - void push_back(CharT ch); - void reserve(size_type new_cap); - void resize(size_type count); - void shrink_to_fit(); - void swap(basic_string &other); -}; - -typedef basic_string<char> string; -typedef basic_string<wchar_t> wstring; -typedef basic_string<char16_t> u16string; -typedef basic_string<char32_t> u32string; - -} // end namespace std - -void consume(const char *) {} -void consume(const wchar_t *) {} -void consume(const char16_t *) {} -void consume(const char32_t *) {} - -void deref_after_scope_char(bool cond) { - const char *c, *d; - { - std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - d = s.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} - std::string s; - const char *c2 = s.c_str(); - if (cond) { - // expected-note@-1 {{Assuming 'cond' is not equal to 0}} - // expected-note@-2 {{Taking true branch}} - // expected-note@-3 {{Assuming 'cond' is 0}} - // expected-note@-4 {{Taking false branch}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} - } else { - consume(d); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} - } -} - -void deref_after_scope_char_data_non_const() { - char *c; - { - std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - std::string s; - char *c2 = s.data(); - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_scope_wchar_t(bool cond) { - const wchar_t *c, *d; - { - std::wstring s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - d = s.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} - std::wstring s; - const wchar_t *c2 = s.c_str(); - if (cond) { - // expected-note@-1 {{Assuming 'cond' is not equal to 0}} - // expected-note@-2 {{Taking true branch}} - // expected-note@-3 {{Assuming 'cond' is 0}} - // expected-note@-4 {{Taking false branch}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} - } else { - consume(d); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} - } -} - -void deref_after_scope_char16_t_cstr() { - const char16_t *c16; - { - std::u16string s16; - c16 = s16.c_str(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - std::u16string s16; - const char16_t *c16_2 = s16.c_str(); - consume(c16); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_scope_char32_t_data() { - const char32_t *c32; - { - std::u32string s32; - c32 = s32.data(); // expected-note {{Dangling inner pointer obtained here}} - } // expected-note {{Inner pointer invalidated by call to destructor}} - std::u32string s32; - const char32_t *c32_2 = s32.data(); - consume(c32); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void multiple_symbols(bool cond) { - const char *c1, *d1; - { - std::string s1; - c1 = s1.c_str(); // expected-note {{Dangling inner pointer obtained here}} - d1 = s1.data(); // expected-note {{Dangling inner pointer obtained here}} - const char *local = s1.c_str(); - consume(local); // no-warning - } // expected-note {{Inner pointer invalidated by call to destructor}} - // expected-note@-1 {{Inner pointer invalidated by call to destructor}} - std::string s2; - const char *c2 = s2.c_str(); - if (cond) { - // expected-note@-1 {{Assuming 'cond' is not equal to 0}} - // expected-note@-2 {{Taking true branch}} - // expected-note@-3 {{Assuming 'cond' is 0}} - // expected-note@-4 {{Taking false branch}} - consume(c1); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} - } else { - consume(d1); // expected-warning {{Use of memory after it is freed}} - } // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_equals() { - const char *c; - std::string s = "hello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s = "world"; // expected-note {{Inner pointer invalidated by call to 'operator='}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_plus_equals() { - const char *c; - std::string s = "hello"; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s += " world"; // expected-note {{Inner pointer invalidated by call to 'operator+='}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_clear() { - const char *c; - std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.clear(); // expected-note {{Inner pointer invalidated by call to 'clear'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_append() { - const char *c; - std::string s = "hello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.append(2, 'x'); // expected-note {{Inner pointer invalidated by call to 'append'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_assign() { - const char *c; - std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.assign(4, 'a'); // expected-note {{Inner pointer invalidated by call to 'assign'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_erase() { - const char *c; - std::string s = "hello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.erase(0, 2); // expected-note {{Inner pointer invalidated by call to 'erase'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_insert() { - const char *c; - std::string s = "ello"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.insert(0, 1, 'h'); // expected-note {{Inner pointer invalidated by call to 'insert'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_replace() { - const char *c; - std::string s = "hello world"; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.replace(6, 5, "string"); // expected-note {{Inner pointer invalidated by call to 'replace'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_pop_back() { - const char *c; - std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.pop_back(); // expected-note {{Inner pointer invalidated by call to 'pop_back'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_push_back() { - const char *c; - std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.push_back('c'); // expected-note {{Inner pointer invalidated by call to 'push_back'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_reserve() { - const char *c; - std::string s; - c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}} - s.reserve(5); // expected-note {{Inner pointer invalidated by call to 'reserve'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_resize() { - const char *c; - std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.resize(5); // expected-note {{Inner pointer invalidated by call to 'resize'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_shrink_to_fit() { - const char *c; - std::string s; - c = s.data(); // expected-note {{Dangling inner pointer obtained here}} - s.shrink_to_fit(); // expected-note {{Inner pointer invalidated by call to 'shrink_to_fit'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_swap() { - const char *c; - std::string s1, s2; - c = s1.data(); // expected-note {{Dangling inner pointer obtained here}} - s1.swap(s2); // expected-note {{Inner pointer invalidated by call to 'swap'}} - consume(c); // expected-warning {{Use of memory after it is freed}} - // expected-note@-1 {{Use of memory after it is freed}} -} - -void deref_after_scope_ok(bool cond) { - const char *c, *d; - std::string s; - { - c = s.c_str(); - d = s.data(); - } - if (cond) - consume(c); // no-warning - else - consume(d); // no-warning -} Copied: cfe/trunk/test/Analysis/inner-pointer.cpp (from r337555, cfe/trunk/test/Analysis/dangling-internal-buffer.cpp) URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?p2=cfe/trunk/test/Analysis/inner-pointer.cpp&p1=cfe/trunk/test/Analysis/dangling-internal-buffer.cpp&r1=337555&r2=337559&rev=337559&view=diff ============================================================================== --- cfe/trunk/test/Analysis/dangling-internal-buffer.cpp (original) +++ cfe/trunk/test/Analysis/inner-pointer.cpp Fri Jul 20 08:14:49 2018 @@ -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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits