[cfe-commits] r84064 - in /cfe/trunk: lib/Analysis/CFRefCount.cpp test/Analysis/retain-release.m
Ted Kremenek
kremenek at apple.com
Tue Oct 13 17:27:24 PDT 2009
Author: kremenek
Date: Tue Oct 13 19:27:24 2009
New Revision: 84064
URL: http://llvm.org/viewvc/llvm-project?rev=84064&view=rev
Log:
retain/release checker: Recognize that calls to
'CVPixelBufferCreateWithPlanarBytes()' and
'CVPixelBufferCreateWithBytes' (Core Video API) can indirectly release
a pixel buffer object via a callback.
This fixes <rdar://problem/7283567>.
Modified:
cfe/trunk/lib/Analysis/CFRefCount.cpp
cfe/trunk/test/Analysis/retain-release.m
Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=84064&r1=84063&r2=84064&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Tue Oct 13 19:27:24 2009
@@ -967,8 +967,8 @@
// FIXME: This should all be refactored into a chain of "summary lookup"
// filters.
- assert (ScratchArgs.isEmpty());
-
+ assert(ScratchArgs.isEmpty());
+
switch (strlen(FName)) {
default: break;
case 14:
@@ -1046,7 +1046,17 @@
// This should be addressed using a API table. This strcmp is also
// a little gross, but there is no need to super optimize here.
ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
- S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
+ DoNothing);
+ }
+ else if (!memcmp(FName, "CVPixelBufferCreateWithBytes", 28)) {
+ // FIXES: <rdar://problem/7283567>
+ // Eventually this can be improved by recognizing that the pixel
+ // buffer passed to CVPixelBufferCreateWithBytes is released via
+ // a callback and doing full IPA to make sure this is done correctly.
+ ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
+ DoNothing);
}
break;
@@ -1058,6 +1068,19 @@
S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
}
break;
+
+ case 34:
+ if (!memcmp(FName, "CVPixelBufferCreateWithPlanarBytes", 34)) {
+ // FIXES: <rdar://problem/7283567>
+ // Eventually this can be improved by recognizing that the pixel
+ // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
+ // via a callback and doing full IPA to make sure this is done
+ // correctly.
+ ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking);
+ S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
+ DoNothing);
+ }
+ break;
}
// Did we get a summary?
Modified: cfe/trunk/test/Analysis/retain-release.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.m?rev=84064&r1=84063&r2=84064&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release.m (original)
+++ cfe/trunk/test/Analysis/retain-release.m Tue Oct 13 19:27:24 2009
@@ -998,6 +998,106 @@
}
//===----------------------------------------------------------------------===//
+// <rdar://problem/7283567> False leak associated with call to
+// CVPixelBufferCreateWithBytes ()
+//
+// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and
+// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the
+// pixel buffer object. These test cases show how the analyzer stops tracking
+// the reference count for the objects passed for this argument. This
+// could be made smarter.
+//===----------------------------------------------------------------------===//
+
+typedef int int32_t;
+typedef UInt32 FourCharCode;
+typedef FourCharCode OSType;
+typedef uint64_t CVOptionFlags;
+typedef int32_t CVReturn;
+typedef struct __CVBuffer *CVBufferRef;
+typedef CVBufferRef CVImageBufferRef;
+typedef CVImageBufferRef CVPixelBufferRef;
+typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress );
+
+extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator,
+ size_t width,
+ size_t height,
+ OSType pixelFormatType,
+ void *baseAddress,
+ size_t bytesPerRow,
+ CVPixelBufferReleaseBytesCallback releaseCallback,
+ void *releaseRefCon,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) ;
+
+typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] );
+
+extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator,
+ size_t width,
+ size_t height,
+ OSType pixelFormatType,
+ void *dataPtr,
+ size_t dataSize,
+ size_t numberOfPlanes,
+ void *planeBaseAddress[],
+ size_t planeWidth[],
+ size_t planeHeight[],
+ size_t planeBytesPerRow[],
+ CVPixelBufferReleasePlanarBytesCallback releaseCallback,
+ void *releaseRefCon,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) ;
+
+extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator,
+ size_t width,
+ size_t height,
+ OSType pixelFormatType,
+ void *baseAddress,
+ size_t bytesPerRow,
+ CVPixelBufferReleaseBytesCallback releaseCallback,
+ void *releaseRefCon,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) ;
+
+CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height,
+ OSType pixelFormatType, void *baseAddress,
+ size_t bytesPerRow,
+ CVPixelBufferReleaseBytesCallback releaseCallback,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) {
+
+ // For the allocated object, it doesn't really matter what type it is
+ // for the purpose of this test. All we want to show is that
+ // this is freed later by the callback.
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+
+ return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType,
+ baseAddress, bytesPerRow, releaseCallback,
+ number, // potentially released by callback
+ pixelBufferAttributes, pixelBufferOut) ;
+}
+
+CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height,
+ OSType pixelFormatType, void *dataPtr, size_t dataSize,
+ size_t numberOfPlanes, void *planeBaseAddress[],
+ size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[],
+ CVPixelBufferReleasePlanarBytesCallback releaseCallback,
+ CFDictionaryRef pixelBufferAttributes,
+ CVPixelBufferRef *pixelBufferOut) {
+
+ // For the allocated object, it doesn't really matter what type it is
+ // for the purpose of this test. All we want to show is that
+ // this is freed later by the callback.
+ NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning
+
+ return CVPixelBufferCreateWithPlanarBytes(allocator,
+ width, height, pixelFormatType, dataPtr, dataSize,
+ numberOfPlanes, planeBaseAddress, planeWidth,
+ planeHeight, planeBytesPerRow, releaseCallback,
+ number, // potentially released by callback
+ pixelBufferAttributes, pixelBufferOut) ;
+}
+
+//===----------------------------------------------------------------------===//
// Tests of ownership attributes.
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list