Deriving from basic stream classes fails when: The name of the derived class is the same as the base class except that it is in a different namespace. The problem can be demonstrated using the following example (test.cpp): include <iostream> namespace mar { template <typename charT, typename char_traitsT = std::char_traits<charT> > class basic_iostream : public std::basic_iostream<charT, char_traitsT> { public: basic_iostream() : std::basic_iostream<charT, char_traitsT>(0) { } }; } int main(int argc, char* argv[]) { mar::basic_iostream<char> strm; return 0; } $ g++ test.cpp test.cpp: In instantiation of `mar::basic_iostream<char, std::char_traits<char> >': test.cpp:20: instantiated from here test.cpp:8: internal error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. $ gcc -v Reading specs from /usr/lib/gcc-lib/i486-slackware-linux/3.2.3/specs Configured with: ../gcc-3.2.3/configure --prefix=/usr --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld --verbose --target=i486-slackware-linux --host=i486-slackware-linux Thread model: posix gcc version 3.2.3 This problem can be avoided by renaming the derived class to something other than basic_iostream.
The ICE is fixed in 3.3.3 but this produces wrong in 3.3.3, 3.4.0, and 3.5.0: pr16171.s: Assembler messages: pr16171.s:609: Error: symbol `_ZTVSd' is already defined pr16171.s:630: Error: symbol `_ZTTSd' is already defined pr16171.s:643: Error: symbol `_ZTCSd0_Si' is already defined pr16171.s:659: Error: symbol `_ZTCSd8_So' is already defined pr16171.s:787: Error: symbol `_ZNSdD1Ev' is already defined pr16171.s:913: Error: symbol `_ZTv0_n12_NSdD1Ev' is already defined pr16171.s:924: Error: symbol `_ZThn8_NSdD1Ev' is already defined pr16171.s:932: Error: symbol `_ZNSdD0Ev' is already defined pr16171.s:1058: Error: symbol `_ZTv0_n12_NSdD0Ev' is already defined pr16171.s:1069: Error: symbol `_ZThn8_NSdD0Ev' is already defined
Here's a reduced testcase which causes assembler errors since gcc 3.3: ============================================================================= struct A {}; namespace std { template<typename> struct char_traits; template<typename, typename> struct basic_iostream : virtual A {}; } template <typename T, typename U = std::char_traits<T> > struct basic_iostream : std::basic_iostream<T, U> {}; basic_iostream<char> s; ============================================================================= With mainline, for example, I get: /tmp/ccmexVtk.s: Assembler messages: /tmp/ccmexVtk.s:124: Error: symbol `_ZTVSd' is already defined /tmp/ccmexVtk.s:133: Error: symbol `_ZTTSd' is already defined What really strikes me is the fact that the errors go away if I replace "std" or "char_traits" or "basic_iostream" by a different name.
Remember that some names in std:: (and namespace std::) are mangled specially to save space. For example, the symbol _ZNSdC1Ev demangles to std::basic_iostream<char, std::char_traits<char> >::basic_iostream() If the names were different, then they would appear in the mangled names. Thus, this looks like an ABI problem to me. W.
I can confirm this as well. This looks to be a problem with the mangling code: the mar::basic_iostream class should be mangled differently than std::basic_iostream. Perhaps g++ is not checking the enclosing namespace before using the C++ ABI substitutions? Hmm. FYI icc does this, which is as I'd expect _ZN3mar14basic_iostreamIcSt11char_traitsIcEEC9Ev -benjamin
The original testcase and the testcase from comment #2 compile on mainline. The underlying ABI problem still remains, however. The following updated testcase still gives assembler errors on mainline: =========================================================================== namespace std { template<typename> struct char_traits; template<typename, typename> struct basic_iostream { basic_iostream(){} }; basic_iostream<char,std::char_traits<char> > s1; } template<typename, typename> struct basic_iostream { basic_iostream(){} }; basic_iostream<char,std::char_traits<char> > s2; ===========================================================================
Created attachment 9705 [details] proposed patch This patch moves the check for the namespace std before the check for basic_*stream.
Subject: Bug 16171 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2005-09-13 15:15:37 Modified files: gcc/cp : ChangeLog mangle.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/abi: mangle26.C mangle27.C mangle28.C mangle29.C Log message: PR c++/16171 * mangle.c (find_substitution): Do not use special substitutions for identifiers not in std::. PR c++/16171 * g++.dg/abi/mangle26.C: New test. * g++.dg/abi/mangle27.C: New test. * g++.dg/abi/mangle28.C: New test. * g++.dg/abi/mangle29.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4889&r2=1.4890 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/mangle.c.diff?cvsroot=gcc&r1=1.127&r2=1.128 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.6057&r2=1.6058 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle26.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle27.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle28.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle29.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
Subject: Bug 16171 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: mmitchel@gcc.gnu.org 2005-09-13 15:17:12 Modified files: gcc/cp : ChangeLog mangle.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/abi: mangle26.C mangle27.C mangle28.C mangle29.C Log message: PR c++/16171 * g++.dg/abi/mangle26.C: New test. * g++.dg/abi/mangle27.C: New test. * g++.dg/abi/mangle28.C: New test. * g++.dg/abi/mangle29.C: New test. PR c++/16171 * mangle.c (find_substitution): Do not use special substitutions for identifiers not in std::. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.4648.2.103&r2=1.4648.2.104 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/mangle.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.116&r2=1.116.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.403&r2=1.5084.2.404 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle26.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle27.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle28.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/abi/mangle29.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1
Fixed in GCC 4.0.2.