diff options
author | Reka Kovacs <rekanikolett@gmail.com> | 2018-06-09 13:03:49 +0000 |
---|---|---|
committer | Reka Kovacs <rekanikolett@gmail.com> | 2018-06-09 13:03:49 +0000 |
commit | 18775fc9b7d196d8f5aa9540417d684f5eed74ff (patch) | |
tree | 19887ced617c592f199c92aa8fe029dcf405d6f5 /clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | |
parent | 8aada65f8131abdc4b72ae33fd57fcb35f1fe5b3 (diff) | |
download | bcm5719-llvm-18775fc9b7d196d8f5aa9540417d684f5eed74ff.tar.gz bcm5719-llvm-18775fc9b7d196d8f5aa9540417d684f5eed74ff.zip |
[analyzer] Add dangling internal buffer check.
This check will mark raw pointers to C++ standard library container internal
buffers 'released' when the objects themselves are destroyed. Such information
can be used by MallocChecker to warn about use-after-free problems.
In this first version, 'std::basic_string's are supported.
Differential Revision: https://reviews.llvm.org/D47135
llvm-svn: 334348
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 341fdd2e880..2ab817a1ccb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -30,6 +30,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "AllocationState.h" #include <climits> #include <utility> @@ -45,7 +46,8 @@ enum AllocationFamily { AF_CXXNew, AF_CXXNewArray, AF_IfNameIndex, - AF_Alloca + AF_Alloca, + AF_InternalBuffer }; class RefState { @@ -1467,6 +1469,7 @@ void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C, case AF_CXXNew: os << "'new'"; return; case AF_CXXNewArray: os << "'new[]'"; return; case AF_IfNameIndex: os << "'if_nameindex()'"; return; + case AF_InternalBuffer: os << "container-specific allocator"; return; case AF_Alloca: case AF_None: llvm_unreachable("not a deallocation expression"); } @@ -1479,6 +1482,7 @@ void MallocChecker::printExpectedDeallocName(raw_ostream &os, case AF_CXXNew: os << "'delete'"; return; case AF_CXXNewArray: os << "'delete[]'"; return; case AF_IfNameIndex: os << "'if_freenameindex()'"; return; + case AF_InternalBuffer: os << "container-specific deallocator"; return; case AF_Alloca: case AF_None: llvm_unreachable("suspicious argument"); } @@ -1653,7 +1657,9 @@ MallocChecker::getCheckIfTracked(AllocationFamily Family, return Optional<MallocChecker::CheckKind>(); } case AF_CXXNew: - case AF_CXXNewArray: { + case AF_CXXNewArray: + // FIXME: Add new CheckKind for AF_InternalBuffer. + case AF_InternalBuffer: { if (IsALeakCheck) { if (ChecksEnabled[CK_NewDeleteLeaksChecker]) return CK_NewDeleteLeaksChecker; @@ -2991,6 +2997,20 @@ void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State, } } +namespace clang { +namespace ento { +namespace allocation_state { + +ProgramStateRef +markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) { + AllocationFamily Family = AF_InternalBuffer; + return State->set<RegionState>(Sym, RefState::getReleased(Family, Origin)); +} + +} // end namespace allocation_state +} // end namespace ento +} // end namespace clang + void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { registerCStringCheckerBasic(mgr); MallocChecker *checker = mgr.registerChecker<MallocChecker>(); |