forked from OSchip/llvm-project
[analyzer] RetainCount: Suppress retain detection heuristic on some CM methods.
If it ends with "Retain" like CFRetain and returns a CFTypeRef like CFRetain, then it is not necessarily a CFRetain. But it is indeed true that these two return something retained. Differential Revision: https://reviews.llvm.org/D55907 rdar://problem/39390714 llvm-svn: 349862
This commit is contained in:
parent
33c46ca675
commit
212bbfad25
|
|
@ -204,6 +204,11 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
|
|||
AllowAnnotations = false;
|
||||
return RetTy->isObjCIdType() ? getUnarySummary(FT, cfmakecollectable)
|
||||
: getPersistentStopSummary();
|
||||
} else if (FName == "CMBufferQueueDequeueAndRetain" ||
|
||||
FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
|
||||
// Part of: <rdar://problem/39390714>.
|
||||
return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,
|
||||
DoNothing);
|
||||
} else if (FName == "CFPlugInInstanceCreate") {
|
||||
return getPersistentSummary(RetEffect::MakeNoRet());
|
||||
} else if (FName == "IORegistryEntrySearchCFProperty" ||
|
||||
|
|
@ -591,6 +596,12 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD,
|
|||
// Handle: (CF|CG|CV)Retain
|
||||
// CFAutorelease
|
||||
// It's okay to be a little sloppy here.
|
||||
if (FName == "CMBufferQueueDequeueAndRetain" ||
|
||||
FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
|
||||
// Part of: <rdar://problem/39390714>.
|
||||
// These are not retain. They just return something and retain it.
|
||||
return None;
|
||||
}
|
||||
if (cocoa::isRefType(ResultTy, "CF", FName) ||
|
||||
cocoa::isRefType(ResultTy, "CG", FName) ||
|
||||
cocoa::isRefType(ResultTy, "CV", FName))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,20 @@
|
|||
// RUN: rm -f %t.objc.plist %t.objcpp.plist
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s -analyzer-output=plist -o %t.objc.plist
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -std=gnu++98 -Wno-objc-root-class %s -analyzer-output=plist -o %t.objcpp.plist
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
|
||||
// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
|
||||
// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\
|
||||
// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
|
||||
// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist
|
||||
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
|
||||
// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
|
||||
// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\
|
||||
// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
|
||||
// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist\
|
||||
// RUN: -x objective-c++ -std=gnu++98
|
||||
// FIXLATER: cat %t.objc.plist ; FileCheck --input-file=%t.objc.plist %s
|
||||
// FIXLATER: cat %t.objcpp.plist ; FileCheck --input-file=%t.objcpp.plist %s
|
||||
|
||||
void clang_analyzer_eval(int);
|
||||
|
||||
#if __has_feature(attribute_ns_returns_retained)
|
||||
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
|
||||
#endif
|
||||
|
|
@ -495,6 +506,21 @@ void testLeakWithReturnsRetainedOutParameter() {
|
|||
// status is returned.
|
||||
}
|
||||
|
||||
typedef CFTypeRef CMBufferRef;
|
||||
|
||||
typedef CFTypeRef *CMBufferQueueRef;
|
||||
|
||||
CMBufferRef CMBufferQueueDequeueAndRetain(CMBufferQueueRef);
|
||||
|
||||
void testCMBufferQueueDequeueAndRetain(CMBufferQueueRef queue) {
|
||||
CMBufferRef buffer = CMBufferQueueDequeueAndRetain(queue); // expected-warning{{Potential leak of an object stored into 'buffer'}}
|
||||
// There's a state split due to the eagerly-assume behavior.
|
||||
// The point here is that we don't treat CMBufferQueueDequeueAndRetain
|
||||
// as some sort of CFRetain() that returns its argument.
|
||||
clang_analyzer_eval((CMFooRef)buffer == (CMFooRef)queue); // expected-warning{{TRUE}}
|
||||
// expected-warning@-1{{FALSE}}
|
||||
}
|
||||
|
||||
// Test retain/release checker with CFString and CFMutableArray.
|
||||
void f11() {
|
||||
// Create the array.
|
||||
|
|
|
|||
Loading…
Reference in New Issue