Bug 688111

Summary: Wrong warning with error(3) constant nonzero status
Product: [Fedora] Fedora Reporter: Matt McCutchen <matt>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 14CC: jakub
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-03-17 14:21:57 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Attachments:
Description Flags
Test case none

Description Matt McCutchen 2011-03-16 11:25:55 UTC
Created attachment 485711 [details]
Test case

Description of problem:
The magic that causes a call to error(3) with a constant nonzero status to be treated as noreturn seems to be broken.

Version-Release number of selected component (if applicable):
gcc-4.5.1-4.fc14.x86_64

How reproducible:
Always

Steps to Reproduce:
1. gcc -Wall -O2 error-test.c -o error-test
  
Actual results:
error-test.c: In function ‘main’:
error-test.c:5:1: warning: control reaches end of non-void function

Expected results:
No warning.

Comment 1 Jakub Jelinek 2011-03-17 12:43:01 UTC
That's not a bug, nothing tells gcc that error is conditionally noreturn, we only have an attribute to say if a function is noreturn and adding anything more complicated is a bad idea.  Simply add __builtin_unreachable (); after it if you want to avoid warnings, or add a return or for (;;); after it.

Comment 2 Matt McCutchen 2011-03-17 13:51:02 UTC
(In reply to comment #1)
> That's not a bug, nothing tells gcc that error is conditionally noreturn

/usr/include/bits/error.h:

/* If we know the function will never return make sure the compiler
   realizes that, too.  */
__extern_always_inline void
error (int __status, int __errnum, __const char *__format, ...)
{
  if (__builtin_constant_p (__status) && __status != 0)
    __error_noreturn (__status, __errnum, __format, __va_arg_pack ());
  else
    __error_alias (__status, __errnum, __format, __va_arg_pack ());
}

I seem to recall that this worked in a previous Fedora version.

Comment 3 Jakub Jelinek 2011-03-17 14:18:13 UTC
It never worked, tried 4.3/4.4/4.5/4.6/4.7.

Comment 4 Jakub Jelinek 2011-03-17 14:21:57 UTC
And, it can't work, because -Wreturn-type is handled way before even early inlining.  The above is just something that can help the optimizers in realizing it won't return, but definitely wasn't meant to avoid -Wreturn-type or similar early warnings.

Comment 5 Matt McCutchen 2011-03-17 16:02:44 UTC
Thanks for the explanation.