On Aug 10, 2010, at 1:00 AM, "attardi at di dot unipi dot it" <gcc-bugzi...@gcc.gnu.org > wrote:

Code produced using -O2 handles dereferencing incorrectly.
Here is a program that shows the bug:

#include <iostream>
#include <vector>

class Derived : public std::vector<char *>
{
public:
  Derived() {}
};

void* foo(void* arg) {
    void* baseptr = 0;
    *(std::vector<char*> **)&baseptr = (Derived *)arg;
    return baseptr;
}

Have it do
jlong a = 0;
memcpy(&a, &arg, sizeof(void*));

That is the most portable way of putting a pointer value in jlong.


void* foo2(void* arg) {
    void* baseptr = 0;
    *(std::vector<char*> **)&baseptr = *(Derived **)&arg;
    return baseptr;
}

int main()
{
  Derived* d = new Derived();
  void* upcast = foo(d);
  void* upcast2 = foo2(d);
  std::cerr << d << ", " << upcast << ", " << upcast2 << std::endl;
}

If you compile without -O2 the two values upcast and upcast2 are the
same, as they should be.
Using -O2 the results are different.

The bug occurrs with both:

g++ (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)
g++ (Ubuntu 4.4.1-4ubuntu9) 4.4.1

This kind of code is generated by SWIG for Java, so I can't change the source.

Curiously the bug disappears if you put a print statement before the
assignment to baseptr.


--
          Summary: optimizer dereference
          Product: gcc
          Version: 4.4.1
           Status: UNCONFIRMED
         Severity: critical
         Priority: P3
        Component: c++
       AssignedTo: unassigned at gcc dot gnu dot org
       ReportedBy: attardi at di dot unipi dot it
GCC build triplet: x86_64-unknown-linux-gnu
 GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu


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

Reply via email to