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