xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/malloc.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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 }