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