https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46476
--- Comment #18 from Richard Biener <rguenth at gcc dot gnu.org> --- We can warn at CFG construction time. Note the ??? though, we'd want to improve here to avoid duplicate diagnostics. Tricky cases: /* Unreachable region entry has a predecessor (backedge). */ void foo() { return; for (int i = 0; i < 5; ++i) ; } /* Unreachable region not backwards reachable from exit. */ void bar1() { return; __builtin_abort (); } void bar2() { return ; for (;;); } /* Unreachable code in if (0) block. */ void baz(int *p) { if (0) { return; *p = 0; } } bootstrap with the prototype currently fails in libgomp: /home/rguenther/src/trunk/libgomp/oacc-plugin.c: In function 'GOMP_PLUGIN_acc_default_dim': /home/rguenther/src/trunk/libgomp/oacc-plugin.c:65:7: error: statement is not reachable [-Werror] 65 | return -1; | ^~~~~~ /home/rguenther/src/trunk/libgomp/oacc-profiling.c: In function 'acc_prof_register': /home/rguenther/src/trunk/libgomp/oacc-profiling.c:354:7: error: statement is not reachable [-Werror] 354 | __builtin_unreachable (); | ^~~~~~~~~~~~~~~~~~~~~ /home/rguenther/src/trunk/libgomp/oacc-profiling.c: In function 'acc_prof_unregister': /home/rguenther/src/trunk/libgomp/oacc-profiling.c:475:7: error: statement is not reachable [-Werror] 475 | __builtin_unreachable (); | ^~~~~~~~~~~~~~~~~~~~~ the latter two are an issue with inital CFG construction I think, where group_case_labels turns void bar (foo x) { <bb 2> : switch (x) <default: <L2>, case 0: <L0>, case 1: <L1>> <bb 3> : <L0>: goto <L2>; <bb 4> : <L1>: __builtin_unreachable (); <bb 5> : <L2>: return; into the following with BB 4 now unreachable. void bar (foo x) { <bb 2> : switch (x) <default: <L2>, case 0: <L0>> <bb 3> : <L0>: goto <L2>; <bb 4> : <L1>: __builtin_unreachable (); <bb 5> : <L2>: return; The C++ FE also warns about the implicit return in main when there's a preceeding one (the C frontend "appropriately" assigns an internal location which supresses the warning). diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index b3a27bcd17c..64ab2607c56 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -242,7 +242,8 @@ build_gimple_cfg (gimple_seq seq) /* Group case nodes to reduce the number of edges. We do this after cleaning up dead labels because otherwise we miss a lot of obvious case merging opportunities. */ - group_case_labels (); + /* ??? This interferes with unreachable code diagnostics. */ + //group_case_labels (); /* Create the edges of the flowgraph. */ discriminator_per_locus = new hash_table<locus_discrim_hasher> (13); @@ -374,6 +375,24 @@ execute_build_cfg (void) fprintf (dump_file, "Scope blocks:\n"); dump_scope_blocks (dump_file, dump_flags); } + + find_unreachable_blocks (); + basic_block bb; + FOR_EACH_BB_FN (bb, cfun) + if (!(bb->flags & BB_REACHABLE)) + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); + gsi_next (&gsi)) + { + if ((LOCATION_LOCUS (gimple_location (gsi_stmt (gsi))) + > BUILTINS_LOCATION) + && !gimple_no_warning_p (gsi_stmt (gsi))) + warning_at (gimple_location (gsi_stmt (gsi)), 0, + "statement is not reachable"); + /* ??? Mark blocks reachable from here. And even better make + sure to process entries to unreachable regions first. */ + break; + } + cleanup_tree_cfg (); bb_to_omp_idx.release ();