aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-04-05 17:55:00 +0000
committerJordan Rose <jordan_rose@apple.com>2013-04-05 17:55:00 +0000
commite85deb356f5d2d2172b7ef70314bc9cfc742a936 (patch)
treeb89a9efd9ae49605b48ad6cdd6b406fdde83ba5d /lib/StaticAnalyzer/Checkers/MallocChecker.cpp
parent6b119d63f5036344acd4e00a6ff2b3c72f26966f (diff)
[analyzer] Split new/delete checker into use-after-free and leaks parts.
This splits the leak-checking part of alpha.cplusplus.NewDelete into a separate user-level checker, alpha.cplusplus.NewDeleteLeaks. All the difficult false positives we've seen with the new/delete checker have been spurious leak warnings; the use-after-free warnings and mismatched deallocator warnings, while rare, have always been valid. <rdar://problem/6194569> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 318be5bf10..851aa0ca36 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -164,6 +164,7 @@ public:
DefaultBool CMallocPessimistic;
DefaultBool CMallocOptimistic;
DefaultBool CNewDeleteChecker;
+ DefaultBool CNewDeleteLeaksChecker;
DefaultBool CMismatchedDeallocatorChecker;
};
@@ -1536,12 +1537,21 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
CheckerContext &C) const {
if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic &&
- !Filter.CNewDeleteChecker)
+ !Filter.CNewDeleteLeaksChecker)
return;
- if (!isTrackedFamily(C, Sym))
+ const RefState *RS = C.getState()->get<RegionState>(Sym);
+ assert(RS && "cannot leak an untracked symbol");
+ AllocationFamily Family = RS->getAllocationFamily();
+ if (!isTrackedFamily(Family))
return;
+ // Special case for new and new[]; these are controlled by a separate checker
+ // flag so that they can be selectively disabled.
+ if (Family == AF_CXXNew || Family == AF_CXXNewArray)
+ if (!Filter.CNewDeleteLeaksChecker)
+ return;
+
assert(N);
if (!BT_Leak) {
BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
@@ -2115,4 +2125,5 @@ void ento::register##name(CheckerManager &mgr) {\
REGISTER_CHECKER(MallocPessimistic)
REGISTER_CHECKER(MallocOptimistic)
REGISTER_CHECKER(NewDeleteChecker)
+REGISTER_CHECKER(NewDeleteLeaksChecker)
REGISTER_CHECKER(MismatchedDeallocatorChecker)