This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

miscompilation with current gcc on x86


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");
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]