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