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]
Other format: [Raw text]

[Bug c++/11973] New: GCC 3.3 optimizer creates wrong code (i386/Linux)


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11973

           Summary: GCC 3.3 optimizer creates wrong code (i386/Linux)
           Product: gcc
           Version: 3.3
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: yuri at tsoft dot com
                CC: gcc-bugs at gcc dot gnu dot org,yuri at tsoft dot com

Symptom: Code (see below) crashes when compiled with -O3 and works
when compiled non-optimized

Expected: both optimized and nonoptimized should exit "main" OK.

Immediate reason in ASM: in inlined function alc() in E::X_alc()
freed = freed->next and first operation of constructor of C class
(vtbl initialization) are swapped by optimizer.
So it fills VTBL pointer into freed->next before it's value is being
placed into freed by alc(). So after the first call to alc()
freed is already wrong (has VTBL in it). And it should have "next"
value from the previous "freed" instance.

Please contact me yuri@tsoft.com if explanation isn't clear.
This bug prevents us from switching to 3.3.

Thanx,
Yuri
 

----Version from "gcc -v"------------------------
Reading specs from /usr/gcc-3.3/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.3/specs
Configured with: ./configure --prefix=/gjt/home/yuri/gcc 
--exec-prefix=/gjt/home/yuri/gcc
Thread model: posix
gcc version 3.3
---end Version------------------------------------
---code-------------------------------------------
#include <stdio.h> 
  
struct SList {
  SList *next;
  int i;
};

SList sl1, sl2;
SList *freed; 
  
inline void *alc() {
  void *r = freed;
  // !!! HERE IS WHERE BUG IS IMPLANTED
  freed = freed->next;
  return (r);
} 
  
class P {
public:
  virtual int fn1() { return (1); }
  virtual int fn2() { return (2); } 
};

class C : public P {
public: 
  virtual int fn1() { return (3); }
  virtual int fn2() { return (4); }

  int i;

  inline void * operator new(size_t sz) { return alc(); }
  inline void operator delete(void *) { }
};

class D {
public:
  virtual C* X_alc() { return (NULL); }
};

class E {
public:
  virtual C* X_alc() { return (new C()); };
};

int
main(int argc[], const char *argv[]) {
  C *c1, *c2;
  E *a = new E;
  
  // initialize
  sl1.next = &sl2;
  sl2.next = NULL;
  freed = &sl1;
  
  
  printf(" ** freed=%p **\n", freed);
  
  printf(" ** alloc: %p **\n", (c1 = a->X_alc()));
  printf(" ** freed=%p **\n", freed);

  printf(" ** alloc: %p **\n", (c2 = a->X_alc()));
  printf(" ** freed=%p **\n", freed);

  delete c1;
  delete c2;

  return (0);
}
---end code---------------------------------------
---asm------(E::X_alc where alc() is inlined)-----
080485e0 <_ZN1E5X_alcEv>:
 80485e0:       55                      push   %ebp
 80485e1:       a1 d8 98 04 08          mov    0x80498d8,%eax
 80485e6:       89 e5                   mov    %esp,%ebp
 80485e8:       c7 00 c8 86 04 08       movl   $0x80486c8,(%eax)
 80485ee:       8b 08                   mov    (%eax),%ecx
 80485f0:       5d                      pop    %ebp
 80485f1:       89 0d d8 98 04 08       mov    %ecx,0x80498d8
 80485f7:       c3                      ret
 80485f8:       90                      nop
 80485f9:       8d b4 26 00 00 00 00    lea    0x0(%esi,1),%esi
---end asm----------------------------------------


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