Add 'AppendValue' to the list of magic CF function names that cause a tracked object to escape. Fixes <rdar://problem/6560661>.

llvm-svn: 63891
This commit is contained in:
Ted Kremenek 2009-02-05 22:34:53 +00:00
parent 2599084ac5
commit 0ca23d3f73
2 changed files with 18 additions and 1 deletions

View File

@ -826,7 +826,8 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
//
ArgEffect E = (CStrInCStrNoCase(FName, "InsertValue") ||
CStrInCStrNoCase(FName, "AddValue") ||
CStrInCStrNoCase(FName, "SetValue"))
CStrInCStrNoCase(FName, "SetValue") ||
CStrInCStrNoCase(FName, "AppendValue"))
? MayEscape : DoNothing;
S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);

View File

@ -15,7 +15,11 @@ enum { kCFNumberSInt32Type = 3 };
CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
void CFDictionaryAddValue(CFMutableDictionaryRef theDict, const void *key, const void *value);
void CFRelease(CFTypeRef cf);
CFTypeRef CFRetain(CFTypeRef cf);
extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
typedef const struct __CFArray * CFArrayRef;
typedef struct __CFArray * CFMutableArrayRef;
void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
void f(CFMutableDictionaryRef y, void* key, void* val_key) {
CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
@ -29,3 +33,15 @@ void f(CFMutableDictionaryRef y, void* key, void* val_key) {
CFDictionaryAddValue(y, val_key, value); // no-warning
}
}
// <rdar://problem/6560661>
// Same issue, except with "AppendValue" functions.
void f2(CFMutableArrayRef x) {
signed z = 1;
CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);
// CFArrayAppendValue keeps a reference to value.
CFArrayAppendValue(x, value);
CFRelease(value);
CFRetain(value);
CFRelease(value); // no-warning
}