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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318979
91177308-0d34-0410-b5e6-
96231b3b80d8
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);
}
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;
}
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.