1 // RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s 2 3 // XFAIL: cygwin,mingw32,win32 4 5 #include "Inputs/system-header-simulator.h" 6 7 typedef __typeof(sizeof(int)) size_t; 8 void *malloc(size_t); 9 void *valloc(size_t); 10 void free(void *); 11 void *realloc(void *ptr, size_t size); 12 void *reallocf(void *ptr, size_t size); 13 void *calloc(size_t nmemb, size_t size); 14 15 void exit(int) __attribute__ ((__noreturn__)); 16 void *memcpy(void * restrict s1, const void * restrict s2, size_t n); 17 size_t strlen(const char *); 18 19 static void my_malloc1(void **d, size_t size) { 20 *d = malloc(size); 21 } 22 23 static void *my_malloc2(int elevel, size_t size) { 24 void *data; 25 data = malloc(size); 26 if (data == 0) 27 exit(0); 28 return data; 29 } 30 31 static void my_free1(void *p) { 32 free(p); 33 } 34 35 static void test1() { 36 void *data = 0; 37 my_malloc1(&data, 4); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}} 38 } 39 40 static void test11() { 41 void *data = 0; 42 my_malloc1(&data, 4); 43 my_free1(data); 44 } 45 46 static void testUniqueingByallocationSiteInTopLevelFunction() { 47 void *data = my_malloc2(1, 4); 48 data = 0; 49 int x = 5;// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}} 50 data = my_malloc2(1, 4);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}} 51 } 52 53 static void test3() { 54 void *data = my_malloc2(1, 4); 55 free(data); 56 data = my_malloc2(1, 4); 57 free(data); 58 } 59 60 int test4() { 61 int *data = (int*)my_malloc2(1, 4); 62 my_free1(data); 63 data = (int *)my_malloc2(1, 4); 64 my_free1(data); 65 return *data; // expected-warning {{Use of memory after it is freed}} 66 } 67 68 void test6() { 69 int *data = (int *)my_malloc2(1, 4); 70 my_free1((int*)data); 71 my_free1((int*)data); // expected-warning{{Use of memory after it is freed}} 72 } 73 74 // TODO: We should warn here. 75 void test5() { 76 int *data; 77 my_free1((int*)data); 78 } 79 80 static char *reshape(char *in) { 81 return 0; 82 } 83 84 void testThatRemoveDeadBindingsRunBeforeEachCall() { 85 char *v = malloc(12); 86 v = reshape(v); 87 v = reshape(v);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'v'}} 88 } 89 90 // Test that we keep processing after 'return;' 91 void fooWithEmptyReturn(int x) { 92 if (x) 93 return; 94 x++; 95 return; 96 } 97 98 int uafAndCallsFooWithEmptyReturn() { 99 int *x = (int*)malloc(12); 100 free(x); 101 fooWithEmptyReturn(12); 102 return *x; // expected-warning {{Use of memory after it is freed}} 103 } 104 105 106 // If we inline any of the malloc-family functions, the checker shouldn't also 107 // try to do additional modeling. <rdar://problem/12317671> 108 char *strndup(const char *str, size_t n) { 109 if (!str) 110 return 0; 111 112 // DO NOT FIX. This is to test that we are actually using the inlined 113 // behavior! 114 if (n < 5) 115 return 0; 116 117 size_t length = strlen(str); 118 if (length < n) 119 n = length; 120 121 char *result = malloc(n + 1); 122 memcpy(result, str, n); 123 result[n] = '\0'; 124 return result; 125 } 126 127 void useStrndup(size_t n) { 128 if (n == 0) 129 (void)strndup(0, 20); // no-warning 130 else if (n < 5) 131 (void)strndup("hi there", n); // no-warning 132 else 133 (void)strndup("hi there", n); // expected-warning{{leak}} 134 } 135