diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 81b80dff928b..f87dbac34baf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-12-23 Eric Botcazou + + PR optimization/13394 + * toplev.c (rest_of_compilation): Move call to + check_function_return_warnings right after the sibcall + optimization pass. + 2003-12-23 Eric Botcazou PR c/13382 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf06beaf5afa..9095c8a4dc58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-12-23 Eric Botcazou + + * gcc.dg/noreturn-7.c: New test. + 2003-12-23 Eric Botcazou * gcc.dg/null-pointer-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/noreturn-7.c b/gcc/testsuite/gcc.dg/noreturn-7.c new file mode 100644 index 000000000000..1d94a7ccea59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/noreturn-7.c @@ -0,0 +1,42 @@ +/* PR optimization/13394 */ +/* Origin: Carlo Wood */ + +/* Verify that a bogus "function does return" warning is not issued + in presence of tail recursion within a noreturn function. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -Wreturn-type -Wmissing-noreturn" } */ + + +void f(void) __attribute__ ((__noreturn__)); +void _exit(int status) __attribute__ ((__noreturn__)); + +int z = 0; + +void g() +{ + if (++z > 10) + _exit(0); + g(); +} /* { dg-warning "possible candidate" } */ + +void f() +{ + if (++z > 10) + _exit(0); + f(); +} /* { dg-bogus "does return" } */ + +int h() +{ + if (++z > 10) + _exit(0); + return h(); +} /* { dg-bogus "end of non-void function" } */ + +int k() +{ + if (++z > 10) + _exit(0); + k(); +} /* { dg-warning "end of non-void function" } */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 2ed4c31ac5c6..7d01eb6dc1c8 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -3144,10 +3144,6 @@ rest_of_compilation (tree decl) delete_unreachable_blocks (); - /* We have to issue these warnings now already, because CFG cleanups - further down may destroy the required information. */ - check_function_return_warnings (); - /* Turn NOTE_INSN_PREDICTIONs into branch predictions. */ if (flag_guess_branch_prob) { @@ -3159,6 +3155,14 @@ rest_of_compilation (tree decl) if (flag_optimize_sibling_calls) rest_of_handle_sibling_calls (insns); + /* We have to issue these warnings now already, because CFG cleanups + further down may destroy the required information. However, this + must be done after the sibcall optimization pass because the barrier + emitted for noreturn calls that are candidate for the optimization + is folded into the CALL_PLACEHOLDER until after this pass, so the + CFG is inaccurate. */ + check_function_return_warnings (); + timevar_pop (TV_JUMP); insn_locators_initialize ();