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