Bug 61846 - gcc assumes errno might be negative and issues unnecessary warning
Summary: gcc assumes errno might be negative and issues unnecessary warning
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2014-07-18 20:46 UTC by Zbigniew Jędrzejewski-Szmek
Modified: 2021-09-13 00:08 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
sample program (277 bytes, text/x-csrc)
2014-07-18 20:46 UTC, Zbigniew Jędrzejewski-Szmek
Details
compilation logs (1.37 KB, text/plain)
2014-07-18 20:48 UTC, Zbigniew Jędrzejewski-Szmek
Details
processed source (9.48 KB, text/plain)
2014-07-18 20:49 UTC, Zbigniew Jędrzejewski-Szmek
Details
sample program (266 bytes, text/plain)
2014-07-18 20:51 UTC, Zbigniew Jędrzejewski-Szmek
Details

Note You need to log in before you can comment on or make changes to this bug.
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" ?