blob: d2409ac1609ce868d0d890a1a0f12fde440ba363 [file] [log] [blame]
Anna Zaksf5aa3f52012-03-22 00:57:20 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s
Anna Zaks3cd89ad2012-02-24 23:56:53 +00002#include "system-header-simulator-objc.h"
Anna Zaksad901a62012-02-16 22:26:15 +00003
4typedef __typeof(sizeof(int)) size_t;
5void *malloc(size_t);
6void free(void *);
7
8// Done with headers. Start testing.
9void testNSDatafFreeWhenDoneNoError(NSUInteger dataLength) {
10 unsigned char *data = (unsigned char *)malloc(42);
11 NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength];
12 free(data); // no warning
13}
14
Anna Zaks3cd89ad2012-02-24 23:56:53 +000015void testNSDataFreeWhenDoneYES(NSUInteger dataLength) {
16 unsigned char *data = (unsigned char *)malloc(42);
17 NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning
18}
19
20void testNSDataFreeWhenDoneYES2(NSUInteger dataLength) {
21 unsigned char *data = (unsigned char *)malloc(42);
22 NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning
23}
24
25
26void testNSStringFreeWhenDoneYES(NSUInteger dataLength) {
27 unsigned char *data = (unsigned char *)malloc(42);
28 NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; // no-warning
29}
30
31void testNSStringFreeWhenDoneYES2(NSUInteger dataLength) {
32 unichar *data = (unichar*)malloc(42);
33 NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; // no-warning
34}
35
36
37void testNSDataFreeWhenDoneNO(NSUInteger dataLength) {
38 unsigned char *data = (unsigned char *)malloc(42);
39 NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}
40}
41
42void testNSDataFreeWhenDoneNO2(NSUInteger dataLength) {
43 unsigned char *data = (unsigned char *)malloc(42);
44 NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}
45}
46
47
48void testNSStringFreeWhenDoneNO(NSUInteger dataLength) {
49 unsigned char *data = (unsigned char *)malloc(42);
50 NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:0]; // expected-warning{{leak}}
51}
52
53void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) {
54 unichar *data = (unichar*)malloc(42);
55 NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}}
56}
57
58// TODO: False Negative.
59void testNSDatafFreeWhenDoneFN(NSUInteger dataLength) {
Anna Zaksad901a62012-02-16 22:26:15 +000060 unsigned char *data = (unsigned char *)malloc(42);
61 NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1];
62 free(data); // false negative
63}
Anna Zaks07d39a42012-02-28 01:54:22 +000064
Anna Zaksca23eb22012-02-29 18:42:47 +000065// Test CF/NS...NoCopy. PR12100: Pointers can escape when custom deallocators are provided.
Anna Zaks07d39a42012-02-28 01:54:22 +000066void testNSDatafFreeWhenDone(NSUInteger dataLength) {
67 CFStringRef str;
68 char *bytes = (char*)malloc(12);
69 str = CFStringCreateWithCStringNoCopy(0, bytes, NSNEXTSTEPStringEncoding, 0); // no warning
70 CFRelease(str); // default allocator also frees bytes
71}
72
73void stringWithExternalContentsExample(void) {
74#define BufferSize 1000
75 CFMutableStringRef mutStr;
76 UniChar *myBuffer;
77
78 myBuffer = (UniChar *)malloc(BufferSize * sizeof(UniChar));
79
80 mutStr = CFStringCreateMutableWithExternalCharactersNoCopy(0, myBuffer, 0, BufferSize, kCFAllocatorNull); // expected-warning{{leak}}
81
82 CFRelease(mutStr);
83 //free(myBuffer);
84}
Anna Zaksca23eb22012-02-29 18:42:47 +000085
86// PR12101 : pointers can escape through custom deallocators set on creation of a container.
87void TestCallbackReleasesMemory(CFDictionaryKeyCallBacks keyCallbacks) {
88 void *key = malloc(12);
89 void *val = malloc(12);
90 CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallbacks, &kCFTypeDictionaryValueCallBacks);
91 CFDictionarySetValue(x, key, val);
92 return;// no-warning
93}
Anna Zaksfb7f76f2012-03-05 17:42:10 +000094
95NSData *radar10976702() {
96 void *bytes = malloc(10);
97 return [NSData dataWithBytesNoCopy:bytes length:10]; // no-warning
98}
99
Anna Zaksf5aa3f52012-03-22 00:57:20 +0000100void testBlocks() {
101 int *x= (int*)malloc(sizeof(int));
102 int (^myBlock)(int) = ^(int num) {
103 free(x);
104 return num;
105 };
106 myBlock(3);
107}
108
Anna Zaks62a5c342012-03-30 05:48:16 +0000109// Test NSMapInsert.
110@interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration>
111@end
112extern void *NSMapGet(NSMapTable *table, const void *key);
113extern void NSMapInsert(NSMapTable *table, const void *key, const void *value);
114extern void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value);
115char *strdup(const char *s);
116
117NSString * radar11152419(NSString *string1, NSMapTable *map) {
118 const char *strkey = "key";
119 NSString *string = ( NSString *)NSMapGet(map, strkey);
120 if (!string) {
121 string = [string1 copy];
122 NSMapInsert(map, strdup(strkey), (void*)string); // no warning
123 NSMapInsertKnownAbsent(map, strdup(strkey), (void*)string); // no warning
124 }
125 return string;
126}
127
Anna Zaks4cd7edf2012-03-26 18:18:39 +0000128// Test that we handle pointer escaping through OSAtomicEnqueue.
129typedef volatile struct {
130 void *opaque1;
131 long opaque2;
132} OSQueueHead;
133void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __attribute__((weak_import));
134static inline void radar11111210(OSQueueHead *pool) {
135 void *newItem = malloc(4);
136 OSAtomicEnqueue(pool, newItem, 4);
137}
138