------- Additional Comments From fuzzypoint at yahoo dot com  2005-06-07 22:19 
-------
(In reply to comment #5)
> Yup, segfaults for 64 on x86-64 too with 3.4.5pre:
> 
> Program received signal SIGSEGV, Segmentation fault.
> main (argc=-1781549440, argv=0x0) at stl_deque.h:134
> 134           { return *_M_cur; }
> 

I'm having similar trouble in x86_64 as well.
Tried the above sample on x86_64 and can confirm.  
I modified the program above
a bit and it seems like deque::operator++ is at fault (or badly compiled).

First the modified sample program
------------------------------------------------------------
#include <iostream>
#include <deque>
#include <memory>

using std::deque;
using std::auto_ptr;

static char c = 0;
struct A { long x; char y; A() : x(0),y(c++) {} };

auto_ptr<deque<A> > foo(int l){
  auto_ptr<deque<A> > d(new deque<A>);
  for (int i=0; i<l; i++)
    d->push_back(A());
  return d;
}

struct v { void *a, *b, *c, *d; };

void foo();

int main(int argc, char **argv) 
{
  auto_ptr<deque<A> > d = foo(atoi(argv[1]));
  A a;
  std::cerr << &*d->begin() << " " << &*d->end() << " "
            << &*d->end()-&*d->begin() << std::endl;
  for (deque<A>::iterator i = d->begin(); i != d->end(); ++i) {
    std::cerr << i->x << ' ' << (int)i->y
              << " v=" << &*i  
              << " cur=" << ((v*)&i)->a 
              << " first=" << ((v*)&i)->b 
              << " last=" << ((v*)&i)->c 
              << " node=" << ((v*)&i)->d 
              << std::endl;
    if( i->y == 31 )
      foo();
  }
  return 0;
}

void foo() { std::cerr << "faulty ++ is next" << std::endl;}
-----------------------------------------

compiled on x86_64 with g++-3.4.4 -O2 -fno-strict-aliasing I get
$ ./runtest 32
0x6007c0 0x6009d0 33
0 0 v=0x6007c0 cur=0x6007c0 first=0x6007c0 last=0x6009c0 node=0x600788
0 1 v=0x6007d0 cur=0x6007d0 first=0x6007c0 last=0x6009c0 node=0x600788
0 2 v=0x6007e0 cur=0x6007e0 first=0x6007c0 last=0x6009c0 node=0x600788
[...]
0 30 v=0x6009a0 cur=0x6009a0 first=0x6007c0 last=0x6009c0 node=0x600788
0 31 v=0x6009b0 cur=0x6009b0 first=0x6007c0 last=0x6009c0 node=0x600788
faulty ++ is next
0 0 v=0x6009c0 cur=0x6009d0 first=0x6009d0 last=0x600bd0 node=0x600790
0 0 v=0x6009e0 cur=0x6009e0 first=0x6009d0 last=0x600bd0 node=0x600790
[...]
0 0 v=0x600bc0 cur=0x600bc0 first=0x6009d0 last=0x600bd0 node=0x600790
0 Segmentation fault


Looks like operator++ somehow jumps over d->end() and continues counting.

Without -fno-strict-aliasing everything seems just fine:

$ ./runtest 32
0x6007c0 0x6009d0 33
0 0 v=0x6007c0 cur=0x6007c0 first=0x6007c0 last=0x6009c0 node=0x600788
0 1 v=0x6007d0 cur=0x6007d0 first=0x6007c0 last=0x6009c0 node=0x600788
[...]
0 30 v=0x6009a0 cur=0x6009a0 first=0x6007c0 last=0x6009c0 node=0x600788
0 31 v=0x6009b0 cur=0x6009b0 first=0x6007c0 last=0x6009c0 node=0x600788
faulty ++ is next

Seems to me like _M_cur = _M_first is forgotten (or evaluated too late?) in
std::deque::operator++()

stl_deque.h:140
      _Self&
      operator++()
      {
        ++_M_cur;
        if (_M_cur == _M_last)
          {
            _M_set_node(_M_node + 1);
            _M_cur = _M_first;
          }
        return *this;
      }


-- 


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

Reply via email to