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