middle-end: Fix stalled swapped condition code value [PR115836]
[official-gcc.git] / gcc / testsuite / c-c++-common / analyzer / malloc-vs-local-1a.c
blobbf77862e67c47c7c7d315deb60c075de986af610
1 /* { dg-additional-options "-fno-analyzer-call-summaries -fanalyzer-transitivity" } */
3 #include <stdlib.h>
4 #include "analyzer-decls.h"
6 extern int foo (int);
8 static int __attribute__((noinline))
9 do_stuff (int *p, int n)
11 int sum = 0;
12 int i;
13 for (i = 0; i < n; i++)
14 p[i] = i; /* { dg-warning "dereference of possibly-NULL 'p'" } */
15 for (i = 0; i < n; i++)
16 sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
17 return sum;
20 static int __attribute__((noinline))
21 do_stuff_2 (int *p, int n)
23 return 0;
26 /* Various examples of functions that use either a malloc buffer
27 or a local buffer, do something, then conditionally free the
28 buffer, tracking whether "free" is necessary in various
29 ways.
31 In each case, there ought to be only two paths through the function,
32 not four. */
34 /* Repeated (n > 10) predicate. */
36 int test_repeated_predicate_1 (int n)
38 int buf[10];
39 int *ptr;
40 int result;
42 if (n > 10)
43 ptr = (int *)malloc (sizeof (int) * n);
44 else
45 ptr = buf;
47 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
49 result = do_stuff (ptr, n);
51 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
53 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
56 if (n > 10)
57 free (ptr); /* { dg-bogus "not on the heap" } */
59 return result; /* { dg-bogus "leak" } */
62 /* A simpler version of the above. */
64 int test_repeated_predicate_2 (int n)
66 int buf[10];
67 int *ptr;
68 int result;
70 if (n > 10)
71 ptr = (int *)malloc (sizeof (int) * n);
72 else
73 ptr = buf;
75 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
77 result = do_stuff_2 (ptr, n);
79 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
81 if (n > 10)
82 free (ptr); /* { dg-bogus "not on the heap" } */
84 return result; /* { dg-bogus "leak" } */
87 /* A predicate that sets a flag for the 2nd test. */
89 int test_explicit_flag (int n)
91 int buf[10];
92 int *ptr;
93 int result;
94 int need_to_free = 0;
96 if (n > 10)
98 ptr = (int *)malloc (sizeof (int) * n);
99 need_to_free = 1;
101 else
102 ptr = buf;
104 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
106 result = do_stuff (ptr, n);
108 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
111 if (need_to_free)
112 free (ptr); /* { dg-bogus "not on the heap" } */
114 return result; /* { dg-bogus "leak" } */
117 /* Pointer comparison. */
119 int test_pointer_comparison (int n)
121 int buf[10];
122 int *ptr;
123 int result;
125 if (n > 10)
126 ptr = (int *)malloc (sizeof (int) * n);
127 else
128 ptr = buf;
130 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
132 result = do_stuff (ptr, n);
134 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
137 if (ptr != buf)
138 free (ptr); /* { dg-bogus "not on the heap" } */
140 return result; /* { dg-bogus "leak" } */
143 /* Set a flag based on a conditional, then use it, then reuse the
144 conditional. */
146 int test_initial_flag (int n)
148 int buf[10];
149 int *ptr;
150 int result;
151 int on_heap = 0;
153 if (n > 10)
154 on_heap = 1;
155 else
156 on_heap = 0;
158 /* Due to state-merging, we lose the relationship between 'n > 10'
159 and 'on_heap' here; we have to rely on feasibility-checking
160 in the diagnostic_manager to reject the false warnings. */
161 __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
163 if (on_heap)
164 ptr = (int *)malloc (sizeof (int) * n);
165 else
166 ptr = buf;
168 __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
170 result = do_stuff (ptr, n);
172 __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
173 // FIXME: why 3 here?
175 if (n > 10)
176 free (ptr); /* { dg-bogus "not on the heap" } */
178 return result; /* { dg-bogus "leak" } */