[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:
parent
932bce6ade
commit
81cc38cf9a
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue