malloc.c revision c8bb3befcad8cd8fc9556bc265289b07dc3c94c8
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,experimental.unix.Malloc -analyzer-store=region -verify %s 2#include "system-header-simulator.h" 3 4typedef __typeof(sizeof(int)) size_t; 5void *malloc(size_t); 6void free(void *); 7void *realloc(void *ptr, size_t size); 8void *calloc(size_t nmemb, size_t size); 9 10void myfoo(int *p); 11void myfooint(int p); 12 13void f1() { 14 int *p = malloc(12); 15 return; // expected-warning{{Allocated memory never released. Potential memory leak.}} 16} 17 18void f2() { 19 int *p = malloc(12); 20 free(p); 21 free(p); // expected-warning{{Try to free a memory block that has been released}} 22} 23 24void f2_realloc_0() { 25 int *p = malloc(12); 26 realloc(p,0); 27 realloc(p,0); // expected-warning{{Try to free a memory block that has been released}} 28} 29 30void f2_realloc_1() { 31 int *p = malloc(12); 32 int *q = realloc(p,0); // no-warning 33} 34 35void reallocNotNullPtr(unsigned sizeIn) { 36 unsigned size = 12; 37 char *p = (char*)malloc(size); 38 if (p) { 39 char *q = (char*)realloc(p, sizeIn); 40 char x = *q; // expected-warning {{Allocated memory never released.}} 41 } 42} 43 44int *realloctest1() { 45 int *q = malloc(12); 46 q = realloc(q, 20); 47 return q; // no warning - returning the allocated value 48} 49 50// p should be freed if realloc fails. 51void reallocFails() { 52 char *p = malloc(12); 53 char *r = realloc(p, 12+1); 54 if (!r) { 55 free(p); 56 } else { 57 free(r); 58 } 59} 60 61// This case tests that storing malloc'ed memory to a static variable which is 62// then returned is not leaked. In the absence of known contracts for functions 63// or inter-procedural analysis, this is a conservative answer. 64int *f3() { 65 static int *p = 0; 66 p = malloc(12); 67 return p; // no-warning 68} 69 70// This case tests that storing malloc'ed memory to a static global variable 71// which is then returned is not leaked. In the absence of known contracts for 72// functions or inter-procedural analysis, this is a conservative answer. 73static int *p_f4 = 0; 74int *f4() { 75 p_f4 = malloc(12); 76 return p_f4; // no-warning 77} 78 79int *f5() { 80 int *q = malloc(12); 81 q = realloc(q, 20); 82 return q; // no-warning 83} 84 85void f6() { 86 int *p = malloc(12); 87 if (!p) 88 return; // no-warning 89 else 90 free(p); 91} 92 93void f6_realloc() { 94 int *p = malloc(12); 95 if (!p) 96 return; // no-warning 97 else 98 realloc(p,0); 99} 100 101 102char *doit2(); 103void pr6069() { 104 char *buf = doit2(); 105 free(buf); 106} 107 108void pr6293() { 109 free(0); 110} 111 112void f7() { 113 char *x = (char*) malloc(4); 114 free(x); 115 x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}} 116} 117 118void f7_realloc() { 119 char *x = (char*) malloc(4); 120 realloc(x,0); 121 x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}} 122} 123 124void PR6123() { 125 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 126} 127 128void PR7217() { 129 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 130 buf[1] = 'c'; // not crash 131} 132 133void mallocCastToVoid() { 134 void *p = malloc(2); 135 const void *cp = p; // not crash 136 free(p); 137} 138 139void mallocCastToFP() { 140 void *p = malloc(2); 141 void (*fp)() = p; // not crash 142 free(p); 143} 144 145// This tests that malloc() buffers are undefined by default 146char mallocGarbage () { 147 char *buf = malloc(2); 148 char result = buf[1]; // expected-warning{{undefined}} 149 free(buf); 150 return result; 151} 152 153// This tests that calloc() buffers need to be freed 154void callocNoFree () { 155 char *buf = calloc(2,2); 156 return; // expected-warning{{never released}} 157} 158 159// These test that calloc() buffers are zeroed by default 160char callocZeroesGood () { 161 char *buf = calloc(2,2); 162 char result = buf[3]; // no-warning 163 if (buf[1] == 0) { 164 free(buf); 165 } 166 return result; // no-warning 167} 168 169char callocZeroesBad () { 170 char *buf = calloc(2,2); 171 char result = buf[3]; // no-warning 172 if (buf[1] != 0) { 173 free(buf); // expected-warning{{never executed}} 174 } 175 return result; // expected-warning{{never released}} 176} 177 178void nullFree() { 179 int *p = 0; 180 free(p); // no warning - a nop 181} 182 183void paramFree(int *p) { 184 myfoo(p); 185 free(p); // no warning 186 myfoo(p); // TODO: This should be a warning. 187} 188 189int* mallocEscapeRet() { 190 int *p = malloc(12); 191 return p; // no warning 192} 193 194void mallocEscapeFoo() { 195 int *p = malloc(12); 196 myfoo(p); 197 return; // no warning 198} 199 200void mallocEscapeFree() { 201 int *p = malloc(12); 202 myfoo(p); 203 free(p); 204} 205 206void mallocEscapeFreeFree() { 207 int *p = malloc(12); 208 myfoo(p); 209 free(p); 210 free(p); // expected-warning{{Try to free a memory block that has been released}} 211} 212 213void mallocEscapeFreeUse() { 214 int *p = malloc(12); 215 myfoo(p); 216 free(p); 217 myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 218} 219 220int *myalloc(); 221void myalloc2(int **p); 222 223void mallocEscapeFreeCustomAlloc() { 224 int *p = malloc(12); 225 myfoo(p); 226 free(p); 227 p = myalloc(); 228 free(p); // no warning 229} 230 231void mallocEscapeFreeCustomAlloc2() { 232 int *p = malloc(12); 233 myfoo(p); 234 free(p); 235 myalloc2(&p); 236 free(p); // no warning 237} 238 239void mallocBindFreeUse() { 240 int *x = malloc(12); 241 int *y = x; 242 free(y); 243 myfoo(x); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 244} 245 246void mallocEscapeMalloc() { 247 int *p = malloc(12); 248 myfoo(p); 249 p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}} 250} 251 252void mallocMalloc() { 253 int *p = malloc(12); 254 p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}} 255} 256 257void mallocFreeMalloc() { 258 int *p = malloc(12); 259 free(p); 260 p = malloc(12); 261 free(p); 262} 263 264void mallocFreeUse_params() { 265 int *p = malloc(12); 266 free(p); 267 myfoo(p); //expected-warning{{Use of dynamically allocated memory after it is freed}} 268} 269 270void mallocFreeUse_params2() { 271 int *p = malloc(12); 272 free(p); 273 myfooint(*p); //expected-warning{{Use of dynamically allocated memory after it is freed}} 274} 275 276void mallocFailedOrNot() { 277 int *p = malloc(12); 278 if (!p) 279 free(p); 280 else 281 free(p); 282} 283 284struct StructWithInt { 285 int g; 286}; 287 288int *mallocReturnFreed() { 289 int *p = malloc(12); 290 free(p); 291 return p; // expected-warning {{Use of dynamically allocated}} 292} 293 294int useAfterFreeStruct() { 295 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 296 px->g = 5; 297 free(px); 298 return px->g; // expected-warning {{Use of dynamically allocated}} 299} 300 301void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p); 302 303void mallocEscapeFooNonSymbolArg() { 304 struct StructWithInt *p = malloc(sizeof(struct StructWithInt)); 305 nonSymbolAsFirstArg(&p->g, p); 306 return; // no warning 307} 308 309void mallocFailedOrNotLeak() { 310 int *p = malloc(12); 311 if (p == 0) 312 return; // no warning 313 else 314 return; // expected-warning {{Allocated memory never released. Potential memory leak.}} 315} 316 317int *Gl; 318struct GlStTy { 319 int *x; 320}; 321 322struct GlStTy GlS = {0}; 323 324void GlobalFree() { 325 free(Gl); 326} 327 328void GlobalMalloc() { 329 Gl = malloc(12); 330} 331 332void GlobalStructMalloc() { 333 int *a = malloc(12); 334 GlS.x = a; 335} 336 337void GlobalStructMallocFree() { 338 int *a = malloc(12); 339 GlS.x = a; 340 free(GlS.x); 341} 342 343// Region escape testing. 344 345unsigned takePtrToPtr(int **p); 346void PassTheAddrOfAllocatedData(int f) { 347 int *p = malloc(12); 348 // We don't know what happens after the call. Should stop tracking here. 349 if (takePtrToPtr(&p)) 350 f++; 351 free(p); // no warning 352} 353 354struct X { 355 int *p; 356}; 357unsigned takePtrToStruct(struct X *s); 358int ** foo2(int *g, int f) { 359 int *p = malloc(12); 360 struct X *px= malloc(sizeof(struct X)); 361 px->p = p; 362 // We don't know what happens after this call. Should not track px nor p. 363 if (takePtrToStruct(px)) 364 f++; 365 free(p); 366 return 0; 367} 368 369struct X* RegInvalidationDetect1(struct X *s2) { 370 struct X *px= malloc(sizeof(struct X)); 371 px->p = 0; 372 px = s2; 373 return px; // expected-warning {{Allocated memory never released. Potential memory leak.}} 374} 375 376struct X* RegInvalidationGiveUp1() { 377 int *p = malloc(12); 378 struct X *px= malloc(sizeof(struct X)); 379 px->p = p; 380 return px; 381} 382 383int **RegInvalidationDetect2(int **pp) { 384 int *p = malloc(12); 385 pp = &p; 386 pp++; 387 return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}} 388} 389 390extern void exit(int) __attribute__ ((__noreturn__)); 391void mallocExit(int *g) { 392 struct xx *p = malloc(12); 393 if (g != 0) 394 exit(1); 395 free(p); 396 return; 397} 398 399extern void __assert_fail (__const char *__assertion, __const char *__file, 400 unsigned int __line, __const char *__function) 401 __attribute__ ((__noreturn__)); 402#define assert(expr) \ 403 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 404void mallocAssert(int *g) { 405 struct xx *p = malloc(12); 406 407 assert(g != 0); 408 free(p); 409 return; 410} 411 412void doNotInvalidateWhenPassedToSystemCalls(char *s) { 413 char *p = malloc(12); 414 strlen(p); 415 strcpy(p, s); // expected-warning {{leak}} 416} 417 418// Below are the known false positives. 419 420// TODO: There should be no warning here. This one might be difficult to get rid of. 421void dependsOnValueOfPtr(int *g, unsigned f) { 422 int *p; 423 424 if (f) { 425 p = g; 426 } else { 427 p = malloc(12); 428 } 429 430 if (p != g) 431 free(p); 432 else 433 return; // expected-warning{{Allocated memory never released. Potential memory leak}} 434 return; 435} 436 437// TODO: Should this be a warning? 438// Here we are returning a pointer one past the allocated value. An idiom which 439// can be used for implementing special malloc. The correct uses of this might 440// be rare enough so that we could keep this as a warning. 441static void *specialMalloc(int n){ 442 int *p; 443 p = malloc( n+8 ); 444 if( p ){ 445 p[0] = n; 446 p++; 447 } 448 return p;// expected-warning {{Allocated memory never released. Potential memory leak.}} 449} 450