r337559 - [analyzer] Rename DanglingInternalBufferChecker to InnerPointerChecker.

Reka Kovacs via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 20 08:14:49 PDT 2018


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 at -1 {{Inner pointer invalidated by call to destructor}}
-  std::string s;
-  const char *c2 = s.c_str();
-  if (cond) {
-    // expected-note at -1 {{Assuming 'cond' is not equal to 0}}
-    // expected-note at -2 {{Taking true branch}}
-    // expected-note at -3 {{Assuming 'cond' is 0}}
-    // expected-note at -4 {{Taking false branch}}
-    consume(c); // expected-warning {{Use of memory after it is freed}}
-    // expected-note at -1 {{Use of memory after it is freed}}
-  } else {
-    consume(d); // expected-warning {{Use of memory after it is freed}}
-    // expected-note at -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 at -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 at -1 {{Inner pointer invalidated by call to destructor}}
-  std::wstring s;
-  const wchar_t *c2 = s.c_str();
-  if (cond) {
-    // expected-note at -1 {{Assuming 'cond' is not equal to 0}}
-    // expected-note at -2 {{Taking true branch}}
-    // expected-note at -3 {{Assuming 'cond' is 0}}
-    // expected-note at -4 {{Taking false branch}}
-    consume(c); // expected-warning {{Use of memory after it is freed}}
-    // expected-note at -1 {{Use of memory after it is freed}}
-  } else {
-    consume(d); // expected-warning {{Use of memory after it is freed}}
-    // expected-note at -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 at -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 at -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 at -1 {{Inner pointer invalidated by call to destructor}}
-  std::string s2;
-  const char *c2 = s2.c_str();
-  if (cond) {
-    // expected-note at -1 {{Assuming 'cond' is not equal to 0}}
-    // expected-note at -2 {{Taking true branch}}
-    // expected-note at -3 {{Assuming 'cond' is 0}}
-    // expected-note at -4 {{Taking false branch}}
-    consume(c1); // expected-warning {{Use of memory after it is freed}}
-    // expected-note at -1 {{Use of memory after it is freed}}
-  } else {
-    consume(d1); // expected-warning {{Use of memory after it is freed}}
-  }              // expected-note at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 at -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 {
 




More information about the cfe-commits mailing list