This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
optimization/487: bad code generated on i86 with optimization <synopsis of the problem (one line)>
- To: gcc-gnats at gcc dot gnu dot org
- Subject: optimization/487: bad code generated on i86 with optimization <synopsis of the problem (one line)>
- From: snyder at fnal dot gov
- Date: Wed, 23 Aug 2000 23:54:07 -0500
- Reply-To: snyder at fnal dot gov
- Resent-Cc: gcc-prs at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org
- Resent-Reply-To: gcc-gnats@gcc.gnu.org, snyder@fnal.gov
>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: