diff mbox

fix segfault in verify_flow_info() with -dx option

Message ID CAAgBjMn5SbD2U9BsMCQiXgUMz5WDT_5STs5m7YZueWnV5vPcsg@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni July 7, 2015, 12:42 a.m. UTC
On 6 July 2015 at 12:00, Richard Biener <richard.guenther@gmail.com> wrote:
> On Sun, Jul 5, 2015 at 2:07 PM, Prathamesh Kulkarni
> <prathamesh.kulkarni@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 mbox

Patch

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)
+{}