r318979 - [analyzer] Teach RetainCountChecker about CoreMedia APIs
Devin Coughlin via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 25 06:57:42 PST 2017
Author: dcoughlin
Date: Sat Nov 25 06:57:42 2017
New Revision: 318979
URL: http://llvm.org/viewvc/llvm-project?rev=318979&view=rev
Log:
[analyzer] Teach RetainCountChecker about CoreMedia APIs
Teach the retain-count checker that CoreMedia reference types use
CoreFoundation-style reference counting. This enables the checker
to catch leaks and over releases of those types.
rdar://problem/33599757
Modified:
cfe/trunk/lib/Analysis/CocoaConventions.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
cfe/trunk/test/Analysis/retain-release.m
Modified: cfe/trunk/lib/Analysis/CocoaConventions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CocoaConventions.cpp?rev=318979&r1=318978&r2=318979&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CocoaConventions.cpp (original)
+++ cfe/trunk/lib/Analysis/CocoaConventions.cpp Sat Nov 25 06:57:42 2017
@@ -47,12 +47,19 @@ bool cocoa::isRefType(QualType RetTy, St
return Name.startswith(Prefix);
}
+/// Returns true when the passed-in type is a CF-style reference-counted
+/// type from the DiskArbitration framework.
+static bool isDiskArbitrationAPIRefType(QualType T) {
+ return cocoa::isRefType(T, "DADisk") ||
+ cocoa::isRefType(T, "DADissenter") ||
+ cocoa::isRefType(T, "DASessionRef");
+}
+
bool coreFoundation::isCFObjectRef(QualType T) {
return cocoa::isRefType(T, "CF") || // Core Foundation.
cocoa::isRefType(T, "CG") || // Core Graphics.
- cocoa::isRefType(T, "DADisk") || // Disk Arbitration API.
- cocoa::isRefType(T, "DADissenter") ||
- cocoa::isRefType(T, "DASessionRef");
+ cocoa::isRefType(T, "CM") || // Core Media.
+ isDiskArbitrationAPIRefType(T);
}
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=318979&r1=318978&r2=318979&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Sat Nov 25 06:57:42 2017
@@ -1201,10 +1201,10 @@ RetainSummaryManager::getFunctionSummary
break;
}
- // For the Disk Arbitration API (DiskArbitration/DADisk.h)
- if (cocoa::isRefType(RetTy, "DADisk") ||
- cocoa::isRefType(RetTy, "DADissenter") ||
- cocoa::isRefType(RetTy, "DASessionRef")) {
+ // For all other CF-style types, use the Create/Get
+ // rule for summaries but don't support Retain functions
+ // with framework-specific prefixes.
+ if (coreFoundation::isCFObjectRef(RetTy)) {
S = getCFCreateGetRuleSummary(FD);
break;
}
Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=318979&r1=318978&r2=318979&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Sat Nov 25 06:57:42 2017
@@ -450,6 +450,51 @@ void f10(io_service_t media, DADiskRef d
if (session) NSLog(@"ok");
}
+
+// Handle CoreMedia API
+
+struct CMFoo;
+typedef struct CMFoo *CMFooRef;
+
+CMFooRef CMCreateFooRef();
+CMFooRef CMGetFooRef();
+
+typedef signed long SInt32;
+typedef SInt32 OSStatus;
+OSStatus CMCreateFooAndReturnViaOutParameter(CMFooRef * CF_RETURNS_RETAINED fooOut);
+
+void testLeakCoreMediaReferenceType() {
+ CMFooRef f = CMCreateFooRef(); // expected-warning{{leak}}
+}
+
+void testOverReleaseMediaReferenceType() {
+ CMFooRef f = CMGetFooRef();
+ CFRelease(f); // expected-warning{{Incorrect decrement of the reference count}}
+}
+
+void testOkToReleaseReturnsRetainedOutParameter() {
+ CMFooRef foo = 0;
+ OSStatus status = CMCreateFooAndReturnViaOutParameter(&foo);
+
+ if (status != 0)
+ return;
+
+ CFRelease(foo); // no-warning
+}
+
+void testLeakWithReturnsRetainedOutParameter() {
+ CMFooRef foo = 0;
+ OSStatus status = CMCreateFooAndReturnViaOutParameter(&foo);
+
+ if (status != 0)
+ return;
+
+ // FIXME: Ideally we would report a leak here since it is the caller's
+ // responsibility to release 'foo'. However, we don't currently have
+ // a mechanism in this checker to only require a release when a successful
+ // status is returned.
+}
+
// Test retain/release checker with CFString and CFMutableArray.
void f11() {
// Create the array.
More information about the cfe-commits
mailing list