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; } 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