Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang++ emits sometimes for extern template #4048

Closed Quuxplusone closed 14 years ago

Quuxplusone commented 14 years ago
Bugzilla Link PR6674
Status RESOLVED FIXED
Importance P normal
Reported by Roman Divacky (rdivacky@freebsd.org)
Reported on 2010-03-22 07:00:51 -0700
Last modified on 2010-03-26 22:51:28 -0700
Version unspecified
Hardware PC Linux
CC dgregor@apple.com, llvm-bugs@lists.llvm.org, pinskia@gmail.com, rafael@espindo.la
Fixed by commit(s)
Attachments
Blocks PR6266
Blocked by
See also
pes delta$ cat compatibility.cc
     namespace std  {
       template<class _CharT>     struct char_traits;
           typedef long streamsize;
       template<typename _CharT, typename _Traits = char_traits<_CharT> >     class basic_istream;
     template<typename _InputIterator1, typename _InputIterator2,     typename _OutputIterator>     _OutputIterator     set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,         _InputIterator2 __first2, _InputIterator2 __last2,         _OutputIterator __result)     {
       }
     class ios_base   {
       };
     template<typename _CharT, typename _Traits>     class basic_ios : public ios_base     {
       };
       template<typename _CharT, typename _Traits>     class basic_istream : virtual public basic_ios<_CharT, _Traits>     {
         typedef basic_istream<_CharT, _Traits> __istream_type;
               virtual       ~basic_istream()       {
  }
           class sentry;
          __istream_type&       ignore(streamsize __n);
       };
       template<>     basic_istream<wchar_t>&     basic_istream<wchar_t>::     ignore(streamsize __n);
       template<typename _CharT, typename _Traits>     class basic_istream<_CharT, _Traits>::sentry     {
       };
        extern template class basic_istream<wchar_t>;
        template<>     basic_istream<wchar_t>&     basic_istream<wchar_t>::     ignore(streamsize __n)     {
       }
      }

pes delta$ clang++ -O2 -c compatibility.cc && nm compatibility.o

0000000000000000 T _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl
                 U _ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev
                 U _ZNSt13basic_istreamIwSt11char_traitsIwEED1Ev
0000000000000000 V _ZTISt13basic_istreamIwSt11char_traitsIwEE
0000000000000000 V _ZTISt8ios_base
0000000000000000 V _ZTISt9basic_iosIwSt11char_traitsIwEE
0000000000000000 V _ZTSSt13basic_istreamIwSt11char_traitsIwEE
0000000000000000 V _ZTSSt8ios_base
0000000000000000 V _ZTSSt9basic_iosIwSt11char_traitsIwEE
0000000000000000 V _ZTTSt13basic_istreamIwSt11char_traitsIwEE
                 U _ZTVN10__cxxabiv117__class_type_infoE
                 U _ZTVN10__cxxabiv120__si_class_type_infoE
                 U _ZTVN10__cxxabiv121__vmi_class_type_infoE
0000000000000000 V _ZTVSt13basic_istreamIwSt11char_traitsIwEE

pes delta$ g++ -O2 -c compatibility.cc && nm compatibility.o

0000000000000000 T _ZNSt13basic_istreamIwSt11char_traitsIwEE6ignoreEl
                 U __gxx_personality_v0
Quuxplusone commented 14 years ago
when linking with real libstdc it complains about destructor... ie.

                 U _ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev
                 U _ZNSt13basic_istreamIwSt11char_traitsIwEED1Ev

the other symbol differences may be interesting too
Quuxplusone commented 14 years ago

I am changing the summary to explain what the issue is with. It is an extern template issue.

Quuxplusone commented 14 years ago
Reduced case:

-----------------------------------------
template<typename _CharT>
class basic_istream     {
  virtual       ~basic_istream()       {
  }
  void ignore(long __n);
};
template<>
void basic_istream<wchar_t>::ignore(long __n) {
}
extern template class basic_istream<wchar_t>
---------------------------------------

The problem is that the specialization of "ignore" causes us to produce the the
vtable for basic_istram and the "extern template" declaration causes us to use
refer to the destructor as an external decl.

The issue is that I think this is actually the correct behavior. The destructor
should be emitted in the with with

template class basic_istream<wchar_t>

Are we not doing so?
Quuxplusone commented 14 years ago
I managed to compile part of gcc 4.5's libstdc++ with clang and with small
changes like

-  { return { __n }; }
+  { _Setw  foo = { __n }; return foo; }

istream-inst.o builds correctly and I get:

nm .libs/istream-inst.o |grep  _ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev
0000000000000000 W _ZNSt13basic_istreamIwSt11char_traitsIwEED0Ev

I am closing the bug since it looks like we are emitting the destructor, just
not exactly in the same places as gcc.

Please reopen the bug if you still see undefined symbols in the final libstdc++.