This is the mail archive of the gcc-prs@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]

optimization/487: bad code generated on i86 with optimization <synopsis of the problem (one line)>



>Number:         487
>Category:       optimization
>Synopsis:       bad code generated on i86 with optimization
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 23 22:46:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     scott snyder
>Release:        2.96  20000823 (experimental)
>Organization:
>Environment:
System: Linux karma 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
>Description:

  g++ miscompiles the following code with -O2:

---------------------------------------------
extern "C" int printf (...);
void foo (const char*) {}
void bar (const void*, int n) { printf ("%d\n", n); }

void
_S_pad_char(char* __olds,
            const int __newlen, const int __oldlen,
            int test, bool __testsign, bool __testhex)
{
  int __plen = static_cast<unsigned long>(__newlen - __oldlen); 
  char __pads[__plen];
  foo (__olds);

  char* __beg = __pads;
  char* __end = __pads;
  unsigned long __mod = 0;
  unsigned long __beglen = 0;

  if (test == 1)
  {
    __beglen = __oldlen;
  }
  else if (test == 2)
  {
    if (__testhex)
    {
      __beglen = __oldlen;
    }
    else if (__testsign)
    {
      __mod = 5;
      __beg = const_cast<char*>(__olds);
      __beglen = 3;
    }
  }
  else
  {
    __beg = __pads;
    __beglen = __plen;
    __end = const_cast<char*>(__olds);
  }

  bar (__beg, __beglen);
  bar (__end, __newlen - __beglen - __mod);
}



int main ()
{
  _S_pad_char (0, 10, 0,  2, true, false);
}
---------------------------------------------

I expect this program to print `3' and `2' when run.
But here's what it actually prints:

$ g++ -O2 -o x x.cc
$ ./x
3
5


Here's the relevant excerpt from the assembly output:

.L8:
        subl    $8, %esp
        pushl   %edi
        pushl   %eax
        call    bar__FPCvi
        movl    -20(%ebp), %eax
        popl    %edx
        popl    %ecx
        subl    %eax, 12(%ebp)
        movl    12(%ebp), %eax
        pushl   %eax
        pushl   %ebx
        call    bar__FPCvi


Here, 12(%ebp) is __newlen, and -20(%ebp) is __mod.
Thus, the __beglen term is getting lost from the subtraction in the
second call to bar().


	
>How-To-Repeat:
  See above.
	
>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted:

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