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