Bug 26755 - [4.0 regression] may fail to generate code for base destructor defined inline with pragma interface
Summary: [4.0 regression] may fail to generate code for base destructor defined inline...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.3
: P3 normal
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ABI, link-failure
Depends on:
Blocks:
 
Reported: 2006-03-19 12:15 UTC by Debian GCC Maintainers
Modified: 2007-02-03 16:25 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.0 4.1.0
Known to fail: 4.0.3
Last reconfirmed: 2006-03-26 16:35:26


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Debian GCC Maintainers 2006-03-19 12:15:37 UTC
[ no small test case yet, forwarded from http://bugs.debian.org/356435 ]

Where a base class has a destructor defined inline, g++ may generate
code for a derived class's destructor that calls an non-inline version
of the base class destructor, but without generating code for the
latter.  This is normally masked by the fact that g++ 4.1 now
generates the base-class destructor (aka the non-in-charge destructor)
along with the whole-object destructor (aka the in-charge
destructor), but becomes a problem when linking with code generated by
g++ 4.0.

An example for this is bug #356245 (xbsql failing to build):

> Automatic build of xbsql_0.11-5 on bigsur by sbuild/mips 1.80
...
> /bin/sh ../libtool --mode=link g++  -UNO_READLINE -I/usr/local/include -g  -g -o xql  xql.o -lxbase -lreadline -lncurses ./libxbsql.la 
> g++ -UNO_READLINE -I/usr/local/include -g -g -o .libs/xql xql.o  -lreadline -lncurses ./.libs/libxbsql.so /usr/lib/libxbase.so
> ./.libs/libxbsql.so: undefined reference to `xbNdx::~xbNdx()'
> collect2: ld returned 1 exit status
> make[2]: *** [xql] Error 1

Ben Hutchings:

I was scratching my head over this one for a long time, because
libxbase.so definitely does include an out-of-line copy of the
destructor (required for the vtable).  Eventually I remembered that the
destructor can be called in several different ways and that the G++ ABI
provides separate entry points, each with its own symbol, for those
different cases.  These aren't distinguished when demangling, so we must
turn that off to see that:

libxbase built with g++ 4.0 has:
0001e940 W _ZN5xbNdxD0Ev  // deleting destructor
0001eb30 W _ZN5xbNdxD1Ev  // complete object destructor

libxbsql built with g++ 4.0 has:
00015676 W _ZN5xbNdxD1Ev  // complete object destructor
00012aec W _ZN5xbNdxD2Ev  // base object destructor

libxbase (built with g++ 4.1) has:
0001f850 W _ZN5xbNdxD0Ev  // deleting destructor
0001f8e0 W _ZN5xbNdxD1Ev  // complete object destructor
0001f960 W _ZN5xbNdxD2Ev  // base object destructor

libxbsql (built with g++ 4.1) has:
         U _ZN5xbNdxD1Ev  // complete object destructor
         U _ZN5xbNdxD2Ev  // base object destructor

It appears that g++ 4.1 generates out-of-line code for all inline
destructors along with other members of the class and relies on that
avoid generating duplicates elsewhere.  But g++ 4.1 is supposed to be
binary-compatible with g++ 4.0 and this behaviour isn't, so this is a
bug in g++.

Ben.
Comment 1 Andrew Pinski 2006-03-19 16:08:46 UTC
We need a testcase to reproduce this.
Comment 2 Martin Michlmayr 2006-03-21 12:09:25 UTC
> We need a testcase to reproduce this.

We don't have a minimal test case yet but you can download the source of the package which shows this problem and see for yourself.  Maybe you can come up with a smaller testcase. 

http://www.rekallrevealed.org/packages/
xbsql-0.11.tgz shos the problem, but you also need xbase-2.0.0.tgz in order to compile it.
Comment 3 Andrew Pinski 2006-03-21 14:06:38 UTC
Reading this bug report, leads me to think there is a bug in 4.0.x.
Comment 4 Andrew Pinski 2006-03-21 14:07:42 UTC
And we cannot do without a testcase as looking at the source which you gave link to does not give any obvious answers.
Comment 5 Andrew Pinski 2006-03-21 14:28:08 UTC
http://gcc.gnu.org/bugs.html 
Please read the instructions there (in fact this should not have been pulled up stream until then).
Comment 6 Martin Michlmayr 2006-03-21 15:33:18 UTC
I think you're onto something here.  Compiling xbsql with 4.1 against a
libxbase compiled with 4.1 works, but it fails against libxbase compiled with
4.0.  So this may be an 4.0 issue - but it still leaves us with a binary
compatibility between 4.0 and 4.1.

gcc version 3.3.6 (Debian 1:3.3.6-13)

libxbase
00020834 W _ZN5xbNdxD0Ev
000207a8 W _ZN5xbNdxD1Ev
0002071c W _ZN5xbNdxD2Ev

xbsql
         U _ZN5xbNdxD1Ev
         U _ZN5xbNdxD2Ev

gcc version 4.0.3 (Debian 4.0.3-1)

libxbase
000225e4 W _ZN5xbNdxD0Ev
00022844 W _ZN5xbNdxD1Ev

xbsql
0001b768 W _ZN5xbNdxD1Ev
0001826c W _ZN5xbNdxD2Ev

gcc version 4.1.0 (Debian 4.1.0-0)

libxbase
00022aa4 W _ZN5xbNdxD0Ev
00022b34 W _ZN5xbNdxD1Ev
00022bc4 W _ZN5xbNdxD2Ev

xbsql
         U _ZN5xbNdxD1Ev
         U _ZN5xbNdxD2Ev


system type: powerpc-unknown-linux-gnu, but also seen on AMD64, i386 and
mips (all Linux)

options given when GCC was configured/built:

gcc-3.3 -v
Reading specs from /usr/lib/gcc-lib/powerpc-linux-gnu/3.3.6/specs
Configured with: ../src/configure -v --enable-languages=c,c++ --prefix=/usr --mandir=/usr/share/man --infodir=/usr
/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --enable-__cxa_atexit --with-system-zlib -
-enable-nls --without-included-gettext --enable-clocale=gnu --enable-debug --disable-multilib powerpc-linux-gnu
Thread model: posix
gcc version 3.3.6 (Debian 1:3.3.6-13)

gcc-4.0 -v
Using built-in specs.
Target: powerpc-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-sh
ared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --pro
gram-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt=gtk-default
 --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-softfloat
 --enable-targets=powerpc-linux,powerpc64-linux --with-cpu=default32 --disable-werror --enable-checking=release po
werpc-linux-gnu
Thread model: posix
gcc version 4.0.3 (Debian 4.0.3-1)

gcc-4.1 -v
Using built-in specs.
Target: powerpc-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,java,fortran,objc,obj-c++,ada,treelang --prefix=/usr
 --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enab
le-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt
=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0/jre --enable-mpfr --disable-softf
loat --enable-targets=powerpc-linux,powerpc64-linux --with-cpu=default32 --enable-checking=release powerpc-linux-g
nu
Thread model: posix
gcc version 4.1.0 (Debian 4.1.0-0)


complete command line that triggers the bug;

3.3:

/bin/sh ../libtool --mode=link g++-3.3  -UNO_READLINE -I/usr/local/include -g  -g -o xql  xql.o -lxbase -lreadline
 -lncurses ./libxbsql.la
g++-3.3 -UNO_READLINE -I/usr/local/include -g -g -o .libs/xql xql.o -lreadline -lncurses ./.libs/libxbsql.so /usr/
lib/libxbase.so
[works]

4.1 with libxbase installed compiled with 4.1:
/bin/sh ../libtool --mode=link g++-4.1  -UNO_READLINE -I/usr/local/include -g  -g -o xql  xql.o -lxbase -lreadline
 -lncurses ./libxbsql.la
g++-4.1 -UNO_READLINE -I/usr/local/include -g -g -o .libs/xql xql.o  -lreadline -lncurses ./.libs/libxbsql.so /usr
/lib/libxbase.so
[works]

4.1 with libxbase installed compiled with 4.0:
/bin/sh ../libtool --mode=link g++-4.1  -UNO_READLINE -I/usr/local/include -g  -g -o xql  xql.o -lxbase -lreadline
 -lncurses ./libxbsql.la
g++-4.1 -UNO_READLINE -I/usr/local/include -g -g -o .libs/xql xql.o  -lreadline -lncurses ./.libs/libxbsql.so /usr
/lib/libxbase.so
./.libs/libxbsql.so: undefined reference to `xbNdx::~xbNdx()'

4.1 with libxbase installed compiled with 3.3:
/bin/sh ../libtool --mode=link g++-4.1  -UNO_READLINE -I/usr/local/include -g  -g -o xql  xql.o -lxbase -lreadline
 -lncurses ./libxbsql.la
g++-4.1 -UNO_READLINE -I/usr/local/include -g -g -o .libs/xql xql.o  -lreadline -lncurses ./.libs/libxbsql.so /usr
/lib/libxbase.so
/usr/bin/ld: warning: libstdc++.so.5, needed by /usr/lib/libxbase.so, may conflict with libstdc++.so.6
[warning, but compiles/links]
Comment 7 Ben Hutchings 2006-03-26 02:07:53 UTC
Here's a trivial test case:

$ cat test.hpp
#ifdef USE_PRAGMA
#pragma interface
#endif

class foo
{
public:
    virtual ~foo() {}
};

class bar : public foo
{
public :
    ~bar();
};
$ cat test.cpp
#include "test.hpp"

#ifdef USE_PRAGMA
#pragma implementation
#endif

bar::~bar()
{
}
$ g++-4.0 -c test.cpp && nm --no-demangle test.o | grep _ZN3fooD
00000000 W _ZN3fooD0Ev
00000000 W _ZN3fooD1Ev
00000000 W _ZN3fooD2Ev
$ g++-4.0 -DUSE_PRAGMA -c test.cpp && nm --no-demangle test.o | grep _ZN3fooD
00000000 W _ZN3fooD2Ev
$ g++-4.1 -c test.cpp && nm --no-demangle test.o | grep _ZN3fooD
00000000 W _ZN3fooD0Ev
00000000 W _ZN3fooD1Ev
00000000 W _ZN3fooD2Ev
$ g++-4.1 -DUSE_PRAGMA -c test.cpp && nm --no-demangle test.o | grep _ZN3fooD
         U _ZN3fooD2Ev
Comment 8 Andrew Pinski 2006-03-26 16:35:26 UTC
4.1.0 is correct as it is the same as 3.4.x.  4.0.x is incorrect and does not correspond to 3.4.x.  So this is a bug in 4.0.x and not in 4.1.0.

Confirmed.  Thanks for the short testcase.
Comment 9 Martin Michlmayr 2006-05-11 11:05:24 UTC
(In reply to comment #8)
> 4.1.0 is correct as it is the same as 3.4.x.  4.0.x is incorrect and does not
> correspond to 3.4.x.  So this is a bug in 4.0.x and not in 4.1.0.
> 
> Confirmed.  Thanks for the short testcase.

Do you think this will be fixed in 4.0.x?
Comment 10 Gabriel Dos Reis 2007-02-03 16:25:23 UTC
Fixed inGCC-4.1.0