This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR optimization/13394


Hi,

This is a regression from GCC 3.2.x present on mainline and 3.3 branch.  The 
compiler emits a bogus return-related warning for the testcase.

The call to check_function_return_warnings in toplev.c was moved from after 
flow in GCC 3.2.x to right after RTL expansion.  This is not the best place, 
because the CFG may be inaccurate until after the sibcall optimization pass 
(the reason is stated in the patch).

The proposed fix is to call check_function_return_warnings right after the 
sibcall optimization pass.  The only adverse effect from 
check_function_return_warnings' viewpoint could be when a tail call is 
optimized into a tail recursion, thus apparently turning a function that 
returns into a function that doesn't.  But
- for the "function might be possible candidate for attribute `noreturn'" 
warning, this improves the situation (function #1)
- for the "`noreturn' function does return" warning, this improves the 
situation (and fixes the PR, function #2),
- for the "control reaches end of non-void function", this doesn't change 
anything since control now can't reach the end of the function at all 
(function #3).

Bootstrapped/regtested on i586-redhat-linux-gnu (mainline, except Ada).


2003-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR optimization/13394
        * toplev.c (rest_of_compilation): Move call to
	check_function_return_warnings right after the sibcall
	optimization pass.

2003-12-21  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * gcc.dg/noreturn-7.c: New test.


-- 
Eric Botcazou
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.851
diff -u -p -r1.851 toplev.c
--- toplev.c	18 Dec 2003 17:07:24 -0000	1.851
+++ toplev.c	21 Dec 2003 09:20:13 -0000
@@ -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)
     {
@@ -3158,6 +3154,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);
 
/* PR optimization/13394 */
/* Origin: Carlo Wood <carlo@gcc.gnu.org> */

/* 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" } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]