From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20377 invoked by alias); 7 Aug 2004 05:43:07 -0000 Mailing-List: contact glibc-bugs-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: glibc-bugs-owner@sources.redhat.com Received: (qmail 20331 invoked by uid 48); 7 Aug 2004 05:43:02 -0000 Date: Sat, 07 Aug 2004 05:43:00 -0000 From: "eggert at gnu dot org" To: glibc-bugs@sources.redhat.com Message-ID: <20040807054259.309.eggert@gnu.org> Reply-To: sourceware-bugzilla@sources.redhat.com Subject: [Bug libc/309] New: fwrite_unlocked bogus warning and results with gcc -O X-Bugzilla-Reason: CC X-SW-Source: 2004-08/txt/msg00043.txt.bz2 List-Id: The impetus for this bug report is that I've lately been getting these annoying warnings for a while, when compiling with gcc -O: foobar.c:108: warning: signed and unsigned type in conditional expression Here's the relevant source line: fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); The warning goes away if I don't use -O. I tracked it down to the fact that fread_unlocked and fwrite_unlocked don't properly evaluate their arguments and assume their arguments are of the correct type. In my case the type was ptrdiff_t rather than size_t. Here's an amusing sample program illustrating the problem: #include int main (void) { int buf[10]; double d = fwrite_unlocked (buf, 0, -0.0, stdout); if (1 / d < 0) fprintf (stderr, "returned %.17g! should have returned zero\n", d); buf[0] = 123456; fread_unlocked (buf, sizeof *buf, 0.5, stdin); if (buf[0] != 123456) fprintf (stderr, "modified the buffer; should have left it alone!\n"); return 0; } Here's what happens when I compile it with "gcc -O" and run it: $ echo sdafasdfsadfasdfsadfdsa | ./a.out returned -0! should have returned zero modified the buffer; should have left it alone! The output should be empty. Here's a patch to libio/bits/stdio.h: 2004-08-06 Paul Eggert * libio/bits/stdio.h (fread_unlocked, fwrite_unlocked) [defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__]: Don't assume that arguments are already of the proper type. --- libio/bits/stdio.h.~1.9.~ 2003-05-10 01:25:21 -0700 +++ libio/bits/stdio.h 2004-08-06 22:12:08 -0700 @@ -128,41 +128,45 @@ ferror_unlocked (FILE *__stream) __THROW #if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__ /* Perform some simple optimizations. */ # define fread_unlocked(ptr, size, n, stream) \ - (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \ - && (size_t) ((size) * (n)) <= 8 && (size) != 0) \ - ? ({ char *__ptr = (char *) (ptr); \ - FILE *__stream = (stream); \ - size_t __cnt; \ - for (__cnt = (size) * (n); __cnt > 0; --__cnt) \ - { \ - int __c = _IO_getc_unlocked (__stream); \ - if (__c == EOF) \ - break; \ - *__ptr++ = __c; \ - } \ - ((size_t) ((size) * (n)) - __cnt) / (size); }) \ - : (((__builtin_constant_p (size) && (size) == 0) \ - || (__builtin_constant_p (n) && (n) == 0)) \ - /* Evaluate all parameters once. */ \ - ? ((void) (ptr), (void) (stream), (void) (size), \ - (void) (n), 0) \ - : fread_unlocked (ptr, size, n, stream)))) + (__extension__ ({ void *__ptr = (ptr); \ + size_t __size = (size); \ + size_t __n = (n); \ + FILE *__stream = (stream); \ + ((__builtin_constant_p (size) && __builtin_constant_p (n) \ + && __size * __n <= 8 && __size != 0) \ + ? ({ size_t __cnt; \ + char *__cptr = __ptr; \ + for (__cnt = __size * __n; __cnt > 0; --__cnt) \ + { \ + int __c = _IO_getc_unlocked (__stream); \ + if (__c == EOF) \ + break; \ + *__cptr++ = __c; \ + } \ + (__size * __n - __cnt) / __size; }) \ + : ((__builtin_constant_p (size) && __size == 0) \ + || (__builtin_constant_p (n) && __n == 0)) \ + ? __n \ + : fread_unlocked (__ptr, __size, __n, __stream)); })) # define fwrite_unlocked(ptr, size, n, stream) \ - (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \ - && (size_t) ((size) * (n)) <= 8 && (size) != 0) \ - ? ({ const char *__ptr = (const char *) (ptr); \ - FILE *__stream = (stream); \ - size_t __cnt; \ - for (__cnt = (size) * (n); __cnt > 0; --__cnt) \ - if (_IO_putc_unlocked (*__ptr++, __stream) == EOF) \ - break; \ - ((size_t) ((size) * (n)) - __cnt) / (size); }) \ - : (((__builtin_constant_p (size) && (size) == 0) \ - || (__builtin_constant_p (n) && (n) == 0)) \ - /* Evaluate all parameters once. */ \ - ? ((void) (ptr), (void) (stream), (void) (size), n) \ - : fwrite_unlocked (ptr, size, n, stream)))) + (__extension__ ({ const void *__ptr = (ptr); \ + size_t __size = (size); \ + size_t __n = (n); \ + FILE *__stream = (stream); \ + ((__builtin_constant_p (size) && __builtin_constant_p (n) \ + && __size * __n <= 8 && __size != 0) \ + ? ({ size_t __cnt; \ + const char *__cptr = __ptr; \ + for (__cnt = __size * __n; __cnt > 0; --__cnt) \ + if (_IO_putc_unlocked (*__cptr++, __stream) \ + == EOF) \ + break; \ + (__size * __n - __cnt) / __size; }) \ + : ((__builtin_constant_p (size) && __size == 0) \ + || (__builtin_constant_p (n) && __n == 0)) \ + ? __n \ + : fwrite_unlocked (__ptr, __size, __n, __stream)); })) #endif /* Define helper macro. */ -- Summary: fwrite_unlocked bogus warning and results with gcc -O Product: glibc Version: 2.3.3 Status: NEW Severity: normal Priority: P2 Component: libc AssignedTo: gotom at debian dot or dot jp ReportedBy: eggert at gnu dot org CC: glibc-bugs at sources dot redhat dot com GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://sources.redhat.com/bugzilla/show_bug.cgi?id=309 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is.