http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59469
--- Comment #2 from Markus Trippelsdorf <octoploid at yandex dot com> --- markus@x4 llvm_build % cat BasicBlock.ii struct A {}; namespace llvm { struct B {}; template <typename> struct ilist_traits : B {}; template <typename> class ilist_iterator : A { public: ilist_iterator(int) {} int operator!=(ilist_iterator &); void operator++(); }; template <typename NodeTy, typename Traits = ilist_traits<NodeTy> > class C : Traits { C &transfer_L2; public: A splice_where; void splice() { this->transferNodesFromList(transfer_L2, 0, 0); } }; class Function; template <typename ValueSubClass, typename ItemParentClass> class SymbolTableListTraits : B { public: ItemParentClass *getListOwner(); void transferNodesFromList(ilist_traits<ValueSubClass> &p1, ilist_iterator<ValueSubClass>, ilist_iterator<ValueSubClass>); }; class BasicBlock { Function *getParent(); void moveBefore(); }; template <typename ValueSubClass, typename ItemParentClass> void SymbolTableListTraits<ValueSubClass, ItemParentClass>::transferNodesFromList( ilist_traits<ValueSubClass> &p1, ilist_iterator<ValueSubClass> p2, ilist_iterator<ValueSubClass> p3) { ItemParentClass a = *getListOwner() = *p1.getListOwner(); int b = *ilist_traits<ValueSubClass>::getSymTab(0); for (; p2 != p3; ++p2) ; } template <> struct ilist_traits<BasicBlock> : SymbolTableListTraits<BasicBlock, Function> { static int *getSymTab(Function *); }; class Function : BasicBlock { public: C<llvm::BasicBlock> &getBasicBlockList(); }; } using namespace llvm; BasicBlock c; void BasicBlock::moveBefore() { c.getParent()->getBasicBlockList().splice(); c.getParent()->getBasicBlockList().splice(); } markus@x4 llvm_build % cat Function.ii struct A {}; namespace llvm { template <typename> struct ilist_traits; class Function; struct B {}; template <typename> class ilist_iterator : A {}; template <typename ValueSubClass, typename> class SymbolTableListTraits : B { void transferNodesFromList(ilist_traits<ValueSubClass> &p1, ilist_iterator<ValueSubClass>, ilist_iterator<ValueSubClass>); }; class BasicBlock; template <typename ValueSubClass, typename ItemParentClass> void SymbolTableListTraits<ValueSubClass, ItemParentClass>::transferNodesFromList( ilist_traits<ValueSubClass> &p1, ilist_iterator<ValueSubClass>, ilist_iterator<ValueSubClass>) {} } using namespace llvm; template class ::SymbolTableListTraits<BasicBlock, Function>; markus@x4 llvm_build % g++ -flto -O3 -fPIC -shared BasicBlock.ii Function.ii markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList markus@x4 llvm_build % g++ -flto -O2 -fPIC -shared BasicBlock.ii Function.ii markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList 00000000000009e0 t llvm::SymbolTableListTraits<llvm::BasicBlock, llvm::Function>::transferNodesFromList(llvm::ilist_traits<llvm::BasicBlock>&, llvm::ilist_iterator<llvm::BasicBlock>, llvm::ilist_iterator<llvm::BasicBlock>) markus@x4 llvm_build % g++ -O3 -fPIC -shared BasicBlock.ii Function.ii markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList 0000000000000b50 W llvm::SymbolTableListTraits<llvm::BasicBlock, llvm::Function>::transferNodesFromList(llvm::ilist_traits<llvm::BasicBlock>&, llvm::ilist_iterator<llvm::BasicBlock>, llvm::ilist_iterator<llvm::BasicBlock>) markus@x4 llvm_build % clang++ -flto -O3 -w -fPIC -shared BasicBlock.ii Function.ii markus@x4 llvm_build % nm ./a.out | c++filt | grep ::transferNodesFromList 0000000000000b70 W llvm::SymbolTableListTraits<llvm::BasicBlock, llvm::Function>::transferNodesFromList(llvm::ilist_traits<llvm::BasicBlock>&, llvm::ilist_iterator<llvm::BasicBlock>, llvm::ilist_iterator<llvm::BasicBlock>) markus@x4 llvm_build %