1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,experimental.unix.MallocWithAnnotations -analyzer-store=region -verify %s 2 typedef __typeof(sizeof(int)) size_t; 3 void *malloc(size_t); 4 void free(void *); 5 void *realloc(void *ptr, size_t size); 6 void *calloc(size_t nmemb, size_t size); 7 void __attribute((ownership_returns(malloc))) *my_malloc(size_t); 8 void __attribute((ownership_takes(malloc, 1))) my_free(void *); 9 void my_freeBoth(void *, void *) 10 __attribute((ownership_holds(malloc, 1, 2))); 11 void __attribute((ownership_returns(malloc, 1))) *my_malloc2(size_t); 12 void __attribute((ownership_holds(malloc, 1))) my_hold(void *); 13 14 // Duplicate attributes are silly, but not an error. 15 // Duplicate attribute has no extra effect. 16 // If two are of different kinds, that is an error and reported as such. 17 void __attribute((ownership_holds(malloc, 1))) 18 __attribute((ownership_holds(malloc, 1))) 19 __attribute((ownership_holds(malloc, 3))) my_hold2(void *, void *, void *); 20 void *my_malloc3(size_t); 21 void *myglobalpointer; 22 struct stuff { 23 void *somefield; 24 }; 25 struct stuff myglobalstuff; 26 27 void f1() { 28 int *p = malloc(12); 29 return; // expected-warning{{Memory is never released; potential leak}} 30 } 31 32 void f2() { 33 int *p = malloc(12); 34 free(p); 35 free(p); // expected-warning{{Attempt to free released memory}} 36 } 37 38 void f2_realloc_0() { 39 int *p = malloc(12); 40 realloc(p,0); 41 realloc(p,0); // expected-warning{{Attempt to free released memory}} 42 } 43 44 void f2_realloc_1() { 45 int *p = malloc(12); 46 int *q = realloc(p,0); // no-warning 47 } 48 49 // ownership attributes tests 50 void naf1() { 51 int *p = my_malloc3(12); 52 return; // no-warning 53 } 54 55 void n2af1() { 56 int *p = my_malloc2(12); 57 return; // expected-warning{{Memory is never released; potential leak}} 58 } 59 60 void af1() { 61 int *p = my_malloc(12); 62 return; // expected-warning{{Memory is never released; potential leak}} 63 } 64 65 void af1_b() { 66 int *p = my_malloc(12); // expected-warning{{Memory is never released; potential leak}} 67 } 68 69 void af1_c() { 70 myglobalpointer = my_malloc(12); // no-warning 71 } 72 73 // TODO: We will be able to handle this after we add support for tracking allocations stored in struct fields. 74 void af1_d() { 75 struct stuff mystuff; 76 mystuff.somefield = my_malloc(12); // false negative 77 } 78 79 // Test that we can pass out allocated memory via pointer-to-pointer. 80 void af1_e(void **pp) { 81 *pp = my_malloc(42); // no-warning 82 } 83 84 void af1_f(struct stuff *somestuff) { 85 somestuff->somefield = my_malloc(12); // no-warning 86 } 87 88 // Allocating memory for a field via multiple indirections to our arguments is OK. 89 void af1_g(struct stuff **pps) { 90 *pps = my_malloc(sizeof(struct stuff)); // no-warning 91 (*pps)->somefield = my_malloc(42); // no-warning 92 } 93 94 void af2() { 95 int *p = my_malloc(12); 96 my_free(p); 97 free(p); // expected-warning{{Attempt to free released memory}} 98 } 99 100 void af2b() { 101 int *p = my_malloc(12); 102 free(p); 103 my_free(p); // expected-warning{{Attempt to free released memory}} 104 } 105 106 void af2c() { 107 int *p = my_malloc(12); 108 free(p); 109 my_hold(p); // expected-warning{{Attempt to free released memory}} 110 } 111 112 void af2d() { 113 int *p = my_malloc(12); 114 free(p); 115 my_hold2(0, 0, p); // expected-warning{{Attempt to free released memory}} 116 } 117 118 // No leak if malloc returns null. 119 void af2e() { 120 int *p = my_malloc(12); 121 if (!p) 122 return; // no-warning 123 free(p); // no-warning 124 } 125 126 // This case would inflict a double-free elsewhere. 127 // However, this case is considered an analyzer bug since it causes false-positives. 128 void af3() { 129 int *p = my_malloc(12); 130 my_hold(p); 131 free(p); // no-warning 132 } 133 134 int * af4() { 135 int *p = my_malloc(12); 136 my_free(p); 137 return p; // expected-warning{{Use of memory after it is freed}} 138 } 139 140 // This case is (possibly) ok, be conservative 141 int * af5() { 142 int *p = my_malloc(12); 143 my_hold(p); 144 return p; // no-warning 145 } 146 147 148 149 // This case tests that storing malloc'ed memory to a static variable which is 150 // then returned is not leaked. In the absence of known contracts for functions 151 // or inter-procedural analysis, this is a conservative answer. 152 int *f3() { 153 static int *p = 0; 154 p = malloc(12); 155 return p; // no-warning 156 } 157 158 // This case tests that storing malloc'ed memory to a static global variable 159 // which is then returned is not leaked. In the absence of known contracts for 160 // functions or inter-procedural analysis, this is a conservative answer. 161 static int *p_f4 = 0; 162 int *f4() { 163 p_f4 = malloc(12); 164 return p_f4; // no-warning 165 } 166 167 int *f5() { 168 int *q = malloc(12); 169 q = realloc(q, 20); 170 return q; // no-warning 171 } 172 173 void f6() { 174 int *p = malloc(12); 175 if (!p) 176 return; // no-warning 177 else 178 free(p); 179 } 180 181 void f6_realloc() { 182 int *p = malloc(12); 183 if (!p) 184 return; // no-warning 185 else 186 realloc(p,0); 187 } 188 189 190 char *doit2(); 191 void pr6069() { 192 char *buf = doit2(); 193 free(buf); 194 } 195 196 void pr6293() { 197 free(0); 198 } 199 200 void f7() { 201 char *x = (char*) malloc(4); 202 free(x); 203 x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} 204 } 205 206 void f7_realloc() { 207 char *x = (char*) malloc(4); 208 realloc(x,0); 209 x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} 210 } 211 212 void PR6123() { 213 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 214 } 215 216 void PR7217() { 217 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 218 buf[1] = 'c'; // not crash 219 } 220 221 void mallocCastToVoid() { 222 void *p = malloc(2); 223 const void *cp = p; // not crash 224 free(p); 225 } 226 227 void mallocCastToFP() { 228 void *p = malloc(2); 229 void (*fp)() = p; // not crash 230 free(p); 231 } 232 233 // This tests that malloc() buffers are undefined by default 234 char mallocGarbage () { 235 char *buf = malloc(2); 236 char result = buf[1]; // expected-warning{{undefined}} 237 free(buf); 238 return result; 239 } 240 241 // This tests that calloc() buffers need to be freed 242 void callocNoFree () { 243 char *buf = calloc(2,2); 244 return; // expected-warning{{never released}} 245 } 246 247 // These test that calloc() buffers are zeroed by default 248 char callocZeroesGood () { 249 char *buf = calloc(2,2); 250 char result = buf[3]; // no-warning 251 if (buf[1] == 0) { 252 free(buf); 253 } 254 return result; // no-warning 255 } 256 257 char callocZeroesBad () { 258 char *buf = calloc(2,2); 259 char result = buf[3]; // no-warning 260 if (buf[1] != 0) { 261 free(buf); // expected-warning{{never executed}} 262 } 263 return result; // expected-warning{{never released}} 264 } 265 266 void testMultipleFreeAnnotations() { 267 int *p = malloc(12); 268 int *q = malloc(12); 269 my_freeBoth(p, q); 270 } 271 272