1 /* Unit tests for function-handling. 2 Copyright (C) 2015-2018 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 "tm.h" 24 #include "opts.h" 25 #include "hash-set.h" 26 #include "fixed-value.h" 27 #include "alias.h" 28 #include "flags.h" 29 #include "symtab.h" 30 #include "tree-core.h" 31 #include "stor-layout.h" 32 #include "tree.h" 33 #include "stringpool.h" 34 #include "stor-layout.h" 35 #include "rtl.h" 36 #include "predict.h" 37 #include "vec.h" 38 #include "hashtab.h" 39 #include "hash-set.h" 40 #include "hard-reg-set.h" 41 #include "input.h" 42 #include "function.h" 43 #include "dominance.h" 44 #include "cfg.h" 45 #include "cfganal.h" 46 #include "basic-block.h" 47 #include "tree-ssa-alias.h" 48 #include "internal-fn.h" 49 #include "gimple-fold.h" 50 #include "gimple-expr.h" 51 #include "toplev.h" 52 #include "print-tree.h" 53 #include "tree-iterator.h" 54 #include "gimplify.h" 55 #include "tree-cfg.h" 56 #include "basic-block.h" 57 #include "alias.h" 58 #include "symtab.h" 59 #include "inchash.h" 60 #include "tree.h" 61 #include "fold-const.h" 62 #include "stor-layout.h" 63 #include "stmt.h" 64 #include "hash-table.h" 65 #include "tree-ssa-alias.h" 66 #include "internal-fn.h" 67 #include "gimple-expr.h" 68 #include "is-a.h" 69 #include "gimple.h" 70 #include "tree-pass.h" 71 #include "context.h" 72 #include "hash-map.h" 73 #include "plugin-api.h" 74 #include "ipa-ref.h" 75 #include "cgraph.h" 76 #include "selftest.h" 77 #include "print-rtl.h" 78 79 #if CHECKING_P 80 81 namespace selftest { 82 83 /* Helper function for selftests of function-creation. */ 84 85 static tree 86 make_fndecl (tree return_type, 87 const char *name, 88 vec <tree> ¶m_types, 89 bool is_variadic = false) 90 { 91 tree fn_type; 92 if (is_variadic) 93 fn_type = build_varargs_function_type_array (return_type, 94 param_types.length (), 95 param_types.address ()); 96 else 97 fn_type = build_function_type_array (return_type, 98 param_types.length (), 99 param_types.address ()); 100 /* FIXME: this uses input_location: */ 101 tree fndecl = build_fn_decl (name, fn_type); 102 103 return fndecl; 104 } 105 106 /* Verify creating a function declaration equivalent to the following 107 int test_fndecl_int_void (void); 108 C declaration. */ 109 110 static void 111 test_fndecl_int_void () 112 { 113 auto_vec <tree> param_types; 114 const char *name = "test_fndecl_int_void"; 115 tree fndecl = make_fndecl (integer_type_node, 116 name, 117 param_types); 118 ASSERT_TRUE (fndecl != NULL); 119 120 /* Verify name of decl. */ 121 tree declname = DECL_NAME (fndecl); 122 ASSERT_TRUE (declname != NULL); 123 ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (declname)); 124 /* We expect it to use a *copy* of the string we passed in. */ 125 const char *identifier_ptr = IDENTIFIER_POINTER (declname); 126 ASSERT_NE (name, identifier_ptr); 127 ASSERT_EQ (0, strcmp ("test_fndecl_int_void", identifier_ptr)); 128 129 /* Verify type of fndecl. */ 130 ASSERT_EQ (FUNCTION_DECL, TREE_CODE (fndecl)); 131 tree fntype = TREE_TYPE (fndecl); 132 ASSERT_EQ (FUNCTION_TYPE, TREE_CODE (fntype)); 133 134 /* Verify return type. */ 135 ASSERT_EQ (integer_type_node, TREE_TYPE (fntype)); 136 137 /* Verify "void" args. */ 138 tree argtypes = TYPE_ARG_TYPES (fntype); 139 ASSERT_EQ (TREE_LIST, TREE_CODE (argtypes)); 140 ASSERT_EQ (void_type_node, TREE_VALUE (argtypes)); 141 ASSERT_EQ (NULL, TREE_CHAIN (argtypes)); 142 } 143 144 /* Verify creating a function declaration equivalent to the following 145 float test_fndecl_float_intchar (int, char); 146 C declaration. */ 147 148 static void 149 test_fndecl_float_intchar () 150 { 151 auto_vec <tree> param_types; 152 param_types.safe_push (integer_type_node); 153 param_types.safe_push (char_type_node); 154 const char *name = "test_fndecl_float_intchar"; 155 tree fndecl = make_fndecl (float_type_node, 156 name, 157 param_types); 158 ASSERT_TRUE (fndecl != NULL); 159 160 /* Verify name of decl. */ 161 tree declname = DECL_NAME (fndecl); 162 ASSERT_TRUE (declname != NULL); 163 ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (declname)); 164 /* We expect it to use a *copy* of the string we passed in. */ 165 const char *identifier_ptr = IDENTIFIER_POINTER (declname); 166 ASSERT_NE (name, identifier_ptr); 167 ASSERT_EQ (0, strcmp (name, identifier_ptr)); 168 169 /* Verify type of fndecl. */ 170 ASSERT_EQ (FUNCTION_DECL, TREE_CODE (fndecl)); 171 tree fntype = TREE_TYPE (fndecl); 172 ASSERT_EQ (FUNCTION_TYPE, TREE_CODE (fntype)); 173 174 /* Verify return type. */ 175 ASSERT_EQ (float_type_node, TREE_TYPE (fntype)); 176 177 /* Verify "(int, char)" args. */ 178 tree arg0 = TYPE_ARG_TYPES (fntype); 179 ASSERT_EQ (TREE_LIST, TREE_CODE (arg0)); 180 ASSERT_EQ (integer_type_node, TREE_VALUE (arg0)); 181 tree arg1 = TREE_CHAIN (arg0); 182 ASSERT_TRUE (arg1 != NULL); 183 ASSERT_EQ (TREE_LIST, TREE_CODE (arg1)); 184 ASSERT_EQ (char_type_node, TREE_VALUE (arg1)); 185 tree argterm = TREE_CHAIN (arg1); 186 ASSERT_TRUE (argterm != NULL); 187 ASSERT_EQ (TREE_LIST, TREE_CODE (argterm)); 188 ASSERT_EQ (void_type_node, TREE_VALUE (argterm)); 189 ASSERT_EQ (NULL, TREE_CHAIN (argterm)); 190 } 191 192 /* The test cases using these helper functions take a trivial function: 193 194 int test_fn (void) { return 42; } 195 196 and test various conversions done to it: 197 198 - gimplification 199 - construction of the CFG 200 - conversion to SSA form 201 - expansion to RTL form 202 203 In avoid having one overlong test case, this is broken 204 up into separate test cases for each stage, with helper functions 205 to minimize code duplication. 206 207 Another approach would be to attempt to directly construct a function 208 in the appropriate representation at each stage, though presumably 209 that would exhibit different kinds of failure compared to this 210 approach. */ 211 212 /* Construct this function: 213 int test_fn (void) { return 42; } 214 in generic tree form. Return the fndecl. */ 215 216 static tree 217 build_trivial_generic_function () 218 { 219 auto_vec <tree> param_types; 220 tree fndecl = make_fndecl (integer_type_node, 221 "test_fn", 222 param_types); 223 ASSERT_TRUE (fndecl != NULL); 224 225 /* Populate the function. */ 226 tree retval = build_decl (UNKNOWN_LOCATION, RESULT_DECL, 227 NULL_TREE, integer_type_node); 228 DECL_ARTIFICIAL (retval) = 1; 229 DECL_IGNORED_P (retval) = 1; 230 DECL_RESULT (fndecl) = retval; 231 232 /* Create a BIND_EXPR, and within it, a statement list. */ 233 tree stmt_list = alloc_stmt_list (); 234 tree_stmt_iterator stmt_iter = tsi_start (stmt_list); 235 tree block = make_node (BLOCK); 236 tree bind_expr 237 = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, block); 238 239 tree modify_retval = build2 (MODIFY_EXPR, 240 integer_type_node, 241 retval, 242 build_int_cst (integer_type_node, 42)); 243 tree return_stmt = build1 (RETURN_EXPR, 244 integer_type_node, 245 modify_retval); 246 tsi_link_after (&stmt_iter, return_stmt, TSI_CONTINUE_LINKING); 247 248 DECL_INITIAL (fndecl) = block; 249 BLOCK_SUPERCONTEXT (block) = fndecl; 250 251 /* how to add to function? the following appears to be how to 252 set the body of a fndecl: */ 253 DECL_SAVED_TREE(fndecl) = bind_expr; 254 255 /* Ensure that locals appear in the debuginfo. */ 256 BLOCK_VARS (block) = BIND_EXPR_VARS (bind_expr); 257 258 return fndecl; 259 } 260 261 /* Construct this function: 262 int test_fn (void) { return 42; } 263 in "high gimple" form. Return the fndecl. */ 264 265 static tree 266 build_trivial_high_gimple_function () 267 { 268 /* Construct a trivial function, and gimplify it: */ 269 tree fndecl = build_trivial_generic_function (); 270 gimplify_function_tree (fndecl); 271 return fndecl; 272 } 273 274 /* Build a CFG for a function in gimple form. */ 275 276 static void 277 build_cfg (tree fndecl) 278 { 279 function *fun = DECL_STRUCT_FUNCTION (fndecl); 280 ASSERT_TRUE (fun != NULL); 281 ASSERT_EQ (fndecl, fun->decl); 282 283 /* We first have to lower control flow; for our trivial test function 284 this gives us: 285 test_fn () 286 { 287 D.56 = 42; 288 goto <D.57>; 289 <D.57>: 290 return D.56; 291 } 292 */ 293 gimple_opt_pass *lower_cf_pass = make_pass_lower_cf (g); 294 push_cfun (fun); 295 lower_cf_pass->execute (fun); 296 pop_cfun (); 297 delete lower_cf_pass; 298 299 /* We can now convert to CFG form; for our trivial test function this 300 gives us: 301 test_fn () 302 { 303 <bb 2>: 304 D.56 = 42; 305 return D.56; 306 } 307 */ 308 gimple_opt_pass *build_cfg_pass = make_pass_build_cfg (g); 309 push_cfun (fun); 310 build_cfg_pass->execute (fun); 311 pop_cfun (); 312 delete build_cfg_pass; 313 } 314 315 /* Convert a gimple+CFG function to SSA form. */ 316 317 static void 318 convert_to_ssa (tree fndecl) 319 { 320 function *fun = DECL_STRUCT_FUNCTION (fndecl); 321 ASSERT_TRUE (fun != NULL); 322 ASSERT_EQ (fndecl, fun->decl); 323 324 gimple_opt_pass *build_ssa_pass = make_pass_build_ssa (g); 325 push_cfun (fun); 326 build_ssa_pass->execute (fun); 327 pop_cfun (); 328 delete build_ssa_pass; 329 } 330 331 /* Assuming we have a simple 3-block CFG like this: 332 [ENTRY] -> [block2] -> [EXIT] 333 get the "real" basic block (block 2). */ 334 335 static basic_block 336 get_real_block (function *fun) 337 { 338 ASSERT_TRUE (fun->cfg != NULL); 339 ASSERT_EQ (3, n_basic_blocks_for_fn (fun)); 340 basic_block bb2 = (*fun->cfg->x_basic_block_info)[2]; 341 ASSERT_TRUE (bb2 != NULL); 342 return bb2; 343 } 344 345 /* Verify that we have a simple 3-block CFG: the two "fake" ones, and 346 a "real" one: 347 [ENTRY] -> [block2] -> [EXIT]. */ 348 349 static void 350 verify_three_block_cfg (function *fun) 351 { 352 ASSERT_TRUE (fun->cfg != NULL); 353 ASSERT_EQ (3, n_basic_blocks_for_fn (fun)); 354 ASSERT_EQ (2, n_edges_for_fn (fun)); 355 356 /* The "fake" basic blocks. */ 357 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (fun); 358 ASSERT_TRUE (entry != NULL); 359 ASSERT_EQ (ENTRY_BLOCK, entry->index); 360 361 basic_block exit = EXIT_BLOCK_PTR_FOR_FN (fun); 362 ASSERT_TRUE (exit != NULL); 363 ASSERT_EQ (EXIT_BLOCK, exit->index); 364 365 /* The "real" basic block. */ 366 basic_block bb2 = get_real_block (fun); 367 ASSERT_TRUE (bb2 != NULL); 368 ASSERT_EQ (2, bb2->index); 369 370 /* Verify connectivity. */ 371 ASSERT_EQ (NULL, entry->preds); 372 ASSERT_EQ (1, entry->succs->length ()); 373 374 edge from_entry_to_bb2 = (*entry->succs)[0]; 375 ASSERT_EQ (entry, from_entry_to_bb2->src); 376 ASSERT_EQ (bb2, from_entry_to_bb2->dest); 377 378 ASSERT_EQ (1, bb2->preds->length ()); 379 ASSERT_EQ (from_entry_to_bb2, (*bb2->preds)[0]); 380 ASSERT_EQ (1, bb2->succs->length ()); 381 382 edge from_bb2_to_exit = (*bb2->succs)[0]; 383 ASSERT_EQ (bb2, from_bb2_to_exit->src); 384 ASSERT_EQ (exit, from_bb2_to_exit->dest); 385 386 ASSERT_EQ (1, exit->preds->length ()); 387 ASSERT_EQ (from_bb2_to_exit, (*exit->preds)[0]); 388 ASSERT_EQ (NULL, exit->succs); 389 } 390 391 /* As above, but additionally verify the gimple statements are sane. */ 392 393 static void 394 verify_three_block_gimple_cfg (function *fun) 395 { 396 verify_three_block_cfg (fun); 397 398 /* The "fake" basic blocks should be flagged as gimple, but with have no 399 statements. */ 400 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (fun); 401 ASSERT_TRUE (entry != NULL); 402 ASSERT_EQ (0, entry->flags & BB_RTL); 403 ASSERT_EQ (NULL, bb_seq (entry)); 404 405 basic_block exit = EXIT_BLOCK_PTR_FOR_FN (fun); 406 ASSERT_TRUE (exit != NULL); 407 ASSERT_EQ (0, entry->flags & BB_RTL); 408 ASSERT_EQ (NULL, bb_seq (exit)); 409 410 /* The "real" basic block should be flagged as gimple, and have one 411 or more statements. */ 412 basic_block bb2 = get_real_block (fun); 413 ASSERT_TRUE (bb2 != NULL); 414 ASSERT_EQ (0, entry->flags & BB_RTL); 415 ASSERT_TRUE (bb_seq (bb2) != NULL); 416 } 417 418 /* As above, but additionally verify the RTL insns are sane. */ 419 420 void 421 verify_three_block_rtl_cfg (function *fun) 422 { 423 verify_three_block_cfg (fun); 424 425 /* The "fake" basic blocks should be flagged as RTL, but with no 426 insns. */ 427 basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (fun); 428 ASSERT_TRUE (entry != NULL); 429 ASSERT_EQ (BB_RTL, entry->flags & BB_RTL); 430 ASSERT_EQ (NULL, BB_HEAD (entry)); 431 432 basic_block exit = EXIT_BLOCK_PTR_FOR_FN (fun); 433 ASSERT_TRUE (exit != NULL); 434 ASSERT_EQ (BB_RTL, exit->flags & BB_RTL); 435 ASSERT_EQ (NULL, BB_HEAD (exit)); 436 437 /* The "real" basic block should be flagged as RTL, and have one 438 or more insns. */ 439 basic_block bb2 = get_real_block (fun); 440 ASSERT_TRUE (bb2 != NULL); 441 ASSERT_EQ (BB_RTL, bb2->flags & BB_RTL); 442 ASSERT_TRUE (BB_HEAD (bb2) != NULL); 443 } 444 445 /* Test converting our trivial function: 446 int test_fn (void) { return 42; } 447 to gimple form. */ 448 449 static void 450 test_gimplification () 451 { 452 tree fndecl = build_trivial_generic_function (); 453 454 /* Convert to gimple: */ 455 gimplify_function_tree (fndecl); 456 457 /* Verify that we got gimple out of it. */ 458 459 /* The function is now in GIMPLE form but the CFG has not been 460 built yet. */ 461 462 /* We should have a struct function for the decl. */ 463 function *fun = DECL_STRUCT_FUNCTION (fndecl); 464 ASSERT_TRUE (fun != NULL); 465 ASSERT_EQ (fndecl, fun->decl); 466 467 /* We expect a GIMPLE_BIND, with two gimple statements within it: 468 tmp = 42; 469 return tmp; */ 470 471 gimple_seq seq_fn_body = gimple_body (fndecl); 472 ASSERT_TRUE (seq_fn_body != NULL); 473 gimple *bind_stmt = gimple_seq_first_stmt (seq_fn_body); 474 ASSERT_EQ (GIMPLE_BIND, gimple_code (bind_stmt)); 475 ASSERT_EQ (NULL, bind_stmt->next); 476 477 gimple_seq seq_bind_body = gimple_bind_body (as_a <gbind *> (bind_stmt)); 478 479 /* Verify that we have the 2 statements we expect. */ 480 ASSERT_TRUE (seq_bind_body != NULL); 481 gimple *stmt1 = gimple_seq_first_stmt (seq_bind_body); 482 ASSERT_TRUE (stmt1 != NULL); 483 ASSERT_EQ (GIMPLE_ASSIGN, gimple_code (stmt1)); 484 gimple *stmt2 = stmt1->next; 485 ASSERT_TRUE (stmt2 != NULL); 486 ASSERT_EQ (stmt1, stmt2->prev); 487 ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt2)); 488 } 489 490 /* Test of building a CFG for a function in high gimple form. */ 491 492 static void 493 test_building_cfg () 494 { 495 /* Construct a trivial function, and gimplify it: */ 496 tree fndecl = build_trivial_high_gimple_function (); 497 function *fun = DECL_STRUCT_FUNCTION (fndecl); 498 ASSERT_TRUE (fun != NULL); 499 500 /* Build a CFG. */ 501 build_cfg (fndecl); 502 503 /* The CFG-building code constructs a 4-block cfg (with 504 ENTRY and EXIT): 505 test_fn () 506 { 507 <bb 2>: 508 D.65 = 42; 509 510 <bb 3>: 511 return D.65; 512 } 513 and then ought to merge blocks 2 and 3 in cleanup_tree_cfg. 514 515 Hence we should end up with a simple 3-block cfg, the two "fake" ones, 516 and a "real" one: 517 [ENTRY] -> [block2] -> [EXIT] 518 with code like this: 519 test_fn () 520 { 521 <bb 2>: 522 D.56 = 42; 523 return D.56; 524 } 525 */ 526 verify_three_block_gimple_cfg (fun); 527 528 /* Verify the statements within the "real" block. */ 529 basic_block bb2 = get_real_block (fun); 530 gimple *stmt_a = gimple_seq_first_stmt (bb_seq (bb2)); 531 ASSERT_EQ (GIMPLE_ASSIGN, gimple_code (stmt_a)); 532 gimple *stmt_b = stmt_a->next; 533 ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt_b)); 534 ASSERT_EQ (NULL, stmt_b->next); 535 } 536 537 /* Test of conversion of gimple to SSA form. */ 538 539 static void 540 test_conversion_to_ssa () 541 { 542 /* As above, construct a trivial function, gimplify it, and build a CFG: */ 543 tree fndecl = build_trivial_high_gimple_function (); 544 function *fun = DECL_STRUCT_FUNCTION (fndecl); 545 ASSERT_TRUE (fun != NULL); 546 build_cfg (fndecl); 547 548 convert_to_ssa (fndecl); 549 550 verify_three_block_gimple_cfg (fun); 551 552 /* For out trivial test function we should now have something like 553 this: 554 test_fn () 555 { 556 <bb 2>: 557 _1 = 42; 558 return _1; 559 } 560 */ 561 basic_block bb2 = get_real_block (fun); 562 gimple *stmt_a = gimple_seq_first_stmt (bb_seq (bb2)); 563 ASSERT_EQ (GIMPLE_ASSIGN, gimple_code (stmt_a)); 564 565 gimple *stmt_b = stmt_a->next; 566 ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt_b)); 567 ASSERT_EQ (NULL, stmt_b->next); 568 569 greturn *return_stmt = as_a <greturn *> (stmt_b); 570 ASSERT_EQ (SSA_NAME, TREE_CODE (gimple_return_retval (return_stmt))); 571 } 572 573 /* Test of expansion from gimple-ssa to RTL. */ 574 575 static void 576 test_expansion_to_rtl () 577 { 578 /* As above, construct a trivial function, gimplify it, build a CFG, 579 and convert to SSA: */ 580 tree fndecl = build_trivial_high_gimple_function (); 581 function *fun = DECL_STRUCT_FUNCTION (fndecl); 582 ASSERT_TRUE (fun != NULL); 583 build_cfg (fndecl); 584 convert_to_ssa (fndecl); 585 586 /* We need a cgraph_node for it. */ 587 cgraph_node::get_create (fndecl); 588 /* Normally, cgraph_node::expand () would call 589 init_function_start (and a bunch of other stuff), 590 and invoke the expand pass, but it also runs 591 all of the other passes. So just do the minimum 592 needed to get from gimple-SSA to RTL. */ 593 rtl_opt_pass *expand_pass = make_pass_expand (g); 594 push_cfun (fun); 595 init_function_start (fndecl); 596 expand_pass->execute (fun); 597 pop_cfun (); 598 delete expand_pass; 599 600 /* On x86_64, I get this: 601 (note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) 602 (note 2 3 5 2 NOTE_INSN_FUNCTION_BEG) 603 (insn 5 2 6 2 (set (reg:SI 87 [ D.59 ]) 604 (const_int 42 [0x2a])) -1 (nil)) 605 (insn 6 5 10 2 (set (reg:SI 88 [ <retval> ]) 606 (reg:SI 87 [ D.59 ])) -1 (nil)) 607 (insn 10 6 11 2 (set (reg/i:SI 0 ax) 608 (reg:SI 88 [ <retval> ])) -1 (nil)) 609 (insn 11 10 0 2 (use (reg/i:SI 0 ax)) -1 (nil)) 610 611 On cr16-elf I get this: 612 (note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) 613 (insn 2 4 3 2 (set (reg:SI 24) 614 (reg/f:SI 16 virtual-incoming-args)) -1 615 (nil)) 616 (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG) 617 (insn 6 3 7 2 (set (reg:HI 22 [ _1 ]) 618 (const_int 42 [0x2a])) -1 619 (nil)) 620 (insn 7 6 11 2 (set (reg:HI 23 [ <retval> ]) 621 (reg:HI 22 [ _1 ])) -1 622 (nil)) 623 (insn 11 7 12 2 (set (reg/i:HI 0 r0) 624 (reg:HI 23 [ <retval> ])) -1 625 (nil)) 626 (insn 12 11 0 2 (use (reg/i:HI 0 r0)) -1 627 (nil)). */ 628 verify_three_block_rtl_cfg (fun); 629 630 /* Verify as much of the RTL as we can whilst avoiding 631 target-specific behavior. */ 632 basic_block bb2 = get_real_block (fun); 633 634 /* Expect a NOTE_INSN_BASIC_BLOCK... */ 635 rtx_insn *insn = BB_HEAD (bb2); 636 ASSERT_TRUE (insn != NULL); 637 ASSERT_EQ (NOTE, insn->code); 638 ASSERT_EQ (NOTE_INSN_BASIC_BLOCK, NOTE_KIND (insn)); 639 ASSERT_EQ (bb2, NOTE_BASIC_BLOCK (insn)); 640 641 /* ...etc; any further checks are likely to over-specify things 642 and run us into target dependencies. */ 643 644 /* Verify that print_rtl_function is sane. */ 645 named_temp_file tmp_out (".rtl"); 646 FILE *outfile = fopen (tmp_out.get_filename (), "w"); 647 print_rtx_function (outfile, fun, true); 648 fclose (outfile); 649 650 char *dump = read_file (SELFTEST_LOCATION, tmp_out.get_filename ()); 651 ASSERT_STR_CONTAINS (dump, "(function \"test_fn\"\n"); 652 ASSERT_STR_CONTAINS (dump, " (insn-chain\n"); 653 ASSERT_STR_CONTAINS (dump, " (block 2\n"); 654 ASSERT_STR_CONTAINS (dump, " (edge-from entry (flags \"FALLTHRU\"))\n"); 655 ASSERT_STR_CONTAINS (dump, " (cinsn "); /* ...etc. */ 656 ASSERT_STR_CONTAINS (dump, " (edge-to exit (flags \"FALLTHRU\"))\n"); 657 ASSERT_STR_CONTAINS (dump, " ) ;; block 2\n"); 658 ASSERT_STR_CONTAINS (dump, " ) ;; insn-chain\n"); 659 ASSERT_STR_CONTAINS (dump, " (crtl\n"); 660 ASSERT_STR_CONTAINS (dump, " ) ;; crtl\n"); 661 ASSERT_STR_CONTAINS (dump, ") ;; function \"test_fn\"\n"); 662 663 free (dump); 664 free_after_compilation (fun); 665 } 666 667 /* Run all of the selftests within this file. */ 668 669 void 670 function_tests_c_tests () 671 { 672 test_fndecl_int_void (); 673 test_fndecl_float_intchar (); 674 test_gimplification (); 675 test_building_cfg (); 676 test_conversion_to_ssa (); 677 test_expansion_to_rtl (); 678 } 679 680 } // namespace selftest 681 682 #endif /* #if CHECKING_P */ 683