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
We should probably warn instead "function returning non-void declared with attribute noreturn".
(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.
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.
(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?
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.
Created attachment 19578 [details] gcc45-pr42674.patch Patch I'm going to bootstrap/regtest.
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
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
Fixed.