diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2013-04-05 17:55:00 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2013-04-05 17:55:00 +0000 |
| commit | 26330563f27a93b9c0a0639a3e4f4cf538aa54fe (patch) | |
| tree | f5afb0f99fb33432db351cbde492751555406ea7 /clang/lib/StaticAnalyzer | |
| parent | 0b55b438b25d39c37737282030d4d9d8bee07fc9 (diff) | |
| download | bcm5719-llvm-26330563f27a93b9c0a0639a3e4f4cf538aa54fe.tar.gz bcm5719-llvm-26330563f27a93b9c0a0639a3e4f4cf538aa54fe.zip | |
[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>
llvm-svn: 178890
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/Checkers.td | 6 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 15 |
2 files changed, 18 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/Checkers.td b/clang/lib/StaticAnalyzer/Checkers/Checkers.td index 3db3fb9962a..a29f53bb796 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/lib/StaticAnalyzer/Checkers/Checkers.td @@ -176,7 +176,11 @@ def VirtualCallChecker : Checker<"VirtualCall">, DescFile<"VirtualCallChecker.cpp">; def NewDeleteChecker : Checker<"NewDelete">, - HelpText<"Check for memory leaks, double free, and use-after-free problems. Traces memory managed by new/delete.">, + HelpText<"Check for double-free and use-after-free problems. Traces memory managed by new/delete.">, + DescFile<"MallocChecker.cpp">; + +def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, + HelpText<"Check for memory leaks. Traces memory managed by new/delete.">, DescFile<"MallocChecker.cpp">; } // end: "alpha.cplusplus" diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 318be5bf107..851aa0ca36b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/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) |

