[RISC-V] Avoid unnecessary extensions when value is already extended
[official-gcc.git] / gcc / testsuite / c-c++-common / analyzer / unknown-fns-2.c
blob1c4bdd6b51b855cf41fb4cb31bbfd180252fc9fd
1 /* Tests for data model handling of unknown fns. */
3 #include <stddef.h>
4 #include "analyzer-decls.h"
6 void unknown_fn (void *);
8 void test_1 (void)
10 int i;
12 i = 42;
13 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
15 unknown_fn (NULL);
16 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
18 unknown_fn (&i);
19 __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
21 i = 17;
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. */
26 unknown_fn (NULL);
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 *))
34 int i;
36 i = 42;
37 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
39 fn_ptr (NULL);
40 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
42 fn_ptr (&i);
43 __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
45 i = 17;
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. */
50 fn_ptr (NULL);
51 __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
54 int *global_for_test_2;
56 void test_2 (void)
58 int i;
60 i = 42;
61 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
63 global_for_test_2 = &i;
64 unknown_fn (NULL);
65 __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
67 global_for_test_2 = NULL;
69 i = 17;
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. */
74 unknown_fn (NULL);
75 __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
78 struct used_by_test_3
80 int *int_ptr;
83 void test_3 (void)
85 int i;
87 struct used_by_test_3 s;
88 s.int_ptr = &i;
90 i = 42;
91 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
93 unknown_fn (NULL);
94 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
95 __analyzer_eval (s.int_ptr == &i); /* { dg-warning "TRUE" } */
97 /* i should escape here. */
98 unknown_fn (&s);
99 __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
100 __analyzer_eval (s.int_ptr == &i); /* { dg-warning "UNKNOWN" } */
102 s.int_ptr = NULL;
103 __analyzer_eval (s.int_ptr == NULL); /* { dg-warning "TRUE" } */
105 i = 17;
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. */
110 unknown_fn (NULL);
111 __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
114 struct used_by_test_4
116 int *int_ptr;
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. */
124 int i = 42;
125 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
127 unknown_fn (NULL);
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;
133 unknown_fn (NULL);
134 __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
136 /* ...and "&i" should now be treated as having escaped. */
137 i = 17;
138 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
139 st4_ptr->int_ptr = NULL;
140 unknown_fn (NULL);
141 __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
144 static void __attribute__((noinline))
145 known_fn (void *ptr)
147 /* Empty. */
150 void test_5 (void)
152 int i;
154 i = 42;
155 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
157 known_fn (&i);
158 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
160 i = 17;
161 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
163 /* Ensure that we don't consider &i to have escaped. */
164 unknown_fn (NULL);
165 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
168 extern int __attribute__ ((__pure__))
169 unknown_pure_fn (void *);
171 void test_6 (void)
173 int i;
175 i = 42;
176 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
178 unknown_pure_fn (&i);
179 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
181 i = 17;
182 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
184 /* Ensure that we don't consider &i to have escaped. */
185 unknown_fn (NULL);
186 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
189 extern void unknown_const_fn (const void *);
191 void test_7 (void)
193 int i;
195 i = 42;
196 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
198 /* &i is passed as a const void *, so i shouldn't be clobbered by
199 the call. */
200 unknown_const_fn (&i);
201 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
203 i = 17;
204 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
206 /* Ensure that we don't consider &i to have escaped. */
207 unknown_fn (NULL);
208 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
211 struct used_by_test_8
213 int *int_ptr;
216 void test_8 (void)
218 int i;
220 i = 42;
221 __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
223 struct used_by_test_8 st8;
224 st8.int_ptr = &i;
226 /* Although unknown_const_fn takes a const void *, the
227 int_ptr is a non-const int *, and so &i should be considered
228 writable. */
229 unknown_const_fn (&st8);
230 __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
232 i = 17;
233 __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
235 /* &i should be considered to have escaped. */
236 unknown_fn (NULL);
237 __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */