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