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