Home | History | Annotate | Download | only in Analysis
      1 // 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 
      6 typedef __typeof__(sizeof(int)) size_t;
      7 void *malloc(size_t);
      8 void *realloc(void *ptr, size_t size);
      9 void *calloc(size_t nmemb, size_t size);
     10 char *strdup(const char *s);
     11 void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
     12 
     13 void free(void *);
     14 void __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
     21 void 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 
     26 void 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 
     32 void 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 
     37 void 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 
     42 void 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 
     47 void 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 
     52 void 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 
     57 void 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 void testAlloca() {
     63   int *p = (int *)__builtin_alloca(sizeof(int));
     64   delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
     65 }
     66 
     67 //--------------- test new family
     68 void testNew1() {
     69   int *p = new int;
     70   free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
     71 }
     72 
     73 void testNew2() {
     74   int *p = (int *)operator new(0);
     75   free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
     76 }
     77 
     78 void testNew3() {
     79   int *p = new int[1];
     80   free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
     81 }
     82 
     83 void testNew4() {
     84   int *p = new int;
     85   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
     86 }
     87 
     88 void testNew5() {
     89   int *p = (int *)operator new(0);
     90   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
     91 }
     92 
     93 void testNew6() {
     94   int *p = new int[1];
     95   realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
     96 }
     97 
     98 int *allocInt() {
     99   return new int;
    100 }
    101 void testNew7() {
    102   int *p = allocInt();
    103   delete[] p; // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'delete[]'}}
    104 }
    105 
    106 void testNew8() {
    107   int *p = (int *)operator new(0);
    108   delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
    109 }
    110 
    111 int *allocIntArray(unsigned c) {
    112   return new int[c];
    113 }
    114 
    115 void testNew9() {
    116   int *p = allocIntArray(1);
    117   delete p; // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
    118 }
    119 
    120 void testNew10() {
    121   int *p = (int *)operator new[](0);
    122   delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
    123 }
    124 
    125 void testNew11(NSUInteger dataLength) {
    126   int *p = new int;
    127   NSData *d = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{+dataWithBytesNoCopy:length:freeWhenDone: cannot take ownership of memory allocated by 'new'}}
    128 }
    129 
    130 //-------------------------------------------------------
    131 // Check for intersection with unix.Malloc bounded with 
    132 // unix.MismatchedDeallocator
    133 //-------------------------------------------------------
    134 
    135 // new/delete oparators are subjects of cplusplus.NewDelete.
    136 void testNewDeleteNoWarn() {
    137   int i;
    138   delete &i; // no-warning
    139 
    140   int *p1 = new int;
    141   delete ++p1; // no-warning
    142 
    143   int *p2 = new int;
    144   delete p2;
    145   delete p2; // no-warning
    146 
    147   int *p3 = new int; // no-warning
    148 }
    149 
    150 void testDeleteOpAfterFree() {
    151   int *p = (int *)malloc(sizeof(int));
    152   free(p);
    153   operator delete(p); // no-warning
    154 }
    155 
    156 void testDeleteAfterFree() {
    157   int *p = (int *)malloc(sizeof(int));
    158   free(p);
    159   delete p; // no-warning
    160 }
    161 
    162 void testStandardPlacementNewAfterFree() {
    163   int *p = (int *)malloc(sizeof(int));
    164   free(p);
    165   p = new(p) int; // no-warning
    166 }
    167 
    168 //---------------------------------------------------------------
    169 // Check for intersection with cplusplus.NewDelete bounded with 
    170 // unix.MismatchedDeallocator
    171 //---------------------------------------------------------------
    172 
    173 // malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
    174 void testMallocFreeNoWarn() {
    175   int i;
    176   free(&i); // no-warning
    177 
    178   int *p1 = (int *)malloc(sizeof(int));
    179   free(++p1); // no-warning
    180 
    181   int *p2 = (int *)malloc(sizeof(int));
    182   free(p2);
    183   free(p2); // no-warning
    184 
    185   int *p3 = (int *)malloc(sizeof(int)); // no-warning
    186 }
    187 
    188 void testFreeAfterDelete() {
    189   int *p = new int;  
    190   delete p;
    191   free(p); // no-warning
    192 }
    193 
    194 void testStandardPlacementNewAfterDelete() {
    195   int *p = new int;  
    196   delete p;
    197   p = new(p) int; // no-warning
    198 }
    199 
    200 
    201 // Smart pointer example
    202 template <typename T>
    203 struct SimpleSmartPointer {
    204   T *ptr;
    205 
    206   explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
    207   ~SimpleSmartPointer() {
    208     delete ptr;
    209     // expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
    210     // expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
    211   }
    212 };
    213 
    214 void testSimpleSmartPointerArrayNew() {
    215   {
    216     SimpleSmartPointer<int> a(new int);
    217   } // no-warning
    218 
    219   {
    220     SimpleSmartPointer<int> a(new int[4]);
    221   }
    222 }
    223 
    224 void testSimpleSmartPointerMalloc() {
    225   {
    226     SimpleSmartPointer<int> a(new int);
    227   } // no-warning
    228 
    229   {
    230     SimpleSmartPointer<int> a((int *)malloc(4));
    231   }
    232 }
    233