Bug 61846

Summary: gcc assumes errno might be negative and issues unnecessary warning
Product: gcc Reporter: Zbigniew Jędrzejewski-Szmek <zbyszek>
Component: middle-endAssignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: sjames
Priority: P3 Keywords: diagnostic
Version: 4.9.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 114952    
Attachments: sample program
compilation logs
processed source
sample program

Description Zbigniew Jędrzejewski-Szmek 2014-07-18 20:46:15 UTC
Created attachment 33148 [details]
sample program

I see this a lot in systemd source code, where the convention is to return a negative integer on error. gcc warns as if errno could also be zero or negative after a system call, and warns about unitialized variables. Simplified example attached.

$ gcc -Wall -O3 -std=gnu99 -o readwarn readwarn.c 
readwarn.c: In function ‘main’:
readwarn.c:28:9: warning: ‘ans’ may be used uninitialized in this function [-Wmaybe-uninitialized]
         printf("ans: %d", ans);
         ^

POSIX states that errno values are positive [1], and read may sets errno, so it is safe to assume that if read() returned -1, errno must have a positive value.

If I replace 'return -errno' with 'return errno > 0 ? -errno : -EIO', the warning disappers.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html#tag_13_10
Comment 1 Zbigniew Jędrzejewski-Szmek 2014-07-18 20:48:53 UTC
Created attachment 33150 [details]
compilation logs
Comment 2 Zbigniew Jędrzejewski-Szmek 2014-07-18 20:49:36 UTC
Created attachment 33151 [details]
processed source
Comment 3 Zbigniew Jędrzejewski-Szmek 2014-07-18 20:51:28 UTC
Created attachment 33152 [details]
sample program
Comment 4 Andrew Pinski 2014-07-18 21:33:03 UTC
C99 also has this requirement.  But C89 did not.

>Values for errno are now required to be distinct positive values rather than 
> non-zero values. This change is for alignment with the ISO/IEC 9899:1999 
> standard.

So using -std=gnu99 should allow this to not be unitilaized except GCC has no way to know you are reading from errno just yet.
Comment 5 Zbigniew Jędrzejewski-Szmek 2014-07-23 12:23:33 UTC
(In reply to Andrew Pinski from comment #4)
> C99 also has this requirement.  But C89 did not.
The warnings are "best effort" anyway. So even if the standards did *not* say that, gcc could skip the warning since existing systems all work this way anyway.

I think it could make for a nice optimization, when compiling for C99, but that is not what I'm asking for atm.

> >Values for errno are now required to be distinct positive values rather than 
> > non-zero values. This change is for alignment with the ISO/IEC 9899:1999 
> > standard.
> 
> So using -std=gnu99 should allow this to not be unitilaized except GCC has
> no way to know you are reading from errno just yet.
Wouldn't it be a matter of annotating read() call with the sideffect of "return value >= 0 || errno > 0" ?