xref: /llvm-project/clang/test/Analysis/malloc-static-storage.cpp (revision 840edd8ab2620a52e9acbef7de037c9f465dfce7)
1*840edd8aSBalazs Benics // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -verify %s
2*840edd8aSBalazs Benics 
3*840edd8aSBalazs Benics typedef __typeof(sizeof(int)) size_t;
4*840edd8aSBalazs Benics void* malloc(size_t size);
5*840edd8aSBalazs Benics void *calloc(size_t num, size_t size);
6*840edd8aSBalazs Benics void free(void * ptr);
7*840edd8aSBalazs Benics 
8*840edd8aSBalazs Benics void escape(void *);
9*840edd8aSBalazs Benics void next_statement();
10*840edd8aSBalazs Benics 
conditional_malloc(bool coin)11*840edd8aSBalazs Benics void conditional_malloc(bool coin) {
12*840edd8aSBalazs Benics   static int *p;
13*840edd8aSBalazs Benics 
14*840edd8aSBalazs Benics   if (coin) {
15*840edd8aSBalazs Benics     p = (int *)malloc(sizeof(int));
16*840edd8aSBalazs Benics   }
17*840edd8aSBalazs Benics   p = 0; // Pointee of 'p' dies, which is recognized at the next statement.
18*840edd8aSBalazs Benics   next_statement(); // expected-warning {{Potential memory leak}}
19*840edd8aSBalazs Benics }
20*840edd8aSBalazs Benics 
malloc_twice()21*840edd8aSBalazs Benics void malloc_twice() {
22*840edd8aSBalazs Benics   static int *p;
23*840edd8aSBalazs Benics   p = (int *)malloc(sizeof(int));
24*840edd8aSBalazs Benics   next_statement();
25*840edd8aSBalazs Benics   p = (int *)malloc(sizeof(int));
26*840edd8aSBalazs Benics   next_statement(); // expected-warning {{Potential memory leak}}
27*840edd8aSBalazs Benics   p = 0;
28*840edd8aSBalazs Benics   next_statement(); // expected-warning {{Potential memory leak}}
29*840edd8aSBalazs Benics }
30*840edd8aSBalazs Benics 
malloc_escape()31*840edd8aSBalazs Benics void malloc_escape() {
32*840edd8aSBalazs Benics   static int *p;
33*840edd8aSBalazs Benics   p = (int *)malloc(sizeof(int));
34*840edd8aSBalazs Benics   escape(p); // no-leak
35*840edd8aSBalazs Benics   p = 0; // no-leak
36*840edd8aSBalazs Benics }
37*840edd8aSBalazs Benics 
38*840edd8aSBalazs Benics void free_whatever_escaped();
malloc_escape_reversed()39*840edd8aSBalazs Benics void malloc_escape_reversed() {
40*840edd8aSBalazs Benics   static int *p;
41*840edd8aSBalazs Benics   escape(&p);
42*840edd8aSBalazs Benics   p = (int *)malloc(sizeof(int));
43*840edd8aSBalazs Benics   free_whatever_escaped();
44*840edd8aSBalazs Benics   p = 0; // FIXME: We should not report a leak here.
45*840edd8aSBalazs Benics   next_statement(); // expected-warning {{Potential memory leak}}
46*840edd8aSBalazs Benics }
47*840edd8aSBalazs Benics 
malloc_return_static()48*840edd8aSBalazs Benics int *malloc_return_static() {
49*840edd8aSBalazs Benics   static int *p = (int *)malloc(sizeof(int));
50*840edd8aSBalazs Benics   return p; // no-leak
51*840edd8aSBalazs Benics }
52*840edd8aSBalazs Benics 
malloc_unreachable(int rng)53*840edd8aSBalazs Benics int malloc_unreachable(int rng) {
54*840edd8aSBalazs Benics   // 'p' does not escape and never freed :(
55*840edd8aSBalazs Benics   static int *p;
56*840edd8aSBalazs Benics 
57*840edd8aSBalazs Benics   // For the second invocation of this function, we leak the previous pointer.
58*840edd8aSBalazs Benics   // FIXME: We should catch this at some point.
59*840edd8aSBalazs Benics   p = (int *)malloc(sizeof(int));
60*840edd8aSBalazs Benics   *p = 0;
61*840edd8aSBalazs Benics 
62*840edd8aSBalazs Benics   if (rng > 0)
63*840edd8aSBalazs Benics     *p = rng;
64*840edd8aSBalazs Benics 
65*840edd8aSBalazs Benics   return *p; // FIXME: We just leaked 'p'. We should warn about this.
66*840edd8aSBalazs Benics }
67*840edd8aSBalazs Benics 
malloc_cond(bool cond)68*840edd8aSBalazs Benics void malloc_cond(bool cond) {
69*840edd8aSBalazs Benics   static int *p;
70*840edd8aSBalazs Benics   if (cond) {
71*840edd8aSBalazs Benics     p = (int*)malloc(sizeof(int));
72*840edd8aSBalazs Benics     free_whatever_escaped();
73*840edd8aSBalazs Benics     p = 0; // FIXME: We should not report a leak here.
74*840edd8aSBalazs Benics     next_statement(); // expected-warning {{Potential memory leak}}
75*840edd8aSBalazs Benics   }
76*840edd8aSBalazs Benics   escape(&p);
77*840edd8aSBalazs Benics }
78