1 /* Tests for data model handling of unknown fns. */
4 #include "analyzer-decls.h"
6 void unknown_fn (void *);
13 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
16 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
19 __analyzer_eval (i
== 42); /* { dg-warning "UNKNOWN" } */
22 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
24 /* Even though we're not passing &i to unknown_fn, it escaped
25 above, so unknown_fn could write to it. */
27 __analyzer_eval (i
== 17); /* { dg-warning "UNKNOWN" } */
30 /* As test_1, but with an unknown fn_ptr. */
32 void test_1a (void (*fn_ptr
) (void *))
37 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
40 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
43 __analyzer_eval (i
== 42); /* { dg-warning "UNKNOWN" } */
46 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
48 /* Even though we're not passing &i to unknown_fn, it escaped
49 above, so fn_ptr (NULL) could write to it. */
51 __analyzer_eval (i
== 17); /* { dg-warning "UNKNOWN" } */
54 int *global_for_test_2
;
61 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
63 global_for_test_2
= &i
;
65 __analyzer_eval (i
== 42); /* { dg-warning "UNKNOWN" } */
67 global_for_test_2
= NULL
;
70 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
72 /* Even though the global no longer points to i, it escaped
73 above, so unknown_fn could write to it. */
75 __analyzer_eval (i
== 17); /* { dg-warning "UNKNOWN" } */
87 struct used_by_test_3 s
;
91 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
94 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
95 __analyzer_eval (s
.int_ptr
== &i
); /* { dg-warning "TRUE" } */
97 /* i should escape here. */
99 __analyzer_eval (i
== 42); /* { dg-warning "UNKNOWN" } */
100 __analyzer_eval (s
.int_ptr
== &i
); /* { dg-warning "UNKNOWN" } */
103 __analyzer_eval (s
.int_ptr
== NULL
); /* { dg-warning "TRUE" } */
106 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
108 /* Even though nothing we know about points to i, it escaped
109 above, so unknown_fn could write to it. */
111 __analyzer_eval (i
== 17); /* { dg-warning "UNKNOWN" } */
114 struct used_by_test_4
119 void test_4 (struct used_by_test_4
*st4_ptr
)
121 /* Something unknown called "test_4", and hence *st4_ptr has
122 effectively already escaped. */
125 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
128 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
130 /* Given that *st4_ptr has effectively already escaped, calling
131 an unknown fn should invalidate our knowledge of i". */
132 st4_ptr
->int_ptr
= &i
;
134 __analyzer_eval (i
== 42); /* { dg-warning "UNKNOWN" } */
136 /* ...and "&i" should now be treated as having escaped. */
138 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
139 st4_ptr
->int_ptr
= NULL
;
141 __analyzer_eval (i
== 17); /* { dg-warning "UNKNOWN" } */
144 static void __attribute__((noinline
))
155 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
158 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
161 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
163 /* Ensure that we don't consider &i to have escaped. */
165 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
168 extern int __attribute__ ((__pure__
))
169 unknown_pure_fn (void *);
176 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
178 unknown_pure_fn (&i
);
179 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
182 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
184 /* Ensure that we don't consider &i to have escaped. */
186 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
189 extern void unknown_const_fn (const void *);
196 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
198 /* &i is passed as a const void *, so i shouldn't be clobbered by
200 unknown_const_fn (&i
);
201 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
204 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
206 /* Ensure that we don't consider &i to have escaped. */
208 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
211 struct used_by_test_8
221 __analyzer_eval (i
== 42); /* { dg-warning "TRUE" } */
223 struct used_by_test_8 st8
;
226 /* Although unknown_const_fn takes a const void *, the
227 int_ptr is a non-const int *, and so &i should be considered
229 unknown_const_fn (&st8
);
230 __analyzer_eval (i
== 42); /* { dg-warning "UNKNOWN" } */
233 __analyzer_eval (i
== 17); /* { dg-warning "TRUE" } */
235 /* &i should be considered to have escaped. */
237 __analyzer_eval (i
== 17); /* { dg-warning "UNKNOWN" } */