This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
miscompilation with current gcc on x86
- To: gcc-bugs at gcc dot gnu dot org
- Subject: miscompilation with current gcc on x86
- From: Ulrich Drepper <drepper at redhat dot com>
- Date: 22 Mar 2000 14:01:15 -0800
- Reply-To: drepper at cygnus dot com (Ulrich Drepper)
The appended code compiled with the current gcc (this bugs exists for
at least a week now) produces strange results. It's supposed to write
to stdout the string "Hello World " but it does not write anything.
The problem is that the inlined function `f' modifies the variable
`format' in function `bar'. Therefore end - (const unsigned char *) format
in the `write' call leads to zero. If you look at the code, the compiler
actually pushes the constant zero.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
68: 83 c4 10 add $0x10,%esp
6b: 39 c3 cmp %eax,%ebx
6d: 75 b1 jne 20 <bar+0x20>
end = f ((const unsigned char *) format, &m);
return write (1, format, end - (const unsigned char *) format);
6f: 83 ec 04 sub $0x4,%esp
72: 6a 00 push $0x0 <--------------- LENGTH
74: 56 push %esi
75: 6a 01 push $0x1
77: e8 fc ff ff ff call 78 <bar+0x78>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compile with
gcc -O2 -march=i686 -mcpu=i686 -o z z.c -g
and enjoy.
--
---------------. drepper at gnu.org ,-. 1325 Chesapeake Terrace
Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA
Red Hat `--' drepper at redhat.com `------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <ctype.h>
#include <stdlib.h>
#include <wchar.h>
static inline unsigned const char *
f (unsigned const char *format, mbstate_t *ps)
{
while (*format != '\0' && *format != '%')
{
int len;
/* Remove any hints of a wrong encoding. */
ps->count = 0;
if (! isascii (*format) && (len = mbrlen (format, MB_CUR_MAX, ps)) > 0)
format += len;
else
++format;
}
return format;
}
int
bar (const char *format)
{
const unsigned char *end;
mbstate_t m;
memset (&m, '\0', sizeof m);
end = f ((const unsigned char *) format, &m);
return write (1, format, end - (const unsigned char *) format);
}
int
main (void)
{
return bar ("Hello World %d");
}