blob: 5a7ec1e8b06ba9d081decec88e95a3c470195a98 [file] [log] [blame]
Anton Yartsev05789592013-03-28 17:05:19 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
2
3#include "Inputs/system-header-simulator-objc.h"
4#include "Inputs/system-header-simulator-cxx.h"
5
6typedef __typeof__(sizeof(int)) size_t;
7void *malloc(size_t);
8void *realloc(void *ptr, size_t size);
9void *calloc(size_t nmemb, size_t size);
10char *strdup(const char *s);
11void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
12
13void free(void *);
14void __attribute((ownership_takes(malloc, 1))) my_free(void *);
15
16//---------------------------------------------------------------
17// Test if an allocation function matches deallocation function
18//---------------------------------------------------------------
19
20//--------------- test malloc family
21void testMalloc1() {
22 int *p = (int *)malloc(sizeof(int));
23 delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
24}
25
26void testMalloc2() {
27 int *p = (int *)malloc(8);
28 int *q = (int *)realloc(p, 16);
29 delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}}
30}
31
32void testMalloc3() {
33 int *p = (int *)calloc(1, sizeof(int));
34 delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
35}
36
37void testMalloc4(const char *s) {
38 char *p = strdup(s);
39 delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
40}
41
42void testMalloc5() {
43 int *p = (int *)my_malloc(sizeof(int));
44 delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}}
45}
46
47void testMalloc6() {
48 int *p = (int *)malloc(sizeof(int));
49 operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}}
50}
51
52void testMalloc7() {
53 int *p = (int *)malloc(sizeof(int));
54 delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
55}
56
57void testMalloc8() {
58 int *p = (int *)malloc(sizeof(int));
59 operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}}
60}
61
62//--------------- test new family
63void testNew1() {
64 int *p = new int;
65 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
66}
67
68void testNew2() {
69 int *p = (int *)operator new(0);
70 free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
71}
72
73void testNew3() {
74 int *p = new int[1];
75 free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
76}
77
78void testNew4() {
79 int *p = new int;
80 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
81}
82
83void testNew5() {
84 int *p = (int *)operator new(0);
85 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
86}
87
88void testNew6() {
89 int *p = new int[1];
90 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
91}
92
93void testNew7() {
94 int *p = new int;
95 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
96}
97
98void testNew8() {
99 int *p = (int *)operator new(0);
100 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
101}
102
103void testNew9() {
104 int *p = new int[1];
105 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
106}
107
108void testNew10() {
109 int *p = (int *)operator new[](0);
110 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
111}
112
113void testNew11(NSUInteger dataLength) {
114 int *p = new int;
115 NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not +dataWithBytesNoCopy:length:freeWhenDone:}}
116 // FIXME: should be "+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'."
117}
118
119//-------------------------------------------------------
120// Check for intersection with unix.Malloc bounded with
121// unix.MismatchedDeallocator
122//-------------------------------------------------------
123
124// new/delete oparators are subjects of cplusplus.NewDelete.
125void testNewDeleteNoWarn() {
126 int i;
127 delete &i; // no-warning
128
129 int *p1 = new int;
130 delete ++p1; // no-warning
131
132 int *p2 = new int;
133 delete p2;
134 delete p2; // no-warning
135
136 int *p3 = new int; // no-warning
137}
138
139void testDeleteOpAfterFree() {
140 int *p = (int *)malloc(sizeof(int));
141 free(p);
142 operator delete(p); // no-warning
143}
144
145void testDeleteAfterFree() {
146 int *p = (int *)malloc(sizeof(int));
147 free(p);
148 delete p; // no-warning
149}
150
151void testStandardPlacementNewAfterFree() {
152 int *p = (int *)malloc(sizeof(int));
153 free(p);
154 p = new(p) int; // no-warning
155}
156
157//---------------------------------------------------------------
158// Check for intersection with cplusplus.NewDelete bounded with
159// unix.MismatchedDeallocator
160//---------------------------------------------------------------
161
162// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
163void testMallocFreeNoWarn() {
164 int i;
165 free(&i); // no-warning
166
167 int *p1 = (int *)malloc(sizeof(int));
168 free(++p1); // no-warning
169
170 int *p2 = (int *)malloc(sizeof(int));
171 free(p2);
172 free(p2); // no-warning
173
174 int *p3 = (int *)malloc(sizeof(int)); // no-warning
175}
176
177void testFreeAfterDelete() {
178 int *p = new int;
179 delete p;
180 free(p); // no-warning
181}
182
183void testStandardPlacementNewAfterDelete() {
184 int *p = new int;
185 delete p;
186 p = new(p) int; // no-warning
187}