CFContainers.mm revision cbd273387a61409f179fcfe8460a8733fcf8f872
1// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.osx.cocoa.ContainerAPI -analyzer-store=region -verify %s
2
3typedef const struct __CFAllocator * CFAllocatorRef;
4typedef const struct __CFString * CFStringRef;
5typedef unsigned char Boolean;
6typedef signed long CFIndex;
7extern
8const CFAllocatorRef kCFAllocatorDefault;
9typedef const void * (*CFArrayRetainCallBack)(CFAllocatorRef allocator, const void *value);
10typedef void (*CFArrayReleaseCallBack)(CFAllocatorRef allocator, const void *value);
11typedef CFStringRef (*CFArrayCopyDescriptionCallBack)(const void *value);
12typedef Boolean (*CFArrayEqualCallBack)(const void *value1, const void *value2);
13typedef struct {
14    CFIndex version;
15    CFArrayRetainCallBack retain;
16    CFArrayReleaseCallBack release;
17    CFArrayCopyDescriptionCallBack copyDescription;
18    CFArrayEqualCallBack equal;
19} CFArrayCallBacks;
20typedef const struct __CFArray * CFArrayRef;
21CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks);
22typedef const struct __CFString * CFStringRef;
23enum {
24    kCFNumberSInt8Type = 1,
25    kCFNumberSInt16Type = 2,
26    kCFNumberSInt32Type = 3,
27    kCFNumberSInt64Type = 4,
28    kCFNumberFloat32Type = 5,
29    kCFNumberFloat64Type = 6,
30    kCFNumberCharType = 7,
31    kCFNumberShortType = 8,
32    kCFNumberIntType = 9,
33    kCFNumberLongType = 10,
34    kCFNumberLongLongType = 11,
35    kCFNumberFloatType = 12,
36    kCFNumberDoubleType = 13,
37    kCFNumberCFIndexType = 14,
38    kCFNumberNSIntegerType = 15,
39    kCFNumberCGFloatType = 16,
40    kCFNumberMaxType = 16
41};
42typedef CFIndex CFNumberType;
43typedef const struct __CFNumber * CFNumberRef;
44typedef CFIndex CFComparisonResult;
45typedef const struct __CFDictionary * CFDictionaryRef;
46typedef const void * (*CFDictionaryRetainCallBack)(CFAllocatorRef allocator, const void *value);
47typedef void (*CFDictionaryReleaseCallBack)(CFAllocatorRef allocator, const void *value);
48typedef CFStringRef (*CFDictionaryCopyDescriptionCallBack)(const void *value);
49typedef Boolean (*CFDictionaryEqualCallBack)(const void *value1, const void *value2);
50typedef Boolean (*CFArrayEqualCallBack)(const void *value1, const void *value2);
51typedef Boolean (*CFSetEqualCallBack)(const void *value1, const void *value2);
52typedef const void * (*CFSetRetainCallBack)(CFAllocatorRef allocator, const void *value);
53typedef void (*CFSetReleaseCallBack)(CFAllocatorRef allocator, const void *value);
54typedef CFStringRef (*CFSetCopyDescriptionCallBack)(const void *value);
55typedef struct {
56    CFIndex version;
57    CFSetRetainCallBack retain;
58    CFSetReleaseCallBack release;
59    CFSetCopyDescriptionCallBack copyDescription;
60    CFSetEqualCallBack equal;
61} CFSetCallBacks;
62typedef struct {
63    CFIndex version;
64    CFDictionaryRetainCallBack retain;
65    CFDictionaryReleaseCallBack release;
66    CFDictionaryCopyDescriptionCallBack copyDescription;
67    CFDictionaryEqualCallBack equal;
68} CFDictionaryKeyCallBacks;
69typedef struct {
70    CFIndex version;
71    CFDictionaryRetainCallBack retain;
72    CFDictionaryReleaseCallBack release;
73    CFDictionaryCopyDescriptionCallBack copyDescription;
74    CFDictionaryEqualCallBack equal;
75} CFDictionaryValueCallBacks;
76CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
77extern
78const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
79typedef const struct __CFSet * CFSetRef;
80extern
81const CFSetCallBacks kCFTypeSetCallBacks;
82extern
83const CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks;
84CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const 
85CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
86CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
87extern
88CFSetRef CFSetCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFSetCallBacks *callBacks);
89#define CFSTR(cStr)  ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
90#define NULL __null
91
92// Done with the headers. 
93// Test experimental.osx.cocoa.ContainerAPI checker.
94void testContainers(int **xNoWarn, CFIndex count) {
95  int x[] = { 1, 2, 3 };
96  CFArrayRef foo = CFArrayCreate(kCFAllocatorDefault, (const void **) x, sizeof(x) / sizeof(x[0]), 0);// expected-warning {{The first argument to 'CFArrayCreate' must be a C array of pointer-sized}}
97
98  CFArrayRef fooNoWarn = CFArrayCreate(kCFAllocatorDefault, (const void **) xNoWarn, sizeof(xNoWarn) / sizeof(xNoWarn[0]), 0); // no warning
99  CFArrayRef fooNoWarn2 = CFArrayCreate(kCFAllocatorDefault, 0, sizeof(xNoWarn) / sizeof(xNoWarn[0]), 0);// no warning, passing in 0
100  CFArrayRef fooNoWarn3 = CFArrayCreate(kCFAllocatorDefault, NULL, sizeof(xNoWarn) / sizeof(xNoWarn[0]), 0);// no warning, passing in NULL
101
102  CFSetRef set = CFSetCreate(NULL, (const void **)x, 3, &kCFTypeSetCallBacks); // expected-warning {{The first argument to 'CFSetCreate' must be a C array of pointer-sized values}}
103  CFArrayRef* pairs = new CFArrayRef[count];
104  CFSetRef fSet = CFSetCreate(kCFAllocatorDefault, (const void**) pairs, count - 1, &kCFTypeSetCallBacks);// no warning
105}
106
107void CreateDict(int *elems) {
108  const short days28 = 28;
109  const short days30 = 30;
110  const short days31 = 31;
111  CFIndex numValues = 6;  
112  CFStringRef keys[6];
113  CFNumberRef values[6];
114  keys[0] = CFSTR("January");  values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &days31);
115  keys[1] = CFSTR("February"); values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &days28);
116  keys[2] = CFSTR("March"); values[2] = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &days31);
117  keys[3] = CFSTR("April"); values[3] = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &days30);
118  keys[4] = CFSTR("May"); values[4] = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &days31);
119  keys[5] = CFSTR("June"); values[5] = CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &days30);
120
121  const CFDictionaryKeyCallBacks keyCB = kCFCopyStringDictionaryKeyCallBacks;
122  const CFDictionaryValueCallBacks valCB = kCFTypeDictionaryValueCallBacks;
123  CFDictionaryRef dict1 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)values, numValues, &keyCB, &valCB); // no warning
124  CFDictionaryRef dict2 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)elems[0], (const void**)values, numValues, &keyCB, &valCB); //expected-warning {{The first argument to 'CFDictionaryCreate' must be a C array of}}
125  CFDictionaryRef dict3 = CFDictionaryCreate(kCFAllocatorDefault, (const void**)keys, (const void**)elems, numValues, &keyCB, &valCB); // expected-warning {{The second argument to 'CFDictionaryCreate' must be a C array of pointer-sized values}}
126}