Created attachment 29942 [details] C source code I just tried to compile the package jam-2.5-14 on gcc-4.9 trunk dated 20130425 on an AMD x86_64 box. The compiler said execunix.c: In function 'execcmd': execunix.c:322:1: error: control flow in the middle of basic block 10 } ^ execunix.c:322:1: error: control flow in the middle of basic block 10 execunix.c:322:1: error: control flow in the middle of basic block 10 execunix.c:322:1: internal compiler error: verify_flow_info failed 0x5f9ae1 verify_flow_info() ../../src/trunk/gcc/cfghooks.c:260 0x91dec4 cleanup_tree_cfg_noloop ../../src/trunk/gcc/tree-cfgcleanup.c:693 0x91dec4 cleanup_tree_cfg() ../../src/trunk/gcc/tree-cfgcleanup.c:742 0x84be64 execute_function_todo ../../src/trunk/gcc/passes.c:1921 0x84c7e7 execute_todo ../../src/trunk/gcc/passes.c:1996 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. Preprocessed source code attached. Flag -O2 required.
Confirmed.
Started with http://gcc.gnu.org/r198192
Ok, I think I reduced this issue to this: /* PR tree-optimization/57075 */ /* { dg-do compile } */ /* { dg-options "-O2" } */ extern int baz (void) __attribute__ ((returns_twice)); int __attribute__ ((__leaf__)) foo (void) { return __builtin_printf ("$"); } void bar () { foo (); baz (); }
b.c: In function ‘bar’: b.c:17:1: error: control flow in the middle of basic block 2 <bb 2>: _5 = __builtin_printf ("$"); D.1727 = _5;
Ok, that's because printf is considered a possible caller of longjmp but inlining doesn't split the block before handling the return. We need to possibly split blocks dependent on stmt_ends_bb_p which depends on function context. Similar testcase can be constructed with non-local gotos, broken before r198192.
Generally fixup_cfg () is used for this kind of needed adjustments.
(In reply to comment #5) > Ok, that's because printf is considered a possible caller of longjmp but > inlining doesn't split the block before handling the return. IIUC, stmt_ends_bb_p then should return true for D.1722 = __builtin_printf ("$"); shouldn't it? It returns false for that stmt.
On Fri, 26 Apr 2013, mpolacek at gcc dot gnu.org wrote: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57075 > > --- Comment #7 from Marek Polacek <mpolacek at gcc dot gnu.org> 2013-04-26 12:03:00 UTC --- > (In reply to comment #5) > > Ok, that's because printf is considered a possible caller of longjmp but > > inlining doesn't split the block before handling the return. > > IIUC, stmt_ends_bb_p then should return true for > D.1722 = __builtin_printf ("$"); > shouldn't it? > > It returns false for that stmt. The return value is dependent on function context :/
I have a patch.
Author: rguenth Date: Mon Apr 29 15:06:18 2013 New Revision: 198423 URL: http://gcc.gnu.org/viewcvs?rev=198423&root=gcc&view=rev Log: 2013-04-29 Richard Biener <rguenther@suse.de> PR middle-end/57075 * tree-inline.c (copy_edges_for_bb): Still split the bbs, even if not adding abnormal edges for calls that can make abnormal gotos. * gcc.dg/torture/pr57075.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr57075.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-inline.c