On 6 July 2015 at 12:00, Richard Biener <richard.guent...@gmail.com> wrote: > On Sun, Jul 5, 2015 at 2:07 PM, Prathamesh Kulkarni > <prathamesh.kulka...@linaro.org> wrote: >> Hi, >> Passing -dx causes segmentation fault: >> Test case: void f(void) {} >> >> ./test.c: In function 'f': >> ../test.c:3:1: internal compiler error: Segmentation fault >> } >> ^ >> 0xab6baf crash_signal >> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/toplev.c:366 >> 0x694b14 verify_flow_info() >> >> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/cfghooks.c:109 >> 0x9f7e64 execute_function_todo >> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/passes.c:1997 >> 0x9f86eb execute_todo >> /home/prathamesh.kulkarni/gnu-toolchain/src/gcc.git/gcc/passes.c:2042 >> >> Started with r210068. >> It looks like -dx causes cfun->cfg to be NULL, and hence the segfault >> in verify_flow_info(). >> The attached patch tries to fix it by adding a check to cfun->cfg before >> calling >> verify_flow_info() from execute_function_todo(). >> Bootstrapped and tested on x86_64-unknown-linux-gnu. >> OK for trunk ? > > No. We've checked cfun->curr_properties & PROP_cfg already. So whatever > is keeping that set but frees the CFG is the offender (and should > clear the flag). I think I have somewhat understood what's happening. -dx turns on flag rtl_dump_and_exit. pass_rest_of_compilation is gated on !rtl_dump_and_exit. Since rtl_dump_and_exit == 1 when -dx is passed, pass_rest_of_compilation and all the rtl passes inserted within pass_rest_of_compilation don't execute. One of these passes is pass_free_cfg which destorys PROP_cfg, but with -dx passed, this pass doesn't get executed and PROP_cfg remains set. Then pass_clean_state::execute() calls free_after_compilation(), which sets cfun->cfg = NULL. And hence after pass_clean_state finishes in execute_function_todo, we end up with cfun->cfg == NULL and CFG_prop set, which calls verify_flow_info() and we hit the segfault.
The following untested patch tries to fix this by clearing CFG_prop in free_after_compilation. Shall that be correct approach ? Thanks, Prathamesh > > Richard. > >> Thank you, >> Prathamesh
diff --git a/gcc/function.c b/gcc/function.c index 8134c4e..d540dc3 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -216,6 +216,7 @@ free_after_compilation (struct function *f) f->eh = NULL; f->machine = NULL; f->cfg = NULL; + f->curr_properties &= ~PROP_cfg; regno_reg_rtx = NULL; } diff --git a/gcc/testsuite/gcc.dg/dx-test.c b/gcc/testsuite/gcc.dg/dx-test.c new file mode 100644 index 0000000..579ccfb --- /dev/null +++ b/gcc/testsuite/gcc.dg/dx-test.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-dx" } */ + +void f(void) +{}