1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify 2*67e74705SXin Li 3*67e74705SXin Li// Fake typedefs. 4*67e74705SXin Litypedef unsigned int OSStatus; 5*67e74705SXin Litypedef unsigned int SecKeychainAttributeList; 6*67e74705SXin Litypedef unsigned int SecKeychainItemRef; 7*67e74705SXin Litypedef unsigned int SecItemClass; 8*67e74705SXin Litypedef unsigned int UInt32; 9*67e74705SXin Litypedef unsigned int CFTypeRef; 10*67e74705SXin Litypedef unsigned int UInt16; 11*67e74705SXin Litypedef unsigned int SecProtocolType; 12*67e74705SXin Litypedef unsigned int SecAuthenticationType; 13*67e74705SXin Litypedef unsigned int SecKeychainAttributeInfo; 14*67e74705SXin Lienum { 15*67e74705SXin Li noErr = 0, 16*67e74705SXin Li GenericError = 1 17*67e74705SXin Li}; 18*67e74705SXin Li 19*67e74705SXin Li// Functions that allocate data. 20*67e74705SXin LiOSStatus SecKeychainItemCopyContent ( 21*67e74705SXin Li SecKeychainItemRef itemRef, 22*67e74705SXin Li SecItemClass *itemClass, 23*67e74705SXin Li SecKeychainAttributeList *attrList, 24*67e74705SXin Li UInt32 *length, 25*67e74705SXin Li void **outData 26*67e74705SXin Li); 27*67e74705SXin LiOSStatus SecKeychainFindGenericPassword ( 28*67e74705SXin Li CFTypeRef keychainOrArray, 29*67e74705SXin Li UInt32 serviceNameLength, 30*67e74705SXin Li const char *serviceName, 31*67e74705SXin Li UInt32 accountNameLength, 32*67e74705SXin Li const char *accountName, 33*67e74705SXin Li UInt32 *passwordLength, 34*67e74705SXin Li void **passwordData, 35*67e74705SXin Li SecKeychainItemRef *itemRef 36*67e74705SXin Li); 37*67e74705SXin LiOSStatus SecKeychainFindInternetPassword ( 38*67e74705SXin Li CFTypeRef keychainOrArray, 39*67e74705SXin Li UInt32 serverNameLength, 40*67e74705SXin Li const char *serverName, 41*67e74705SXin Li UInt32 securityDomainLength, 42*67e74705SXin Li const char *securityDomain, 43*67e74705SXin Li UInt32 accountNameLength, 44*67e74705SXin Li const char *accountName, 45*67e74705SXin Li UInt32 pathLength, 46*67e74705SXin Li const char *path, 47*67e74705SXin Li UInt16 port, 48*67e74705SXin Li SecProtocolType protocol, 49*67e74705SXin Li SecAuthenticationType authenticationType, 50*67e74705SXin Li UInt32 *passwordLength, 51*67e74705SXin Li void **passwordData, 52*67e74705SXin Li SecKeychainItemRef *itemRef 53*67e74705SXin Li); 54*67e74705SXin LiOSStatus SecKeychainItemCopyAttributesAndData ( 55*67e74705SXin Li SecKeychainItemRef itemRef, 56*67e74705SXin Li SecKeychainAttributeInfo *info, 57*67e74705SXin Li SecItemClass *itemClass, 58*67e74705SXin Li SecKeychainAttributeList **attrList, 59*67e74705SXin Li UInt32 *length, 60*67e74705SXin Li void **outData 61*67e74705SXin Li); 62*67e74705SXin Li 63*67e74705SXin Li// Functions which free data. 64*67e74705SXin LiOSStatus SecKeychainItemFreeContent ( 65*67e74705SXin Li SecKeychainAttributeList *attrList, 66*67e74705SXin Li void *data 67*67e74705SXin Li); 68*67e74705SXin LiOSStatus SecKeychainItemFreeAttributesAndData ( 69*67e74705SXin Li SecKeychainAttributeList *attrList, 70*67e74705SXin Li void *data 71*67e74705SXin Li); 72*67e74705SXin Li 73*67e74705SXin Livoid errRetVal() { 74*67e74705SXin Li unsigned int *ptr = 0; 75*67e74705SXin Li OSStatus st = 0; 76*67e74705SXin Li UInt32 length; 77*67e74705SXin Li void *outData; 78*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 79*67e74705SXin Li if (st == GenericError) 80*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}} 81*67e74705SXin Li} // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}} 82*67e74705SXin Li 83*67e74705SXin Li// If null is passed in, the data is not allocated, so no need for the matching free. 84*67e74705SXin Livoid fooDoNotReportNull() { 85*67e74705SXin Li unsigned int *ptr = 0; 86*67e74705SXin Li OSStatus st = 0; 87*67e74705SXin Li UInt32 *length = 0; 88*67e74705SXin Li void **outData = 0; 89*67e74705SXin Li SecKeychainItemCopyContent(2, ptr, ptr, 0, 0); 90*67e74705SXin Li SecKeychainItemCopyContent(2, ptr, ptr, length, outData); 91*67e74705SXin Li}// no-warning 92*67e74705SXin Li 93*67e74705SXin Livoid doubleAlloc() { 94*67e74705SXin Li unsigned int *ptr = 0; 95*67e74705SXin Li OSStatus st = 0; 96*67e74705SXin Li UInt32 length; 97*67e74705SXin Li void *outData; 98*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 99*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); // expected-warning {{Allocated data should be released before another call to the allocator:}} 100*67e74705SXin Li if (st == noErr) 101*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData); 102*67e74705SXin Li} 103*67e74705SXin Li 104*67e74705SXin Livoid fooOnlyFree() { 105*67e74705SXin Li unsigned int *ptr = 0; 106*67e74705SXin Li OSStatus st = 0; 107*67e74705SXin Li UInt32 length; 108*67e74705SXin Li void *outData = &length; 109*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}} 110*67e74705SXin Li} 111*67e74705SXin Li 112*67e74705SXin Li// Do not warn if undefined value is passed to a function. 113*67e74705SXin Livoid fooOnlyFreeUndef() { 114*67e74705SXin Li unsigned int *ptr = 0; 115*67e74705SXin Li OSStatus st = 0; 116*67e74705SXin Li UInt32 length; 117*67e74705SXin Li void *outData; 118*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData); 119*67e74705SXin Li}// no-warning 120*67e74705SXin Li 121*67e74705SXin Li// Do not warn if the address is a parameter in the enclosing function. 122*67e74705SXin Livoid fooOnlyFreeParam(void *attrList, void* X) { 123*67e74705SXin Li SecKeychainItemFreeContent(attrList, X); 124*67e74705SXin Li}// no-warning 125*67e74705SXin Li 126*67e74705SXin Li// If we are returning the value, do not report. 127*67e74705SXin Livoid* returnContent() { 128*67e74705SXin Li unsigned int *ptr = 0; 129*67e74705SXin Li OSStatus st = 0; 130*67e74705SXin Li UInt32 length; 131*67e74705SXin Li void *outData; 132*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 133*67e74705SXin Li return outData; 134*67e74705SXin Li} // no-warning 135*67e74705SXin Li 136*67e74705SXin Li// Password was passed in as an argument and does not have to be deleted. 137*67e74705SXin LiOSStatus getPasswordAndItem(void** password, UInt32* passwordLength) { 138*67e74705SXin Li OSStatus err; 139*67e74705SXin Li SecKeychainItemRef item; 140*67e74705SXin Li err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", 141*67e74705SXin Li passwordLength, password, &item); 142*67e74705SXin Li return err; 143*67e74705SXin Li} // no-warning 144*67e74705SXin Li 145*67e74705SXin Li// Make sure we do not report an error if we call free only if password != 0. 146*67e74705SXin Li// Also, do not report double allocation if first allocation returned an error. 147*67e74705SXin LiOSStatus testSecKeychainFindGenericPassword(UInt32* passwordLength, 148*67e74705SXin Li CFTypeRef keychainOrArray, SecProtocolType protocol, 149*67e74705SXin Li SecAuthenticationType authenticationType) { 150*67e74705SXin Li OSStatus err; 151*67e74705SXin Li SecKeychainItemRef item; 152*67e74705SXin Li void *password; 153*67e74705SXin Li err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", 154*67e74705SXin Li passwordLength, &password, &item); 155*67e74705SXin Li if( err == GenericError ) { 156*67e74705SXin Li err = SecKeychainFindInternetPassword(keychainOrArray, 157*67e74705SXin Li 16, "server", 16, "domain", 16, "account", 158*67e74705SXin Li 16, "path", 222, protocol, authenticationType, 159*67e74705SXin Li passwordLength, &(password), 0); 160*67e74705SXin Li } 161*67e74705SXin Li 162*67e74705SXin Li if (err == noErr && password) { 163*67e74705SXin Li SecKeychainItemFreeContent(0, password); 164*67e74705SXin Li } 165*67e74705SXin Li return err; 166*67e74705SXin Li} 167*67e74705SXin Li 168*67e74705SXin Liint apiMismatch(SecKeychainItemRef itemRef, 169*67e74705SXin Li SecKeychainAttributeInfo *info, 170*67e74705SXin Li SecItemClass *itemClass) { 171*67e74705SXin Li OSStatus st = 0; 172*67e74705SXin Li SecKeychainAttributeList *attrList; 173*67e74705SXin Li UInt32 length; 174*67e74705SXin Li void *outData; 175*67e74705SXin Li 176*67e74705SXin Li st = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 177*67e74705SXin Li &attrList, &length, &outData); 178*67e74705SXin Li if (st == noErr) 179*67e74705SXin Li SecKeychainItemFreeContent(attrList, outData); // expected-warning{{Deallocator doesn't match the allocator}} 180*67e74705SXin Li return 0; 181*67e74705SXin Li} 182*67e74705SXin Li 183*67e74705SXin Liint ErrorCodesFromDifferentAPISDoNotInterfere(SecKeychainItemRef itemRef, 184*67e74705SXin Li SecKeychainAttributeInfo *info, 185*67e74705SXin Li SecItemClass *itemClass) { 186*67e74705SXin Li unsigned int *ptr = 0; 187*67e74705SXin Li OSStatus st = 0; 188*67e74705SXin Li UInt32 length; 189*67e74705SXin Li void *outData; 190*67e74705SXin Li OSStatus st2 = 0; 191*67e74705SXin Li SecKeychainAttributeList *attrList; 192*67e74705SXin Li UInt32 length2; 193*67e74705SXin Li void *outData2; 194*67e74705SXin Li 195*67e74705SXin Li st2 = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 196*67e74705SXin Li &attrList, &length2, &outData2); 197*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 198*67e74705SXin Li if (st == noErr) { 199*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData); 200*67e74705SXin Li if (st2 == noErr) { 201*67e74705SXin Li SecKeychainItemFreeAttributesAndData(attrList, outData2); 202*67e74705SXin Li } 203*67e74705SXin Li } 204*67e74705SXin Li return 0; // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeAttributesAndData'}} 205*67e74705SXin Li} 206*67e74705SXin Li 207*67e74705SXin Liint foo(CFTypeRef keychainOrArray, SecProtocolType protocol, 208*67e74705SXin Li SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) { 209*67e74705SXin Li unsigned int *ptr = 0; 210*67e74705SXin Li OSStatus st = 0; 211*67e74705SXin Li 212*67e74705SXin Li UInt32 length; 213*67e74705SXin Li void *outData[5]; 214*67e74705SXin Li 215*67e74705SXin Li st = SecKeychainFindInternetPassword(keychainOrArray, 216*67e74705SXin Li 16, "server", 16, "domain", 16, "account", 217*67e74705SXin Li 16, "path", 222, protocol, authenticationType, 218*67e74705SXin Li &length, &(outData[3]), itemRef); 219*67e74705SXin Li if (length == 5) { 220*67e74705SXin Li if (st == noErr) 221*67e74705SXin Li SecKeychainItemFreeContent(ptr, outData[3]); 222*67e74705SXin Li } 223*67e74705SXin Li if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}} 224*67e74705SXin Li length++; 225*67e74705SXin Li } 226*67e74705SXin Li return 0; 227*67e74705SXin Li}// no-warning 228*67e74705SXin Li 229*67e74705SXin Livoid free(void *ptr); 230*67e74705SXin Livoid deallocateWithFree() { 231*67e74705SXin Li unsigned int *ptr = 0; 232*67e74705SXin Li OSStatus st = 0; 233*67e74705SXin Li UInt32 length; 234*67e74705SXin Li void *outData; 235*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 236*67e74705SXin Li if (st == noErr) 237*67e74705SXin Li free(outData); // expected-warning{{Deallocator doesn't match the allocator: 'SecKeychainItemFreeContent' should be used}} 238*67e74705SXin Li} 239*67e74705SXin Li 240*67e74705SXin Li// Typesdefs for CFStringCreateWithBytesNoCopy. 241*67e74705SXin Litypedef char uint8_t; 242*67e74705SXin Litypedef signed long CFIndex; 243*67e74705SXin Litypedef UInt32 CFStringEncoding; 244*67e74705SXin Litypedef unsigned Boolean; 245*67e74705SXin Litypedef const struct __CFString * CFStringRef; 246*67e74705SXin Litypedef const struct __CFAllocator * CFAllocatorRef; 247*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorDefault; 248*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorSystemDefault; 249*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorMalloc; 250*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorMallocZone; 251*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorNull; 252*67e74705SXin Liextern const CFAllocatorRef kCFAllocatorUseContext; 253*67e74705SXin LiCFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator); 254*67e74705SXin Liextern void CFRelease(CFStringRef cf); 255*67e74705SXin Li 256*67e74705SXin Livoid DellocWithCFStringCreate1(CFAllocatorRef alloc) { 257*67e74705SXin Li unsigned int *ptr = 0; 258*67e74705SXin Li OSStatus st = 0; 259*67e74705SXin Li UInt32 length; 260*67e74705SXin Li void *bytes; 261*67e74705SXin Li char * x; 262*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 263*67e74705SXin Li if (st == noErr) { 264*67e74705SXin Li CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorDefault); // expected-warning{{Deallocator doesn't match the allocator:}} 265*67e74705SXin Li CFRelease(userStr); 266*67e74705SXin Li } 267*67e74705SXin Li} 268*67e74705SXin Li 269*67e74705SXin Livoid DellocWithCFStringCreate2(CFAllocatorRef alloc) { 270*67e74705SXin Li unsigned int *ptr = 0; 271*67e74705SXin Li OSStatus st = 0; 272*67e74705SXin Li UInt32 length; 273*67e74705SXin Li void *bytes; 274*67e74705SXin Li char * x; 275*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 276*67e74705SXin Li if (st == noErr) { 277*67e74705SXin Li CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorNull); // expected-warning{{Allocated data is not released}} 278*67e74705SXin Li CFRelease(userStr); 279*67e74705SXin Li } 280*67e74705SXin Li} 281*67e74705SXin Li 282*67e74705SXin Livoid DellocWithCFStringCreate3(CFAllocatorRef alloc) { 283*67e74705SXin Li unsigned int *ptr = 0; 284*67e74705SXin Li OSStatus st = 0; 285*67e74705SXin Li UInt32 length; 286*67e74705SXin Li void *bytes; 287*67e74705SXin Li char * x; 288*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 289*67e74705SXin Li if (st == noErr) { 290*67e74705SXin Li CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorUseContext); 291*67e74705SXin Li CFRelease(userStr); 292*67e74705SXin Li } 293*67e74705SXin Li} 294*67e74705SXin Li 295*67e74705SXin Livoid DellocWithCFStringCreate4(CFAllocatorRef alloc) { 296*67e74705SXin Li unsigned int *ptr = 0; 297*67e74705SXin Li OSStatus st = 0; 298*67e74705SXin Li UInt32 length; 299*67e74705SXin Li void *bytes; 300*67e74705SXin Li char * x; 301*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 302*67e74705SXin Li if (st == noErr) { 303*67e74705SXin Li CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, 0); // expected-warning{{Deallocator doesn't match the allocator:}} 304*67e74705SXin Li CFRelease(userStr); 305*67e74705SXin Li } 306*67e74705SXin Li} 307*67e74705SXin Li 308*67e74705SXin Listatic CFAllocatorRef gKeychainDeallocator = 0; 309*67e74705SXin Li 310*67e74705SXin Listatic CFAllocatorRef GetKeychainDeallocator() { 311*67e74705SXin Li return gKeychainDeallocator; 312*67e74705SXin Li} 313*67e74705SXin Li 314*67e74705SXin LiCFStringRef DellocWithCFStringCreate5(CFAllocatorRef alloc) { 315*67e74705SXin Li unsigned int *ptr = 0; 316*67e74705SXin Li OSStatus st = 0; 317*67e74705SXin Li UInt32 length; 318*67e74705SXin Li void *bytes; 319*67e74705SXin Li char * x; 320*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes); 321*67e74705SXin Li if (st == noErr) { 322*67e74705SXin Li return CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, GetKeychainDeallocator()); // no-warning 323*67e74705SXin Li } 324*67e74705SXin Li return 0; 325*67e74705SXin Li} 326*67e74705SXin Li 327*67e74705SXin Livoid radar10508828() { 328*67e74705SXin Li UInt32 pwdLen = 0; 329*67e74705SXin Li void* pwdBytes = 0; 330*67e74705SXin Li OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0); 331*67e74705SXin Li#pragma unused(rc) 332*67e74705SXin Li if (pwdBytes) 333*67e74705SXin Li SecKeychainItemFreeContent(0, pwdBytes); 334*67e74705SXin Li} 335*67e74705SXin Li 336*67e74705SXin Livoid radar10508828_2() { 337*67e74705SXin Li UInt32 pwdLen = 0; 338*67e74705SXin Li void* pwdBytes = 0; 339*67e74705SXin Li OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0); 340*67e74705SXin Li SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}} 341*67e74705SXin Li} 342*67e74705SXin Li 343*67e74705SXin Li//Example from bug 10797. 344*67e74705SXin Li__inline__ static 345*67e74705SXin Liconst char *__WBASLLevelString(int level) { 346*67e74705SXin Li return "foo"; 347*67e74705SXin Li} 348*67e74705SXin Li 349*67e74705SXin Listatic int *bug10798(int *p, int columns, int prevRow) { 350*67e74705SXin Li int *row = 0; 351*67e74705SXin Li row = p + prevRow * columns; 352*67e74705SXin Li prevRow += 2; 353*67e74705SXin Li do { 354*67e74705SXin Li ++prevRow; 355*67e74705SXin Li row+=columns; 356*67e74705SXin Li } while(10 >= row[1]); 357*67e74705SXin Li return row; 358*67e74705SXin Li} 359*67e74705SXin Li 360*67e74705SXin Li// Test inter-procedural behaviour. 361*67e74705SXin Li 362*67e74705SXin Livoid my_FreeParam(void *attrList, void* X) { 363*67e74705SXin Li SecKeychainItemFreeContent(attrList, X); 364*67e74705SXin Li} 365*67e74705SXin Li 366*67e74705SXin Livoid *my_AllocateReturn(OSStatus *st) { 367*67e74705SXin Li unsigned int *ptr = 0; 368*67e74705SXin Li UInt32 length; 369*67e74705SXin Li void *outData; 370*67e74705SXin Li *st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 371*67e74705SXin Li return outData; 372*67e74705SXin Li} 373*67e74705SXin Li 374*67e74705SXin LiOSStatus my_Allocate_Param(void** password, UInt32* passwordLength) { 375*67e74705SXin Li OSStatus err; 376*67e74705SXin Li SecKeychainItemRef item; 377*67e74705SXin Li err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", 378*67e74705SXin Li passwordLength, password, &item); 379*67e74705SXin Li return err; 380*67e74705SXin Li} 381*67e74705SXin Li 382*67e74705SXin Livoid allocAndFree1() { 383*67e74705SXin Li unsigned int *ptr = 0; 384*67e74705SXin Li OSStatus st = 0; 385*67e74705SXin Li UInt32 length; 386*67e74705SXin Li void *outData; 387*67e74705SXin Li st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 388*67e74705SXin Li if (st == noErr) 389*67e74705SXin Li my_FreeParam(ptr, outData); 390*67e74705SXin Li} 391*67e74705SXin Li 392*67e74705SXin Livoid consumeChar(char); 393*67e74705SXin Li 394*67e74705SXin Livoid allocNoFree2(int x) { 395*67e74705SXin Li OSStatus st = 0; 396*67e74705SXin Li void *outData = my_AllocateReturn(&st); 397*67e74705SXin Li if (x) { 398*67e74705SXin Li consumeChar(*(char*)outData); // expected-warning{{Allocated data is not released:}} 399*67e74705SXin Li return; 400*67e74705SXin Li } else { 401*67e74705SXin Li consumeChar(*(char*)outData); 402*67e74705SXin Li } 403*67e74705SXin Li return; 404*67e74705SXin Li} 405*67e74705SXin Li 406*67e74705SXin Livoid allocAndFree2(void *attrList) { 407*67e74705SXin Li OSStatus st = 0; 408*67e74705SXin Li void *outData = my_AllocateReturn(&st); 409*67e74705SXin Li if (st == noErr) 410*67e74705SXin Li my_FreeParam(attrList, outData); 411*67e74705SXin Li} 412*67e74705SXin Li 413*67e74705SXin Livoid allocNoFree3() { 414*67e74705SXin Li UInt32 length = 32; 415*67e74705SXin Li void *outData; 416*67e74705SXin Li void *outData2; 417*67e74705SXin Li OSStatus st = my_Allocate_Param(&outData, &length); // expected-warning{{Allocated data is not released}} 418*67e74705SXin Li st = my_Allocate_Param(&outData2, &length); // expected-warning{{Allocated data is not released}} 419*67e74705SXin Li} 420*67e74705SXin Li 421*67e74705SXin Livoid allocAndFree3(void *attrList) { 422*67e74705SXin Li UInt32 length = 32; 423*67e74705SXin Li void *outData; 424*67e74705SXin Li OSStatus st = my_Allocate_Param(&outData, &length); 425*67e74705SXin Li if (st == noErr) 426*67e74705SXin Li SecKeychainItemFreeContent(attrList, outData); 427*67e74705SXin Li} 428*67e74705SXin Li 429