comparison clang/test/Analysis/MismatchedDeallocator-checker-test.mm @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children
comparison
equal deleted inserted replaced
147:c2174574ed3a 150:1d019706d866
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
3
4 #include "Inputs/system-header-simulator-objc.h"
5 #include "Inputs/system-header-simulator-cxx.h"
6
7 typedef __typeof__(sizeof(int)) size_t;
8 void *malloc(size_t);
9 void *realloc(void *ptr, size_t size);
10 void *calloc(size_t nmemb, size_t size);
11 char *strdup(const char *s);
12 void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
13
14 void free(void *);
15 void __attribute((ownership_takes(malloc, 1))) my_free(void *);
16
17 //---------------------------------------------------------------
18 // Test if an allocation function matches deallocation function
19 //---------------------------------------------------------------
20
21 //--------------- test malloc family
22 void testMalloc1() {
23 int *p = (int *)malloc(sizeof(int));
24 delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
25 }
26
27 void testMalloc2() {
28 int *p = (int *)malloc(8);
29 int *q = (int *)realloc(p, 16);
30 delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}}
31 }
32
33 void testMalloc3() {
34 int *p = (int *)calloc(1, sizeof(int));
35 delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
36 }
37
38 void testMalloc4(const char *s) {
39 char *p = strdup(s);
40 delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
41 }
42
43 void testMalloc5() {
44 int *p = (int *)my_malloc(sizeof(int));
45 delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}}
46 }
47
48 void testMalloc6() {
49 int *p = (int *)malloc(sizeof(int));
50 operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}}
51 }
52
53 void testMalloc7() {
54 int *p = (int *)malloc(sizeof(int));
55 delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
56 }
57
58 void testMalloc8() {
59 int *p = (int *)malloc(sizeof(int));
60 operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}}
61 }
62
63 void testAlloca() {
64 int *p = (int *)__builtin_alloca(sizeof(int));
65 delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
66 }
67
68 //--------------- test new family
69 void testNew1() {
70 int *p = new int;
71 free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
72 }
73
74 void testNew2() {
75 int *p = (int *)operator new(0);
76 free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
77 }
78
79 void testNew3() {
80 int *p = new int[1];
81 free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
82 }
83
84 void testNew4() {
85 int *p = new int;
86 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
87 }
88
89 void testNew5() {
90 int *p = (int *)operator new(0);
91 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
92 }
93
94 void testNew6() {
95 int *p = new int[1];
96 realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
97 }
98
99 int *allocInt() {
100 return new int;
101 }
102 void testNew7() {
103 int *p = allocInt();
104 delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
105 }
106
107 void testNew8() {
108 int *p = (int *)operator new(0);
109 delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
110 }
111
112 int *allocIntArray(unsigned c) {
113 return new int[c];
114 }
115
116 void testNew9() {
117 int *p = allocIntArray(1);
118 delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
119 }
120
121 void testNew10() {
122 int *p = (int *)operator new[](0);
123 delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
124 }
125
126 void testNew11(NSUInteger dataLength) {
127 int *p = new int;
128 NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}
129 }
130
131 //-------------------------------------------------------
132 // Check for intersection with unix.Malloc bounded with
133 // unix.MismatchedDeallocator
134 //-------------------------------------------------------
135
136 // new/delete oparators are subjects of cplusplus.NewDelete.
137 void testNewDeleteNoWarn() {
138 int i;
139 delete &i; // no-warning
140
141 int *p1 = new int;
142 delete ++p1; // no-warning
143
144 int *p2 = new int;
145 delete p2;
146 delete p2; // no-warning
147
148 int *p3 = new int; // no-warning
149 }
150
151 void testDeleteOpAfterFree() {
152 int *p = (int *)malloc(sizeof(int));
153 free(p);
154 operator delete(p); // no-warning
155 }
156
157 void testDeleteAfterFree() {
158 int *p = (int *)malloc(sizeof(int));
159 free(p);
160 delete p; // no-warning
161 }
162
163 void testStandardPlacementNewAfterFree() {
164 int *p = (int *)malloc(sizeof(int));
165 free(p);
166 p = new(p) int; // no-warning
167 }
168
169 //---------------------------------------------------------------
170 // Check for intersection with cplusplus.NewDelete bounded with
171 // unix.MismatchedDeallocator
172 //---------------------------------------------------------------
173
174 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
175 void testMallocFreeNoWarn() {
176 int i;
177 free(&i); // no-warning
178
179 int *p1 = (int *)malloc(sizeof(int));
180 free(++p1); // no-warning
181
182 int *p2 = (int *)malloc(sizeof(int));
183 free(p2);
184 free(p2); // no-warning
185
186 int *p3 = (int *)malloc(sizeof(int)); // no-warning
187 }
188
189 void testFreeAfterDelete() {
190 int *p = new int;
191 delete p;
192 free(p); // no-warning
193 }
194
195 void testStandardPlacementNewAfterDelete() {
196 int *p = new int;
197 delete p;
198 p = new(p) int; // no-warning
199 }
200
201
202 // Smart pointer example
203 template <typename T>
204 struct SimpleSmartPointer {
205 T *ptr;
206
207 explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
208 ~SimpleSmartPointer() {
209 delete ptr;
210 // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
211 // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
212 }
213 };
214
215 void testSimpleSmartPointerArrayNew() {
216 {
217 SimpleSmartPointer<int> a(new int);
218 } // no-warning
219
220 {
221 SimpleSmartPointer<int> a(new int[4]);
222 }
223 }
224
225 void testSimpleSmartPointerMalloc() {
226 {
227 SimpleSmartPointer<int> a(new int);
228 } // no-warning
229
230 {
231 SimpleSmartPointer<int> a((int *)malloc(4));
232 }
233 }