[analyzer] Teach RetainCountChecker about CVFooRetain

Change the retain count checker to treat CoreFoundation-style "CV"-prefixed
reference types from CoreVideo similarly to CoreGraphics types. With this
change, we treat CVFooRetain() on a CVFooRef type as a retain. CVFooRelease()
APIs are annotated as consuming their parameter, so this change prevents false
positives about incorrect decrements of reference counts.

<rdar://problem/27116090>

llvm-svn: 278382
This commit is contained in:
Devin Coughlin 2016-08-11 18:41:29 +00:00
parent 932bce6ade
commit 81cc38cf9a
2 changed files with 26 additions and 4 deletions

View File

@ -1171,8 +1171,9 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
break; break;
} }
// For CoreGraphics ('CG') types. // For CoreGraphics ('CG') and CoreVideo ('CV') types.
if (cocoa::isRefType(RetTy, "CG", FName)) { if (cocoa::isRefType(RetTy, "CG", FName) ||
cocoa::isRefType(RetTy, "CV", FName)) {
if (isRetain(FD, FName)) if (isRetain(FD, FName))
S = getUnarySummary(FT, cfretain); S = getUnarySummary(FT, cfretain);
else else
@ -3372,12 +3373,13 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// Handle: id NSMakeCollectable(CFTypeRef) // Handle: id NSMakeCollectable(CFTypeRef)
canEval = II->isStr("NSMakeCollectable"); canEval = II->isStr("NSMakeCollectable");
} else if (ResultTy->isPointerType()) { } else if (ResultTy->isPointerType()) {
// Handle: (CF|CG)Retain // Handle: (CF|CG|CV)Retain
// CFAutorelease // CFAutorelease
// CFMakeCollectable // CFMakeCollectable
// It's okay to be a little sloppy here (CGMakeCollectable doesn't exist). // It's okay to be a little sloppy here (CGMakeCollectable doesn't exist).
if (cocoa::isRefType(ResultTy, "CF", FName) || if (cocoa::isRefType(ResultTy, "CF", FName) ||
cocoa::isRefType(ResultTy, "CG", FName)) { cocoa::isRefType(ResultTy, "CG", FName) ||
cocoa::isRefType(ResultTy, "CV", FName)) {
canEval = isRetain(FD, FName) || isAutorelease(FD, FName) || canEval = isRetain(FD, FName) || isAutorelease(FD, FName) ||
isMakeCollectable(FD, FName); isMakeCollectable(FD, FName);
} }

View File

@ -1247,6 +1247,26 @@ CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height,
pixelBufferAttributes, pixelBufferOut) ; pixelBufferAttributes, pixelBufferOut) ;
} }
#pragma clang arc_cf_code_audited begin
typedef struct SomeOpaqueStruct *CMSampleBufferRef;
CVImageBufferRef _Nonnull CMSampleBufferGetImageBuffer(CMSampleBufferRef _Nonnull sbuf);
#pragma clang arc_cf_code_audited end
CVBufferRef _Nullable CVBufferRetain(CVBufferRef _Nullable buffer);
void CVBufferRelease(CF_CONSUMED CVBufferRef _Nullable buffer);
void testCVPrefixRetain(CMSampleBufferRef sbuf) {
// Make sure RetainCountChecker treats CVFooRetain() as a CF-style retain.
CVPixelBufferRef pixelBuf = CMSampleBufferGetImageBuffer(sbuf);
CVBufferRetain(pixelBuf);
CVBufferRelease(pixelBuf); // no-warning
// Make sure result of CVFooRetain() is the same as its argument.
CVPixelBufferRef pixelBufAlias = CVBufferRetain(pixelBuf);
CVBufferRelease(pixelBufAlias); // no-warning
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// <rdar://problem/7358899> False leak associated with // <rdar://problem/7358899> False leak associated with
// CGBitmapContextCreateWithData // CGBitmapContextCreateWithData