PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11326 Summary: C++ IA64 ABI: 3.1.4: sometimes pointer to temporary return value is implicit first parameter preceding “this” Product: gcc Version: 3.2 Status: UNCONFIRMED Severity: normal Priority: P1 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: Vyatcheslav dot Sysoltsev at intel dot com CC: gcc-bugs at gcc dot gnu dot org According to C++ Itanium ABI (http://www.codesourcery.com/cxx- abi/abi.html#calls) clause 3.1.4 if the return value type has a non-trivial copy constructor or destructor the caller allocates space for a temporary, and passes a pointer to the temporary as an implicit first parameter preceding both the “this” parameter and user parameters. The callee then constructs the return value into this temporary. I tried gcc 3.2 on United Linux 1.0 and found that this rule is violated, “this” pointer is always r32 and the value returned in different ways but never the way described in this part of ABI. Here is a test case that demonstrates the problem: test.cc: #include #include struct ConstructedObject { ConstructedObject() {}; ~ConstructedObject() {}; ConstructedObject(const ConstructedObject &from) {}; }; struct FrameworkObject { ConstructedObject action(); }; ConstructedObject FrameworkObject::action() { void *r32, *r33; asm("mov %0 = r32\nmov %1 = r33" : "=r"(r32), "=r"(r33) : ); printf("In FrameworkObject, this = %lx, r32 = %lx, r33 = %lx\n", this, r32, r33); if (this != r33) { printf ("Test failed\n"); exit(-1); } }; int main() { FrameworkObject slawa; slawa.action(); return 0; } command line: g++ -g -O0 test.cc && a.out Output: In FrameworkObject, this = 60000fffffffb270, r32 = 60000fffffffb270, r33 = 6000000000000de0 Test failed Test fails because according to ABI r32 is a placeholder for returned object, r33 is “this” pointer. Because gcc violates C++ Itanium ABI such way, binaries built by gcc can be incompatible with binaries built by other compiler. To avoid such a situation C++ ABI standard was created. All compilers must honor it, gcc must in greater degree as the most popular one, that's why I set P1 priority. The bug is reproducible both with gcc 3.2 and gcc 3.4. /usr/bin/g++ -v Reading specs from /usr/lib/gcc-lib/ia64-suse-linux/3.2/specs Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local- prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man -- libdir=/usr/lib --enable-languages=c,c++,f77,objc,java,ada --enable-libgcj -- with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib --with-system-zlib -- enable-shared --enable-__cxa_atexit ia64-suse-linux Thread model: posix gcc version 3.2 /mnt/scratch/compiler/gcc-3.4-IA64/usr/local/bin/g++ -v Reading specs from /mnt/scratch/compiler/gcc-3.4-IA64/usr/local/bin/../lib/gcc- lib/ia64-unknown-linux-gnu/3.4/specs Configured with: ./configure Thread model: posix gcc version 3.4 20030603 (experimental)