1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify %s
2 
3 typedef __typeof(sizeof(int)) size_t;
4 void *malloc(size_t);
5 void free(void *);
6 void *realloc(void *ptr, size_t size);
7 void *calloc(size_t nmemb, size_t size);
8 char *strdup(const char *s);
9 
checkThatMallocCheckerIsRunning()10 void checkThatMallocCheckerIsRunning() {
11   malloc(4);
12 } // expected-warning{{leak}}
13 
14 // Test for radar://11110132.
15 struct Foo {
16     mutable void* m_data;
FooFoo17     Foo(void* data) : m_data(data) {}
18 };
aFunction()19 Foo 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.
27 int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = free);
r11160612_3()28 void r11160612_3() {
29   char *x = (char*)malloc(12);
30   const_ptr_and_callback_def_param(0, x, 12);
31 }
32 
33 int const_ptr_and_callback_def_param_null(int, const char*, int n, void(*)(void*) = 0);
r11160612_no_callback()34 void 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.
40 struct CanFreeMemory {
41   static void myFree(void*);
42 };
43 //This is handled because we look at the type of the parameter(not argument).
r11160612_3(CanFreeMemory * p)44 void 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 
50 namespace PR13751 {
51   class OwningVector {
52     void **storage;
53     size_t length;
54   public:
55     OwningVector();
56     ~OwningVector();
push_back(void * Item)57     void push_back(void *Item) {
58       storage[length++] = Item;
59     }
60   };
61 
testDestructors()62   void testDestructors() {
63     OwningVector v;
64     v.push_back(malloc(4));
65     // no leak warning; freed in destructor
66   }
67 }
68 
69 struct X { void *a; };
70 
get()71 struct 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.
79 struct Property {
80   char* getterName;
PropertyProperty81   Property(char* n)
82   : getterName(n) {}
83 
84 };
85 void append(Property x);
86 
appendWrapper(char * getterName)87 void appendWrapper(char *getterName) {
88   append(Property(getterName));
89 }
foo(const char * name)90 void foo(const char* name) {
91   char* getterName = strdup(name);
92   appendWrapper(getterName); // no-warning
93 }
94 
95 struct NestedProperty {
96   Property prop;
NestedPropertyNestedProperty97   NestedProperty(Property p)
98   : prop(p) {}
99 };
100 void appendNested(NestedProperty x);
101 
appendWrapperNested(char * getterName)102 void appendWrapperNested(char *getterName) {
103   appendNested(NestedProperty(Property(getterName)));
104 }
fooNested(const char * name)105 void fooNested(const char* name) {
106   char* getterName = strdup(name);
107   appendWrapperNested(getterName); // no-warning
108 }