Bug 42674 - [4.4/4.5 Regression] Bogus "no return statement in function returning non-void" warning
Summary: [4.4/4.5 Regression] Bogus "no return statement in function returning non-voi...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.5.0
: P2 normal
Target Milestone: 4.4.3
Assignee: Jakub Jelinek
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2010-01-09 19:10 UTC by Dave Korn
Modified: 2010-01-14 23:19 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.3.4
Known to fail: 4.4.2 4.5.0
Last reconfirmed: 2010-01-13 17:38:25


Attachments
gcc45-pr42674.patch (701 bytes, patch)
2010-01-13 18:07 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Korn 2010-01-09 19:10:39 UTC
Simple testcase not even worth attaching preprocessed source for, using HEAD@155680.  Note that this only arises in C++, not when compiled as C:

------------------------------------------------------------------------
$ cat badwarn.cpp

extern void bar (void);
int foo (void) __attribute__ ((__noreturn__));

int
foo (void)
{
  while (1)
  {
    bar ();
  }
}

$ g++-4 -c badwarn.cpp  -Wall
badwarn.cpp: In function 'int foo()':
badwarn.cpp:12:1: warning: no return statement in function returning non-void
------------------------------------------------------------------------

Discussed on the list at http://gcc.gnu.org/ml/gcc/2010-01/threads.html#00180; Ross Smith identified this as a regression as it does not arise with 4.0.1, 4.2.1 and 4.3.4, and HJ tracked it to r.138140:

http://gcc.gnu.org/ml/gcc-cvs/2008-07/msg00852.html
Comment 1 Richard Biener 2010-01-10 22:08:30 UTC
We should probably warn instead "function returning non-void declared with attribute noreturn".
Comment 2 Dave Korn 2010-01-11 00:23:55 UTC
(In reply to comment #1)
> We should probably warn instead "function returning non-void declared with
> attribute noreturn".
> 

I think not; I don't see why you should be obliged to change the prototype of a function in order to tell the compiler that it does not return, and it's very often the case that you can't control the prototype of a function.  The particular example this came from was a thread function that was spawned by pthread_create, so it had to have an int return type, even though it had a while (1) loop that meant it never would, in fact return; I wanted to tell the compiler that.

Note however that I only included noreturn to show that it doesn't suppress the warning; the warning arises even without it (as I mentioned in the list thread but see I forgot to mention earlier here; sorry).  The real problem is that it shouldn't complain about a missing return statement if there's no possible way of exiting the function.
Comment 3 Manuel López-Ibáñez 2010-01-11 18:17:49 UTC
There must be some reason why this:

  if (warn_return_type
      && TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
      && !current_function_returns_value && !current_function_returns_null
      /* Don't complain if we are no-return.  */
      && !current_function_returns_abnormally
      /* Don't warn for main().  */
      && !MAIN_NAME_P (DECL_NAME (fndecl))
      /* Or if they didn't actually specify a return type.  */
      && !C_FUNCTION_IMPLICIT_INT (fndecl)
      /* Normally, with -Wreturn-type, flow will complain, but we might
         optimize out static functions.  */
      && !TREE_PUBLIC (fndecl))
    {
      warning (OPT_Wreturn_type,
	       "no return statement in function returning non-void");
      TREE_NO_WARNING (fndecl) = 1;
    }

is not triggered in C (even without the __noreturn__?), whereas this is:

  if (warn_return_type
      && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
      && !dependent_type_p (TREE_TYPE (fntype))
      && !current_function_returns_value && !current_function_returns_null
      /* Don't complain if we abort or throw.  */
      && !current_function_returns_abnormally
      && !DECL_NAME (DECL_RESULT (fndecl))
      && !TREE_NO_WARNING (fndecl)
      /* Structor return values (if any) are set by the compiler.  */
      && !DECL_CONSTRUCTOR_P (fndecl)
      && !DECL_DESTRUCTOR_P (fndecl))
    {
      warning (OPT_Wreturn_type,
 	       "no return statement in function returning non-void");
      TREE_NO_WARNING (fndecl) = 1;
    }

I think this may be actually two bugs, one is the noreturn which should set current_function_returns_abnormally to true, so no warning. Another is that the function is not marked as never returning because of the infinite loop.
Comment 4 Dave Korn 2010-01-11 19:07:59 UTC
(In reply to comment #3)
> (even without the __noreturn__?)

  Yes, even without.

> I think this may be actually two bugs, one is the noreturn which should set
> current_function_returns_abnormally to true, so no warning. Another is that the
> function is not marked as never returning because of the infinite loop.
 
  Sounds right to me.  Ok to leave them both under this one PR, or should we separate them?
Comment 5 Jakub Jelinek 2010-01-13 17:38:25 UTC
The difference between C and C++ FE is just r138140, i.e. the && !TREE_PUBLIC check.
Just try
extern void bar (void);
static int foo (void) __attribute__ ((__noreturn__, __used__));

static int
foo (void)
{
  while (1)
    bar ();
}

which warns both in C and C++.  I guess we should just add !TREE_THIS_VOLATILE (fndecl) check to both C and C++ FE.
Comment 6 Jakub Jelinek 2010-01-13 18:07:05 UTC
Created attachment 19578 [details]
gcc45-pr42674.patch

Patch I'm going to bootstrap/regtest.
Comment 7 Jakub Jelinek 2010-01-14 22:44:13 UTC
Subject: Bug 42674

Author: jakub
Date: Thu Jan 14 22:43:56 2010
New Revision: 155920

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=155920
Log:
	PR middle-end/42674
	* c-decl.c (finish_function): Don't emit -Wreturn-type warnings in
	functions with noreturn attribute.

	* decl.c (finish_function): Don't emit -Wreturn-type warnings in
	functions with noreturn attribute.

	* c-c++-common/pr42674.c: New test.

Added:
    trunk/gcc/testsuite/c-c++-common/pr42674.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-decl.c
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Jakub Jelinek 2010-01-14 22:49:36 UTC
Subject: Bug 42674

Author: jakub
Date: Thu Jan 14 22:49:17 2010
New Revision: 155922

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=155922
Log:
	PR middle-end/42674
	* c-decl.c (finish_function): Don't emit -Wreturn-type warnings in
	functions with noreturn attribute.

	* decl.c (finish_function): Don't emit -Wreturn-type warnings in
	functions with noreturn attribute.

	* c-c++-common/pr42674.c: New test.

Added:
    branches/gcc-4_4-branch/gcc/testsuite/c-c++-common/pr42674.c
Modified:
    branches/gcc-4_4-branch/gcc/ChangeLog
    branches/gcc-4_4-branch/gcc/c-decl.c
    branches/gcc-4_4-branch/gcc/cp/ChangeLog
    branches/gcc-4_4-branch/gcc/cp/decl.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 9 Jakub Jelinek 2010-01-14 23:19:55 UTC
Fixed.