summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2015-02-05 01:02:53 +0000
committerAnna Zaks <ganna@apple.com>2015-02-05 01:02:53 +0000
commit486a0ff4b79bb79cbd12c4fd34cf2b816d62bc12 (patch)
tree7c28d51c6c5af95c56ee228c5e43a96411722460 /clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
parent7b6da65990958fc3478961526332bfca283b77a7 (diff)
downloadbcm5719-llvm-486a0ff4b79bb79cbd12c4fd34cf2b816d62bc12.tar.gz
bcm5719-llvm-486a0ff4b79bb79cbd12c4fd34cf2b816d62bc12.zip
[analyzer] Look for allocation site in the parent frames as well as the current one.
Instead of handling edge cases (mostly involving blocks), where we have difficulty finding an allocation statement, allow the allocation site to be in a parent node. Previously we assumed that the allocation site can always be found in the same frame as allocation, but there are scenarios in which an element is leaked in a child frame but is allocated in the parent. llvm-svn: 228247
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp33
1 files changed, 13 insertions, 20 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index c8578543de5..ac74ecd0f49 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2190,7 +2190,7 @@ static AllocationInfo
GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
SymbolRef Sym) {
const ExplodedNode *AllocationNode = N;
- const ExplodedNode *AllocationNodeInCurrentContext = N;
+ const ExplodedNode *AllocationNodeInCurrentOrParentContext = N;
const MemRegion *FirstBinding = nullptr;
const LocationContext *LeakContext = N->getLocationContext();
@@ -2220,10 +2220,15 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
// AllocationNode is the last node in which the symbol was tracked.
AllocationNode = N;
- // AllocationNodeInCurrentContext, is the last node in the current context
- // in which the symbol was tracked.
- if (NContext == LeakContext)
- AllocationNodeInCurrentContext = N;
+ // AllocationNodeInCurrentContext, is the last node in the current or
+ // parent context in which the symbol was tracked.
+ //
+ // Note that the allocation site might be in the parent conext. For example,
+ // the case where an allocation happens in a block that captures a reference
+ // to it and that reference is overwritten/dropped by another call to
+ // the block.
+ if (NContext == LeakContext || NContext->isParentOf(LeakContext))
+ AllocationNodeInCurrentOrParentContext = N;
// Find the last init that was called on the given symbol and store the
// init method's location context.
@@ -2261,7 +2266,7 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
FirstBinding = nullptr;
}
- return AllocationInfo(AllocationNodeInCurrentContext,
+ return AllocationInfo(AllocationNodeInCurrentOrParentContext,
FirstBinding,
InterestingMethodContext);
}
@@ -2392,20 +2397,8 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
ProgramPoint P = AllocNode->getLocation();
if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
AllocStmt = Exit->getCalleeContext()->getCallSite();
- else {
- // We are going to get a BlockEdge when the leak and allocation happen in
- // different, non-nested frames (contexts). For example, the case where an
- // allocation happens in a block that captures a reference to it and
- // that reference is overwritten/dropped by another call to the block.
- if (Optional<BlockEdge> Edge = P.getAs<BlockEdge>()) {
- if (Optional<CFGStmt> St = Edge->getDst()->front().getAs<CFGStmt>()) {
- AllocStmt = St->getStmt();
- }
- }
- else {
- AllocStmt = P.castAs<PostStmt>().getStmt();
- }
- }
+ else
+ AllocStmt = P.castAs<PostStmt>().getStmt();
assert(AllocStmt && "Cannot find allocation statement");
PathDiagnosticLocation AllocLocation =
OpenPOWER on IntegriCloud