1c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s 2a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 31b22cec353bc6112653d50b060a1d78d70c51527Chandler Carruth#include "Inputs/system-header-simulator.h" 4a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 5a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksvoid *malloc(size_t); 6a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksvoid *valloc(size_t); 7a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksvoid free(void *); 8a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksvoid *realloc(void *ptr, size_t size); 9a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksvoid *reallocf(void *ptr, size_t size); 10a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksvoid *calloc(size_t nmemb, size_t size); 11c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 12c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rosevoid exit(int) __attribute__ ((__noreturn__)); 13c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rosevoid *memcpy(void * restrict s1, const void * restrict s2, size_t n); 14c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rosesize_t strlen(const char *); 15a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 16a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksstatic void my_malloc1(void **d, size_t size) { 17a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks *d = malloc(size); 18a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks} 19a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 20a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksstatic void *my_malloc2(int elevel, size_t size) { 21a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks void *data; 22a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks data = malloc(size); 23a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks if (data == 0) 24a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks exit(0); 25a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks return data; 26a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks} 27a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 28a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksstatic void my_free1(void *p) { 29a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks free(p); 30a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks} 31a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 32a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksstatic void test1() { 33a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks void *data = 0; 3463bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose my_malloc1(&data, 4); 3568eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks} // expected-warning {{Potential leak of memory pointed to by 'data'}} 36a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 37362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaksstatic void test11() { 38362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks void *data = 0; 39362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks my_malloc1(&data, 4); 40362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks my_free1(data); 41362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks} 42362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks 437752d292c97fd4b78a954c9a027b2a862be50f8bAnna Zaksstatic void testUniqueingByallocationSiteInTopLevelFunction() { 447752d292c97fd4b78a954c9a027b2a862be50f8bAnna Zaks void *data = my_malloc2(1, 4); 457752d292c97fd4b78a954c9a027b2a862be50f8bAnna Zaks data = 0; 4668eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks int x = 5;// expected-warning {{Potential leak of memory pointed to by 'data'}} 4763bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose data = my_malloc2(1, 4); 4868eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks} // expected-warning {{Potential leak of memory pointed to by 'data'}} 49a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 50a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksstatic void test3() { 51a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks void *data = my_malloc2(1, 4); 52a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks free(data); 53a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks data = my_malloc2(1, 4); 54a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks free(data); 55a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks} 56a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 57a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaksint test4() { 58a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks int *data = (int*)my_malloc2(1, 4); 59a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks my_free1(data); 60a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks data = (int *)my_malloc2(1, 4); 61a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks my_free1(data); 62a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks return *data; // expected-warning {{Use of memory after it is freed}} 63a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks} 64a19581ae489335abf5cf96b253b31ecefe96b8e4Anna Zaks 65362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaksvoid test6() { 66362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks int *data = (int *)my_malloc2(1, 4); 67362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks my_free1((int*)data); 68362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks my_free1((int*)data); // expected-warning{{Use of memory after it is freed}} 69362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks} 70362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks 71362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks// TODO: We should warn here. 72362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaksvoid test5() { 73362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks int *data; 74362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks my_free1((int*)data); 75362054766d3dacb8a87c0ee3f503d096709adf08Anna Zaks} 76e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks 77ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaksstatic char *reshape(char *in) { 78ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks return 0; 79ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks} 80ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 81ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaksvoid testThatRemoveDeadBindingsRunBeforeEachCall() { 82ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks char *v = malloc(12); 83ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks v = reshape(v); 8468eb4c25e961d18f82b47a0a385f90d7af09bcc3Anna Zaks v = reshape(v);// expected-warning {{Potential leak of memory pointed to by 'v'}} 85ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks} 86ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 87e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks// Test that we keep processing after 'return;' 88e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaksvoid fooWithEmptyReturn(int x) { 89e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks if (x) 90e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks return; 91e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks x++; 92e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks return; 93e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks} 94e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks 95e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaksint uafAndCallsFooWithEmptyReturn() { 96e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks int *x = (int*)malloc(12); 97e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks free(x); 98e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks fooWithEmptyReturn(12); 99e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks return *x; // expected-warning {{Use of memory after it is freed}} 100e55b03a6e44b99c1cd77b8ea5e4d836c28948904Anna Zaks} 101c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 102c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 103c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose// If we inline any of the malloc-family functions, the checker shouldn't also 104c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose// try to do additional modeling. <rdar://problem/12317671> 105c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rosechar *strndup(const char *str, size_t n) { 106c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose if (!str) 107c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose return 0; 108c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 109c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose // DO NOT FIX. This is to test that we are actually using the inlined 110c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose // behavior! 111c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose if (n < 5) 112c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose return 0; 113c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 114c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose size_t length = strlen(str); 115c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose if (length < n) 116c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose n = length; 117c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 118c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose char *result = malloc(n + 1); 119c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose memcpy(result, str, n); 120c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose result[n] = '\0'; 121c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose return result; 122c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose} 123c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose 124c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rosevoid useStrndup(size_t n) { 12563bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose if (n == 0) { 126c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose (void)strndup(0, 20); // no-warning 12763bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose return; 12863bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose } else if (n < 5) { 129c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose (void)strndup("hi there", n); // no-warning 13063bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose return; 13163bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose } else { 13263bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose (void)strndup("hi there", n); 13363bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose return; // expected-warning{{leak}} 13463bc186d6ac0b44ba4ec6fccb5f471b05c79b666Jordan Rose } 135c20c7275c351f362b42915901d308ac66b8b71d1Jordan Rose} 136