1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -analyzer-max-loop 4 -verify %s
2 #include "Inputs/system-header-simulator.h"
3 
4 typedef __typeof(sizeof(int)) size_t;
5 void *malloc(size_t);
6 
another_function(int * y)7 static int another_function(int *y) {
8   if (*y > 0)
9     return *y;
10   return 0;
11 }
12 
function_which_doesnt_give_up(int ** x)13 static void function_which_doesnt_give_up(int **x) {
14    *x = 0;
15 }
16 
function_which_gives_up(int * x)17 static void function_which_gives_up(int *x) {
18   for (int i = 0; i < 5; ++i)
19     (*x)++;
20 }
21 
function_which_gives_up_nested(int * x)22 static void function_which_gives_up_nested(int *x) {
23   function_which_gives_up(x);
24   for (int i = 0; i < 5; ++i)
25     (*x)++;
26 }
27 
function_which_doesnt_give_up_nested(int * x,int * y)28 static void function_which_doesnt_give_up_nested(int *x, int *y) {
29   *y = another_function(x);
30   function_which_gives_up(x);
31 }
32 
coverage1(int * x)33 void coverage1(int *x) {
34   function_which_gives_up(x);
35   char *m = (char*)malloc(12);
36 } // expected-warning {{Potential leak of memory pointed to by 'm'}}
37 
coverage2(int * x)38 void coverage2(int *x) {
39   if (x) {
40     function_which_gives_up(x);
41     char *m = (char*)malloc(12);
42   }
43 } // expected-warning {{Potential leak of memory pointed to by 'm'}}
44 
coverage3(int * x)45 void coverage3(int *x) {
46   x++;
47   function_which_gives_up(x);
48   char *m = (char*)malloc(12);
49 } // expected-warning {{Potential leak of memory pointed to by 'm'}}
50 
coverage4(int * x)51 void coverage4(int *x) {
52   *x += another_function(x);
53   function_which_gives_up(x);
54   char *m = (char*)malloc(12);
55 } // expected-warning {{Potential leak of memory pointed to by 'm'}}
56 
coverage5(int * x)57 void coverage5(int *x) {
58   for (int i = 0; i<7; ++i)
59     function_which_gives_up(x);
60   // The root function gives up here.
61   char *m = (char*)malloc(12); // no-warning
62 }
63 
coverage6(int * x)64 void coverage6(int *x) {
65   for (int i = 0; i<3; ++i) {
66     function_which_gives_up(x);
67   }
68   char *m = (char*)malloc(12);
69 } // expected-warning {{Potential leak of memory pointed to by 'm'}}
70 
coverage7_inline(int * i)71 int coverage7_inline(int *i) {
72   function_which_doesnt_give_up(&i);
73   return *i; // expected-warning {{Dereference}}
74 }
75 
coverage8(int * x)76 void coverage8(int *x) {
77   int y;
78   function_which_doesnt_give_up_nested(x, &y);
79   y = (*x)/y;  // expected-warning {{Division by zero}}
80   char *m = (char*)malloc(12);
81 } // expected-warning {{Potential leak of memory pointed to by 'm'}}
82 
function_which_gives_up_settonull(int ** x)83 void function_which_gives_up_settonull(int **x) {
84   *x = 0;
85   int y = 0;
86   for (int i = 0; i < 5; ++i)
87     y++;
88 }
89 
coverage9(int * x)90 void coverage9(int *x) {
91   int y = 5;
92   function_which_gives_up_settonull(&x);
93   y = (*x);  // no warning
94 }
95 
empty_function()96 static void empty_function(){
97 }
use_empty_function(int x)98 int use_empty_function(int x) {
99     x = 0;
100     empty_function();
101     return 5/x; //expected-warning {{Division by zero}}
102 }
103