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