xref: /aosp_15_r20/external/clang/test/Analysis/keychainAPI.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
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