summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-11-30 02:17:31 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-11-30 02:17:31 +0000
commita1c3bb88eeb83d5aa010827cae0408749d06a10d (patch)
tree1132b19af89d187ffe9bdd97dcc0c8ec424b2974 /clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
parent58c3837ee38c27d2370d3d7b047255c650106bb0 (diff)
downloadbcm5719-llvm-a1c3bb88eeb83d5aa010827cae0408749d06a10d.tar.gz
bcm5719-llvm-a1c3bb88eeb83d5aa010827cae0408749d06a10d.zip
[analyzer] Reference leaked object by name, even if it was created in an inlined function.
rdar://45532181 Differential Revision: https://reviews.llvm.org/D54973 llvm-svn: 347942
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp32
1 files changed, 17 insertions, 15 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index 927b7a2fa19..608ed88eb03 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -306,9 +306,8 @@ struct AllocationInfo {
};
} // end anonymous namespace
-static AllocationInfo
-GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
- SymbolRef Sym) {
+static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr,
+ const ExplodedNode *N, SymbolRef Sym) {
const ExplodedNode *AllocationNode = N;
const ExplodedNode *AllocationNodeInCurrentOrParentContext = N;
const MemRegion *FirstBinding = nullptr;
@@ -353,9 +352,9 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
// Find the last init that was called on the given symbol and store the
// init method's location context.
if (!InitMethodContext)
- if (Optional<CallEnter> CEP = N->getLocation().getAs<CallEnter>()) {
+ if (auto CEP = N->getLocation().getAs<CallEnter>()) {
const Stmt *CE = CEP->getCallExpr();
- if (const ObjCMessageExpr *ME = dyn_cast_or_null<ObjCMessageExpr>(CE)) {
+ if (const auto *ME = dyn_cast_or_null<ObjCMessageExpr>(CE)) {
const Stmt *RecExpr = ME->getInstanceReceiver();
if (RecExpr) {
SVal RecV = St->getSVal(RecExpr, NContext);
@@ -365,7 +364,7 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
}
}
- N = N->pred_empty() ? nullptr : *(N->pred_begin());
+ N = N->getFirstPred();
}
// If we are reporting a leak of the object that was allocated with alloc,
@@ -382,9 +381,11 @@ GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
// If allocation happened in a function different from the leak node context,
// do not report the binding.
assert(N && "Could not find allocation node");
- if (N->getLocationContext() != LeakContext) {
+
+ if (AllocationNodeInCurrentOrParentContext &&
+ AllocationNodeInCurrentOrParentContext->getLocationContext() !=
+ LeakContext)
FirstBinding = nullptr;
- }
return AllocationInfo(AllocationNodeInCurrentOrParentContext,
FirstBinding,
@@ -409,8 +410,7 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
// We are reporting a leak. Walk up the graph to get to the first node where
// the symbol appeared, and also get the first VarDecl that tracked object
// is stored to.
- AllocationInfo AllocI =
- GetAllocationSite(BRC.getStateManager(), EndN, Sym);
+ AllocationInfo AllocI = GetAllocationSite(BRC.getStateManager(), EndN, Sym);
const MemRegion* FirstBinding = AllocI.R;
BR.markInteresting(AllocI.InterestingMethodContext);
@@ -448,11 +448,12 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
os << (isa<ObjCMethodDecl>(D) ? " is returned from a method "
: " is returned from a function ");
- if (D->hasAttr<CFReturnsNotRetainedAttr>())
+ if (D->hasAttr<CFReturnsNotRetainedAttr>()) {
os << "that is annotated as CF_RETURNS_NOT_RETAINED";
- else if (D->hasAttr<NSReturnsNotRetainedAttr>())
+ } else if (D->hasAttr<NSReturnsNotRetainedAttr>()) {
os << "that is annotated as NS_RETURNS_NOT_RETAINED";
- else {
+ // TODO: once the patch is ready, insert a case for OS_RETURNS_NOT_RETAINED
+ } else {
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
if (BRC.getASTContext().getLangOpts().ObjCAutoRefCount) {
os << "managed by Automatic Reference Counting";
@@ -497,7 +498,8 @@ void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
}
}
-void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,SymbolRef sym) {
+void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,
+ SymbolRef sym) {
// Most bug reports are cached at the location where they occurred.
// With leaks, we want to unique them by the location where they were
// allocated, and only report a single path. To do this, we need to find
@@ -511,7 +513,7 @@ void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,SymbolRef sym) {
const SourceManager& SMgr = Ctx.getSourceManager();
AllocationInfo AllocI =
- GetAllocationSite(Ctx.getStateManager(), getErrorNode(), sym);
+ GetAllocationSite(Ctx.getStateManager(), getErrorNode(), sym);
AllocNode = AllocI.N;
AllocBinding = AllocI.R;
OpenPOWER on IntegriCloud