1 #include <stdlib.h>
2 #include "analyzer-decls.h"
3 
4 extern int foo (int);
5 
6 static int __attribute__((noinline))
do_stuff_2(int * p,int n)7 do_stuff_2 (int *p, int n)
8 {
9   return 0;
10 }
11 
12 /* As malloc-vs-local.c, but hand-inlining the logic.  */
13 
14 /* Repeated (n > 10) predicate.  */
15 
test_repeated_predicate_1(int n)16 int test_repeated_predicate_1 (int n)
17 {
18   int buf[10];
19   int *ptr;
20   int result;
21 
22   if (n > 10)
23     ptr = (int *)malloc (sizeof (int) * n);
24   else
25     ptr = buf;
26 
27   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
28 
29   {
30     int *p = ptr;
31     int sum = 0;
32     int i;
33     for (i = 0; i < n; i++)
34       p[i] = i;
35     for (i = 0; i < n; i++)
36       sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
37     result = sum;
38   }
39 
40   __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
41 
42   if (n > 10)
43     free (ptr); /* { dg-bogus "not on the heap" } */
44 
45   return result; /* { dg-bogus "leak" } */
46 }
47 
48 /* As above, but with just one loop.  */
49 
test_repeated_predicate_1a(int n)50 int test_repeated_predicate_1a (int n)
51 {
52   int buf[10];
53   int *ptr;
54   int result;
55 
56   if (n > 10)
57     ptr = (int *)malloc (sizeof (int) * n);
58   else
59     ptr = buf;
60 
61   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
62 
63   {
64     int *p = ptr;
65     int sum = 0;
66     int i;
67     for (i = 0; i < n; i++)
68       p[i] = i;
69     result = sum;
70   }
71 
72   __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
73 
74   if (n > 10)
75     free (ptr); /* { dg-bogus "not on the heap" } */
76 
77   return result; /* { dg-bogus "leak" } */
78 }
79 
80 /* A simpler version of the above.  */
81 
test_repeated_predicate_2(int n)82 int test_repeated_predicate_2 (int n)
83 {
84   int buf[10];
85   int *ptr;
86   int result;
87 
88   if (n > 10)
89     ptr = (int *)malloc (sizeof (int) * n);
90   else
91     ptr = buf;
92 
93   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
94 
95   result = do_stuff_2 (ptr, n);
96 
97   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
98 
99   if (n > 10)
100     free (ptr); /* { dg-bogus "not on the heap" } */
101 
102   return result; /* { dg-bogus "leak" } */
103 }
104 
105 /* A predicate that sets a flag for the 2nd test.  */
106 
test_explicit_flag(int n)107 int test_explicit_flag (int n)
108 {
109   int buf[10];
110   int *ptr;
111   int result;
112   int need_to_free = 0;
113 
114   if (n > 10)
115     {
116       ptr = (int *)malloc (sizeof (int) * n);
117       need_to_free = 1;
118     }
119   else
120     ptr = buf;
121 
122   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
123 
124   {
125     int *p = ptr;
126     int sum = 0;
127     int i;
128     for (i = 0; i < n; i++)
129       p[i] = i;
130     for (i = 0; i < n; i++)
131       sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
132     result = sum;
133   }
134 
135   __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
136 
137   if (need_to_free)
138     free (ptr); /* { dg-bogus "not on the heap" } */
139 
140   return result; /* { dg-bogus "leak" } */
141 }
142 
143 /* Pointer comparison.  */
144 
test_pointer_comparison(int n)145 int test_pointer_comparison (int n)
146 {
147   int buf[10];
148   int *ptr;
149   int result;
150 
151   if (n > 10)
152     ptr = (int *)malloc (sizeof (int) * n);
153   else
154     ptr = buf;
155 
156   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
157 
158   {
159     int *p = ptr;
160     int sum = 0;
161     int i;
162     for (i = 0; i < n; i++)
163       p[i] = i;
164     for (i = 0; i < n; i++)
165       sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
166     result = sum;
167   }
168 
169   __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
170 
171   if (ptr != buf)
172     free (ptr); /* { dg-bogus "not on the heap" } */
173 
174   return result; /* { dg-bogus "leak" } */
175 }
176