malloc.cpp revision 658a28479dd775f6ff2c07fa5699a7ea01e04127
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*) = 0);
28void r11160612_3() {
29  char *x = (char*)malloc(12);
30  const_ptr_and_callback_def_param(0, x, 12);
31}
32
33// Test member function pointer.
34struct CanFreeMemory {
35  static void myFree(void*);
36};
37//This is handled because we look at the type of the parameter(not argument).
38void r11160612_3(CanFreeMemory* p) {
39  char *x = (char*)malloc(12);
40  const_ptr_and_callback_def_param(0, x, 12, p->myFree);
41}
42
43
44namespace PR13751 {
45  class OwningVector {
46    void **storage;
47    size_t length;
48  public:
49    OwningVector();
50    ~OwningVector();
51    void push_back(void *Item) {
52      storage[length++] = Item;
53    }
54  };
55
56  void testDestructors() {
57    OwningVector v;
58    v.push_back(malloc(4));
59    // no leak warning; freed in destructor
60  }
61}
62
63struct X { void *a; };
64
65struct X get() {
66  struct X result;
67  result.a = malloc(4);
68  return result; // no-warning
69}
70
71// Ensure that regions accessible through a LazyCompoundVal trigger region escape.
72// Malloc checker used to report leaks for the following two test cases.
73struct Property {
74  char* getterName;
75  Property(char* n)
76  : getterName(n) {}
77
78};
79void append(Property x);
80
81void appendWrapper(char *getterName) {
82  append(Property(getterName));
83}
84void foo(const char* name) {
85  char* getterName = strdup(name);
86  appendWrapper(getterName); // no-warning
87}
88
89struct NestedProperty {
90  Property prop;
91  NestedProperty(Property p)
92  : prop(p) {}
93};
94void appendNested(NestedProperty x);
95
96void appendWrapperNested(char *getterName) {
97  appendNested(NestedProperty(Property(getterName)));
98}
99void fooNested(const char* name) {
100  char* getterName = strdup(name);
101  appendWrapperNested(getterName); // no-warning
102}