https://stackoverflow.com/a/6614369/1091587 has a quick rundown of the destructor types (D0, D1, D2) that appear when you read the symbol table of a program compiled using “gcc3”-type name mangling. There are also corresponding constructors C0/C1/C2. With g++-4.7 (possibly earlier), there appears a new ctor/dtor pair, namely C5/D5, however only as a debugging symbol.
$ cat i.cpp
class X { public: virtual ~X() {}; };
int main(void) { X x; return 0; };
$ g++ -c i.cpp
$ nm i.o | grep 5
0000000000000000 n _ZN1XC5Ev
0000000000000000 n _ZN1XD5Ev
$ c++filt -n _ZN1XC5Ev _ZN1XD5Ev
X::X()
X::~X()
The demangler source calls the D5 object a “gnu_v3_object_dtor_group”, but what exactly is a dtor group and what is it good for? clang++-3.3 does not emit it, and http://gcc.gnu.org/ml/gcc-patches/2011-11/msg00383.html suggests it might have something to do with the new transactional memory feature in gcc.
This LLVM patch and this GCC bug provide more background. By following the links I found Bug 3187 - gcc lays down two copies of constructors which seems to be the origin of it all:
You can find many discussions on the gcc-patches ML if you search for "PR c++/3187" (e.g.). Basically, C5/D5 is not a constructor/destructor by itself, but a COMDAT group containing two or more of "basic" constructors/destructors. This ensures that the functions in the group are either all used in the final binary, or all discarded (to enforce the "one definition rule").
The result of the discussions in the above bugs seems to be:
You can see the comdats by e.g. dumping the file with
readelf -G
:(This is with GCC 4.6 which is probably why it does not match the definition above)