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