summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp32
1 files changed, 24 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 28097e30ca9..09b744243b0 100644
--- a/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
//
// This file defines summaries implementation for retain counting, which
-// implements a reference count checker for Core Foundation and Cocoa
-// on (Mac OS X).
+// implements a reference count checker for Core Foundation, Cocoa
+// and OSObject (on Mac OS X).
//
//===----------------------------------------------------------------------===//
@@ -94,6 +94,22 @@ static bool isMakeCollectable(StringRef FName) {
return FName.contains_lower("MakeCollectable");
}
+/// A function is OSObject related if it is declared on a subclass
+/// of OSObject, or any of the parameters is a subclass of an OSObject.
+static bool isOSObjectRelated(const CXXMethodDecl *MD) {
+ if (isOSObjectSubclass(MD->getParent()))
+ return true;
+
+ for (ParmVarDecl *Param : MD->parameters()) {
+ QualType PT = Param->getType();
+ if (CXXRecordDecl *RD = PT->getPointeeType()->getAsCXXRecordDecl())
+ if (isOSObjectSubclass(RD))
+ return true;
+ }
+
+ return false;
+}
+
const RetainSummary *
RetainSummaryManager::generateSummary(const FunctionDecl *FD,
bool &AllowAnnotations) {
@@ -322,12 +338,10 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
}
}
- if (isa<CXXMethodDecl>(FD)) {
-
- // Stop tracking arguments passed to C++ methods, as those might be
- // wrapping smart pointers.
- return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking,
- DoNothing);
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ if (!(TrackOSObjects && isOSObjectRelated(MD)))
+ return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking,
+ DoNothing);
}
return getDefaultSummary();
@@ -642,6 +656,8 @@ RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
if (D->hasAttr<CFReturnsNotRetainedAttr>())
return RetEffect::MakeNotOwned(RetEffect::CF);
+ else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained"))
+ return RetEffect::MakeNotOwned(RetEffect::Generalized);
return None;
}
OpenPOWER on IntegriCloud