1 /* { dg-additional-options "-fno-analyzer-call-summaries -fanalyzer-transitivity" } */
4 #include "analyzer-decls.h"
8 static int __attribute__((noinline
))
9 do_stuff (int *p
, int n
)
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" } */
20 static int __attribute__((noinline
))
21 do_stuff_2 (int *p
, int n
)
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
31 In each case, there ought to be only two paths through the function,
34 /* Repeated (n > 10) predicate. */
36 int test_repeated_predicate_1 (int n
)
43 ptr
= (int *)malloc (sizeof (int) * n
);
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" } */
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
)
71 ptr
= (int *)malloc (sizeof (int) * n
);
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" } */
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
)
98 ptr
= (int *)malloc (sizeof (int) * n
);
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" } */
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
)
126 ptr
= (int *)malloc (sizeof (int) * n
);
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" } */
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
146 int test_initial_flag (int n
)
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" } */
164 ptr
= (int *)malloc (sizeof (int) * n
);
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?
176 free (ptr
); /* { dg-bogus "not on the heap" } */
178 return result
; /* { dg-bogus "leak" } */