analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / ggc-tests.cc
1 /* Unit tests for GCC's garbage collector (and gengtype etc).
2    Copyright (C) 2015-2022 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tree-core.h"
24 #include "tree.h"
25 #include "selftest.h"
26
27 #if CHECKING_P
28
29 /* The various GTY markers must be outside of a namespace to be seen by
30    gengtype, so we don't put this file within the selftest namespace.  */
31
32 \f
33
34 /* Verify that a simple struct works, and that it can
35    own references to non-roots, and have them be marked.  */
36
37 struct GTY(()) test_struct
38 {
39   struct test_struct *other;
40 };
41
42 static GTY(()) test_struct *root_test_struct;
43
44 static void
45 test_basic_struct ()
46 {
47   root_test_struct = ggc_cleared_alloc <test_struct> ();
48   root_test_struct->other = ggc_cleared_alloc <test_struct> ();
49
50   ggc_collect (GGC_COLLECT_FORCE);
51
52   ASSERT_TRUE (ggc_marked_p (root_test_struct));
53   ASSERT_TRUE (ggc_marked_p (root_test_struct->other));
54 }
55
56 \f
57
58 /* Selftest for GTY((length)).  */
59
60 /* A test struct using GTY((length)).  */
61
62 struct GTY(()) test_of_length
63 {
64   int num_elem;
65   struct test_of_length * GTY ((length ("%h.num_elem"))) elem[1];
66 };
67
68 static GTY(()) test_of_length *root_test_of_length;
69
70 static void
71 test_length ()
72 {
73   const int count = 5;
74   size_t sz = sizeof (test_of_length) + (count- 1) * sizeof (test_of_length *);
75   root_test_of_length = (test_of_length *)ggc_internal_cleared_alloc (sz);
76   root_test_of_length->num_elem = count;
77   for (int i = 0; i < count; i++)
78     root_test_of_length->elem[i] = ggc_cleared_alloc <test_of_length> ();
79
80   ggc_collect (GGC_COLLECT_FORCE);
81
82   ASSERT_TRUE (ggc_marked_p (root_test_of_length));
83   for (int i = 0; i < count; i++)
84     ASSERT_TRUE (ggc_marked_p (root_test_of_length->elem[i]));
85 }
86
87 \f
88
89 /* Selftest for unions, GTY((tag)), and GTY((desc)).  */
90
91 /* A struct with a reference that's an a different offset to test_struct,
92    to ensure that we're using the correct types.  */
93
94 struct GTY(()) test_other
95 {
96   char dummy[256];
97   test_struct *m_ptr;
98 };
99
100 enum which_field
101 {
102   WHICH_FIELD_USE_TEST_STRUCT,
103   WHICH_FIELD_USE_TEST_OTHER
104 };
105
106 /* An example function for use by a GTY((desc)) marker.  */
107
108 static enum which_field
109 calc_desc (int kind)
110 {
111   switch (kind)
112     {
113     case 0: return WHICH_FIELD_USE_TEST_STRUCT;
114     case 1: return WHICH_FIELD_USE_TEST_OTHER;
115     default:
116       gcc_unreachable ();
117     }
118 }
119
120 /* A struct containing an example of a union, showing the "tag" and
121    "desc" markers.  */
122
123 struct GTY(()) test_of_union
124 {
125   int m_kind;
126   union u {
127     test_struct * GTY ((tag ("WHICH_FIELD_USE_TEST_STRUCT") )) u_test_struct;
128     test_other * GTY ((tag ("WHICH_FIELD_USE_TEST_OTHER") )) u_test_other;
129   } GTY ((desc ("calc_desc (%0.m_kind)"))) m_u;
130 };
131
132 /* Example roots.  */
133
134 static GTY(()) test_of_union *root_test_of_union_1;
135 static GTY(()) test_of_union *root_test_of_union_2;
136
137 /* Verify that the above work correctly.  */
138
139 static void
140 test_union ()
141 {
142   root_test_of_union_1 = ggc_cleared_alloc <test_of_union> ();
143   root_test_of_union_1->m_kind = 0;
144   test_struct *ts = ggc_cleared_alloc <test_struct> ();
145   root_test_of_union_1->m_u.u_test_struct = ts;
146
147   root_test_of_union_2 = ggc_cleared_alloc <test_of_union> ();
148   root_test_of_union_2->m_kind = 1;
149   test_other *other = ggc_cleared_alloc <test_other> ();
150   root_test_of_union_2->m_u.u_test_other = other;
151   test_struct *referenced_by_other = ggc_cleared_alloc <test_struct> ();
152   other->m_ptr = referenced_by_other;
153
154   ggc_collect (GGC_COLLECT_FORCE);
155
156   ASSERT_TRUE (ggc_marked_p (root_test_of_union_1));
157   ASSERT_TRUE (ggc_marked_p (ts));
158
159   ASSERT_TRUE (ggc_marked_p (root_test_of_union_2));
160   ASSERT_TRUE (ggc_marked_p (other));
161   ASSERT_TRUE (ggc_marked_p (referenced_by_other));
162 }
163
164 \f
165
166 /* Verify that destructors get run when instances are collected.  */
167
168 class GTY(()) test_struct_with_dtor
169 {
170 public:
171   /* This struct has a destructor; it *ought* to be called
172      by the ggc machinery when instances are collected.  */
173   ~test_struct_with_dtor () { dtor_call_count++; }
174
175   static int dtor_call_count;
176 };
177
178 int test_struct_with_dtor::dtor_call_count;
179
180 static void
181 test_finalization ()
182 {
183 #if GCC_VERSION >= 4003
184   ASSERT_FALSE (need_finalization_p <test_struct> ());
185   ASSERT_TRUE (need_finalization_p <test_struct_with_dtor> ());
186 #endif
187
188   /* Create some garbage.  */
189   const int count = 10;
190   for (int i = 0; i < count; i++)
191     ggc_cleared_alloc <test_struct_with_dtor> ();
192
193   test_struct_with_dtor::dtor_call_count = 0;
194
195   ggc_collect (GGC_COLLECT_FORCE);
196
197   /* Verify that the destructor was run for each instance.  */
198   ASSERT_EQ (count, test_struct_with_dtor::dtor_call_count);
199 }
200
201 \f
202
203 /* Verify that a global can be marked as "deletable".  */
204
205 static GTY((deletable)) test_struct *test_of_deletable;
206
207 static void
208 test_deletable_global ()
209 {
210   test_of_deletable = ggc_cleared_alloc <test_struct> ();
211   ASSERT_TRUE (test_of_deletable != NULL);
212
213   ggc_collect (GGC_COLLECT_FORCE);
214
215   ASSERT_EQ (NULL, test_of_deletable);
216 }
217
218 \f
219
220 /* Verify that gengtype etc can cope with inheritance.  */
221
222 class GTY((desc("%h.m_kind"), tag("0"))) example_base
223 {
224  public:
225   example_base ()
226     : m_kind (0),
227       m_a (ggc_cleared_alloc <test_struct> ())
228   {}
229
230   void *
231   operator new (size_t sz)
232   {
233     return ggc_internal_cleared_alloc (sz);
234   }
235
236  protected:
237   example_base (int kind)
238     : m_kind (kind),
239       m_a (ggc_cleared_alloc <test_struct> ())
240   {}
241
242  public:
243   int m_kind;
244   test_struct *m_a;
245 };
246
247 class GTY((tag("1"))) some_subclass : public example_base
248 {
249  public:
250   some_subclass ()
251     : example_base (1),
252       m_b (ggc_cleared_alloc <test_struct> ())
253   {}
254
255   test_struct *m_b;
256 };
257
258 class GTY((tag("2"))) some_other_subclass : public example_base
259 {
260  public:
261   some_other_subclass ()
262     : example_base (2),
263       m_c (ggc_cleared_alloc <test_struct> ())
264   {}
265
266   test_struct *m_c;
267 };
268
269 /* Various test roots, both expressed as a ptr to the actual class, and
270    as a ptr to the base class.  */
271 static GTY(()) example_base *test_example_base;
272 static GTY(()) some_subclass *test_some_subclass;
273 static GTY(()) some_other_subclass *test_some_other_subclass;
274 static GTY(()) example_base *test_some_subclass_as_base_ptr;
275 static GTY(()) example_base *test_some_other_subclass_as_base_ptr;
276
277 static void
278 test_inheritance ()
279 {
280   test_example_base = new example_base ();
281   test_some_subclass = new some_subclass ();
282   test_some_other_subclass = new some_other_subclass ();
283   test_some_subclass_as_base_ptr = new some_subclass ();
284   test_some_other_subclass_as_base_ptr = new some_other_subclass ();
285
286   ggc_collect (GGC_COLLECT_FORCE);
287
288   /* Verify that the roots and everything referenced by them got marked
289      (both for fields in the base class and those in subclasses).  */
290   ASSERT_TRUE (ggc_marked_p (test_example_base));
291   ASSERT_TRUE (ggc_marked_p (test_example_base->m_a));
292
293   ASSERT_TRUE (ggc_marked_p (test_some_subclass));
294   ASSERT_TRUE (ggc_marked_p (test_some_subclass->m_a));
295   ASSERT_TRUE (ggc_marked_p (test_some_subclass->m_b));
296
297   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass));
298   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass->m_a));
299   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass->m_c));
300
301   ASSERT_TRUE (ggc_marked_p (test_some_subclass_as_base_ptr));
302   ASSERT_TRUE (ggc_marked_p (test_some_subclass_as_base_ptr->m_a));
303   ASSERT_TRUE (ggc_marked_p (((some_subclass *)
304                               test_some_subclass_as_base_ptr)->m_b));
305
306   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass_as_base_ptr));
307   ASSERT_TRUE (ggc_marked_p (test_some_other_subclass_as_base_ptr->m_a));
308   ASSERT_TRUE (ggc_marked_p (((some_other_subclass *)
309                               test_some_other_subclass_as_base_ptr)->m_c));
310 }
311
312 \f
313
314 /* Test of chain_next/chain_prev
315
316    Construct a very long linked list, so that without
317    the chain_next/chain_prev optimization we'd have
318    a stack overflow when gt_ggc_mx_test_node recurses.  */
319
320 struct GTY(( chain_next ("%h.m_next"),
321              chain_prev ("%h.m_prev") )) test_node
322 {
323   test_node *m_prev;
324   test_node *m_next;
325   int m_idx;
326 };
327
328 static GTY(()) test_node *root_test_node;
329
330 static void
331 test_chain_next ()
332 {
333   /* Ideally we would construct a long list so that the number of
334      stack frames would be deep enough to crash if gengtype has created
335      something that recurses.
336
337      However, as the list is lengthened to increase the chance of
338      overflowing the stack, the test will require more time and memory
339      to run.  On a Fedora 20 x86_64 box with 128GB of RAM, count=2000000
340      without the chain_next optimization reliably overflowed the stack,
341      but the test took 0.5s to run.
342
343      For now this test runs with a low value for "count", which defeats
344      the main purpose of the test - though it at least gives us coverage
345      for walking a GTY((chain_next)) list.
346
347      We could potentially increase this value once we have a better sense
348      of the time and space requirements of the test on different hosts,
349      or perhaps find a way to reduce the stack size when running this
350      testcase.  */
351   const int count = 10;
352
353   /* Build the linked list.  */
354   root_test_node = ggc_cleared_alloc <test_node> ();
355   test_node *tail_node = root_test_node;
356   for (int i = 0; i < count; i++)
357     {
358       test_node *new_node = ggc_cleared_alloc <test_node> ();
359       tail_node->m_next = new_node;
360       new_node->m_prev = tail_node;
361       new_node->m_idx = i;
362       tail_node = new_node;
363     }
364
365   ggc_collect (GGC_COLLECT_FORCE);
366
367   /* If we got here, we survived.  */
368
369   /* Verify that all nodes in the list were marked.  */
370   ASSERT_TRUE (ggc_marked_p (root_test_node));
371   test_node *iter_node = root_test_node->m_next;
372   for (int i = 0; i < count; i++)
373     {
374       ASSERT_TRUE (ggc_marked_p (iter_node));
375       ASSERT_EQ (i, iter_node->m_idx);
376       iter_node = iter_node->m_next;
377     }
378 }
379
380 \f
381
382 /* Test for GTY((user)).  */
383
384 struct GTY((user)) user_struct
385 {
386   char dummy[16];
387   test_struct *m_ptr;
388 };
389
390 static GTY(()) user_struct *root_user_struct_ptr;
391
392 /* A global for verifying that the user-provided gt_ggc_mx gets
393    called.  */
394 static int num_calls_to_user_gt_ggc_mx;
395
396 /* User-provided implementation of gt_ggc_mx.  */
397
398 static void
399 gt_ggc_mx (user_struct *p)
400 {
401   num_calls_to_user_gt_ggc_mx++;
402   gt_ggc_mx_test_struct (p->m_ptr);
403 }
404
405 /* User-provided implementation of gt_pch_nx.  */
406
407 static void
408 gt_pch_nx (user_struct *p)
409 {
410   gt_pch_nx_test_struct (p->m_ptr);
411 }
412
413 /* User-provided implementation of gt_pch_nx.  */
414
415 static void
416 gt_pch_nx (user_struct *p, gt_pointer_operator op, void *cookie)
417 {
418   op (&(p->m_ptr), NULL, cookie);
419 }
420
421 /* Verify that GTY((user)) works.  */
422
423 static void
424 test_user_struct ()
425 {
426   root_user_struct_ptr = ggc_cleared_alloc <user_struct> ();
427   test_struct *referenced = ggc_cleared_alloc <test_struct> ();
428   root_user_struct_ptr->m_ptr = referenced;
429
430   num_calls_to_user_gt_ggc_mx = 0;
431
432   ggc_collect (GGC_COLLECT_FORCE);
433
434   ASSERT_TRUE (ggc_marked_p (root_user_struct_ptr));
435   ASSERT_TRUE (ggc_marked_p (referenced));
436   ASSERT_TRUE (num_calls_to_user_gt_ggc_mx > 0);
437 }
438
439 \f
440
441 /* Smoketest to ensure that the tree type is marked.  */
442
443 static GTY(()) tree dummy_unittesting_tree;
444
445 static void
446 test_tree_marking ()
447 {
448   dummy_unittesting_tree = build_int_cst (integer_type_node, 1066);
449
450   ggc_collect (GGC_COLLECT_FORCE);
451
452   ASSERT_TRUE (ggc_marked_p (dummy_unittesting_tree));
453 }
454
455 \f
456
457 /* Ideas for other tests:
458    - pch-handling  */
459
460 namespace selftest {
461
462 /* Run all of the selftests within this file.  */
463
464 void
465 ggc_tests_cc_tests ()
466 {
467   test_basic_struct ();
468   test_length ();
469   test_union ();
470   test_finalization ();
471   test_deletable_global ();
472   test_inheritance ();
473   test_chain_next ();
474   test_user_struct ();
475   test_tree_marking ();
476 }
477
478 } // namespace selftest
479
480 #include "gt-ggc-tests.h"
481
482 #else /* #if CHECKING_P */
483
484 /* The #if CHECKING_P code above has various GTY-marked roots.
485    gengtype has no knowledge of the preprocessor, and so detects
486    these roots and writes them out to gt-ggc-tests.h.
487    In a !CHECKING_P build we can ignore gt-ggc-tests.h, but the
488    root tables are referenced in the various generated gtype-*.c
489    files like this:
490
491       ...snip...
492       extern const struct ggc_root_tab gt_ggc_r_gt_ggc_tests_h[];
493       ...snip...
494
495       EXPORTED_CONST struct ggc_root_tab * const gt_ggc_rtab[] = {
496         ...snip...
497         gt_ggc_r_gt_ggc_tests_h,
498         ...snip...
499       };
500
501     Hence to avoid a link failure, we provide dummy implementations
502     of these root tables in an unchecked build.
503
504     Note that these conditional roots imply that PCH files are
505     incompatible between checked and unchecked builds.  */
506
507 EXPORTED_CONST struct ggc_root_tab gt_ggc_r_gt_ggc_tests_h[] = {
508   LAST_GGC_ROOT_TAB
509 };
510
511 EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_gt_ggc_tests_h[] = {
512   LAST_GGC_ROOT_TAB
513 };
514
515 #endif /* #else clause of #if CHECKING_P */