1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify %s
2
3typedef __typeof(sizeof(int)) size_t;
4void *malloc(size_t);
5void free(void *);
6void *realloc(void *ptr, size_t size);
7void *calloc(size_t nmemb, size_t size);
8char *strdup(const char *s);
9
10void checkThatMallocCheckerIsRunning() {
11  malloc(4);
12} // expected-warning{{leak}}
13
14// Test for radar://11110132.
15struct Foo {
16    mutable void* m_data;
17    Foo(void* data) : m_data(data) {}
18};
19Foo aFunction() {
20    return malloc(10);
21}
22
23// Assume that functions which take a function pointer can free memory even if
24// they are defined in system headers and take the const pointer to the
25// allocated memory. (radar://11160612)
26// Test default parameter.
27int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = free);
28void r11160612_3() {
29  char *x = (char*)malloc(12);
30  const_ptr_and_callback_def_param(0, x, 12);
31}
32
33int const_ptr_and_callback_def_param_null(int, const char*, int n, void(*)(void*) = 0);
34void r11160612_no_callback() {
35  char *x = (char*)malloc(12);
36  const_ptr_and_callback_def_param_null(0, x, 12);
37} // expected-warning{{leak}}
38
39// Test member function pointer.
40struct CanFreeMemory {
41  static void myFree(void*);
42};
43//This is handled because we look at the type of the parameter(not argument).
44void r11160612_3(CanFreeMemory* p) {
45  char *x = (char*)malloc(12);
46  const_ptr_and_callback_def_param(0, x, 12, p->myFree);
47}
48
49
50namespace PR13751 {
51  class OwningVector {
52    void **storage;
53    size_t length;
54  public:
55    OwningVector();
56    ~OwningVector();
57    void push_back(void *Item) {
58      storage[length++] = Item;
59    }
60  };
61
62  void testDestructors() {
63    OwningVector v;
64    v.push_back(malloc(4));
65    // no leak warning; freed in destructor
66  }
67}
68
69struct X { void *a; };
70
71struct X get() {
72  struct X result;
73  result.a = malloc(4);
74  return result; // no-warning
75}
76
77// Ensure that regions accessible through a LazyCompoundVal trigger region escape.
78// Malloc checker used to report leaks for the following two test cases.
79struct Property {
80  char* getterName;
81  Property(char* n)
82  : getterName(n) {}
83
84};
85void append(Property x);
86
87void appendWrapper(char *getterName) {
88  append(Property(getterName));
89}
90void foo(const char* name) {
91  char* getterName = strdup(name);
92  appendWrapper(getterName); // no-warning
93}
94
95struct NestedProperty {
96  Property prop;
97  NestedProperty(Property p)
98  : prop(p) {}
99};
100void appendNested(NestedProperty x);
101
102void appendWrapperNested(char *getterName) {
103  appendNested(NestedProperty(Property(getterName)));
104}
105void fooNested(const char* name) {
106  char* getterName = strdup(name);
107  appendWrapperNested(getterName); // no-warning
108}