1 // RUN: rm -f %t 2 // RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,unix.Malloc -analyzer-output=plist -verify -o %t -analyzer-config eagerly-assume=false %s 3 // RUN: tail -n +11 %t | %normalize_plist | diff -ub %S/Inputs/expected-plists/malloc-plist.c.plist - 4 5 typedef __typeof(sizeof(int)) size_t; 6 void *malloc(size_t); 7 void free(void *); 8 void *realloc(void *ptr, size_t size); 9 diagnosticTest(int in)10void diagnosticTest(int in) { 11 if (in > 5) { 12 int *p = malloc(12); 13 *p = 0; 14 (*p)++; 15 } 16 in++; // expected-warning {{leak}} 17 } 18 myArrayAllocation()19void myArrayAllocation() { 20 int **A; 21 A = malloc(2*sizeof(int*)); 22 A[0] = 0; 23 }//expected-warning{{Potential leak}} 24 reallocDiagnostics()25void reallocDiagnostics() { 26 char * buf = malloc(100); 27 char * tmp; 28 tmp = (char*)realloc(buf, 0x1000000); 29 if (!tmp) { 30 return;// expected-warning {{leak}} 31 } 32 buf = tmp; 33 free(buf); 34 } 35 wrapper()36void *wrapper() { 37 void *x = malloc(100); 38 // This is intentionally done to test diagnostic emission. 39 if (x) 40 return x; 41 return 0; 42 } 43 test_wrapper()44void test_wrapper() { 45 void *buf = wrapper(); 46 (void) buf; 47 }//expected-warning{{Potential leak}} 48 49 // Test what happens when the same call frees and allocated memory. 50 // Also tests the stack hint for parameters, when they are passed directly or via pointer. my_free(void * x)51void my_free(void *x) { 52 free(x); 53 } my_malloc_and_free(void ** x)54void my_malloc_and_free(void **x) { 55 *x = malloc(100); 56 if (*x) 57 my_free(*x); 58 return; 59 } test_double_action_call()60void *test_double_action_call() { 61 void *buf; 62 my_malloc_and_free(&buf); 63 return buf; //expected-warning{{Use of memory after it is freed}} 64 } 65 66 // Test stack hint for 'reallocation failed'. my_realloc(char * buf)67char *my_realloc(char *buf) { 68 char *tmp; 69 tmp = (char*)realloc(buf, 0x1000000); 70 if (!tmp) { 71 return tmp; 72 } 73 return tmp; 74 } reallocIntra()75void reallocIntra() { 76 char *buf = (char *)malloc(100); 77 buf = my_realloc(buf); 78 free(buf);//expected-warning{{Potential leak}} 79 } 80 81 // Test stack hint when returning a result. malloc_wrapper_ret()82static char *malloc_wrapper_ret() { 83 return (char*)malloc(12); 84 } use_ret()85void use_ret() { 86 char *v; 87 v = malloc_wrapper_ret(); 88 }//expected-warning{{Potential leak}} 89 90 // Passing a block as a parameter to an inlined call for which we generate 91 // a stack hint message caused crashes. 92 // rdar://problem/21291971 93 void myfree_takingblock(void (^ignored)(void), int *p) { 94 free(p); 95 } 96 call_myfree_takingblock()97void call_myfree_takingblock() { 98 void (^some_block)(void) = ^void(void) { }; 99 100 int *p = malloc(sizeof(int)); 101 myfree_takingblock(some_block, p); 102 *p = 3;//expected-warning{{Use of memory after it is freed}} 103 } 104 105 // Test that we refer to the last symbol used in the leak diagnostic. LeakedSymbol(int in)106void LeakedSymbol(int in) { 107 int *m = 0; 108 int *p; 109 p = (int*)malloc(12); 110 *p = 0; 111 (*p)++; 112 m = p; 113 p = 0; 114 (*m)++; 115 in++;//expected-warning{{Potential leak}} 116 } 117 118 // Tests that exercise running remove dead bindings at Call exit. function_with_leak1()119static void function_with_leak1() { 120 char *x = (char*)malloc(12); 121 } //expected-warning{{Potential leak}} use_function_with_leak1()122void use_function_with_leak1() { 123 function_with_leak1(); 124 int y = 0; 125 } 126 function_with_leak2()127static void function_with_leak2() { 128 char *x = (char*)malloc(12); 129 int m = 0; //expected-warning{{Potential leak}} 130 } use_function_with_leak2()131void use_function_with_leak2() { 132 function_with_leak2(); 133 } 134 function_with_leak3(int y)135static void function_with_leak3(int y) { 136 char *x = (char*)malloc(12); 137 if (y) 138 y++; 139 }//expected-warning{{Potential leak}} use_function_with_leak3(int y)140void use_function_with_leak3(int y) { 141 function_with_leak3(y); 142 } 143 function_with_leak4(int y)144static void function_with_leak4(int y) { 145 char *x = (char*)malloc(12); 146 if (y) 147 y++; 148 else 149 y--;//expected-warning{{Potential leak}} 150 } use_function_with_leak4(int y)151void use_function_with_leak4(int y) { 152 function_with_leak4(y); 153 } 154 anotherFunction5()155int anotherFunction5() { 156 return 5; 157 } function_with_leak5()158static int function_with_leak5() { 159 char *x = (char*)malloc(12); 160 return anotherFunction5();//expected-warning{{Potential leak}} 161 } use_function_with_leak5()162void use_function_with_leak5() { 163 function_with_leak5(); 164 } 165 anotherFunction6(int m)166void anotherFunction6(int m) { 167 m++; 168 } function_with_leak6()169static void function_with_leak6() { 170 char *x = (char*)malloc(12); 171 anotherFunction6(3);//expected-warning{{Potential leak}} 172 } use_function_with_leak6()173void use_function_with_leak6() { 174 function_with_leak6(); 175 } 176 empty_function()177static void empty_function(){ 178 } use_empty_function()179void use_empty_function() { 180 empty_function(); 181 } function_with_leak7()182static char *function_with_leak7() { 183 return (char*)malloc(12); 184 } use_function_with_leak7()185void use_function_with_leak7() { 186 function_with_leak7(); 187 }//expected-warning{{Potential memory leak}} 188 189 // Test that we do not print the name of a variable not visible from where 190 // the issue is reported. my_malloc()191int *my_malloc() { 192 int *p = malloc(12); 193 return p; 194 } testOnlyRefferToVisibleVariables()195void testOnlyRefferToVisibleVariables() { 196 my_malloc(); 197 } // expected-warning{{Potential memory leak}} 198 199 struct PointerWrapper{ 200 int*p; 201 }; my_malloc_into_struct()202int *my_malloc_into_struct() { 203 struct PointerWrapper w; 204 w.p = malloc(12); 205 return w.p; 206 } testMyMalloc()207void testMyMalloc() { 208 my_malloc_into_struct(); 209 } // expected-warning{{Potential memory leak}} 210