Patchwork libstdc++/52104 - fix linker error for non-TLS targets

login
register
mail settings
Submitter Jonathan Wakely
Date Feb. 6, 2012, 12:12 a.m.
Message ID <CAH6eHdQCD1i1_qjWa7VW_Fpq_6Cm=hs7CnusiCgDe0-heMyBiA@mail.gmail.com>
Download mbox | patch
Permalink /patch/139671/
State New
Headers show

Comments

Jonathan Wakely - Feb. 6, 2012, 12:12 a.m.
The out-of-line destructor in future.cc uses std::call_once which uses
a lambda on TLS targets. Because we compile with
-fno-implicit-templates an explicit instantiation is needed, but can't
be done because the closure type created by the lambda can't be named.
 This puts the destructor inline in the header for TLS targets.  A
better fix would be to avoid using a lambda in std::call_once, but I
don't want to touch that code instage4.

        PR libstdc++/52104
        * include/std/future (__future_base::_Async_state_common): Define
        destructor inline for targets without TLS.
        * src/c++11/future.cc (__future_base::_Async_state_common): Only
        define destructor for TLS targets.

Tested x86_64-linux by me and on sparc-solaris by Eric Botcazou.
Committed to trunk.

Patch

diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 1093e3f..962400b 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -1425,7 +1425,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   class __future_base::_Async_state_common : public __future_base::_State_base
   {
   protected:
+#ifdef _GLIBCXX_HAVE_TLS
     ~_Async_state_common();
+#else
+    ~_Async_state_common() { _M_join(); }
+#endif
 
     // Allow non-timed waiting functions to block until the thread completes,
     // as if joined.
diff --git a/libstdc++-v3/src/c++11/future.cc b/libstdc++-v3/src/c++11/future.cc
index dab0774..61a9729 100644
--- a/libstdc++-v3/src/c++11/future.cc
+++ b/libstdc++-v3/src/c++11/future.cc
@@ -85,11 +85,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   __future_base::_State_base::~_State_base() = default;
 
+#ifdef _GLIBCXX_HAVE_TLS
   __future_base::_Async_state_common::~_Async_state_common() { _M_join(); }
 
   // Explicit instantiation due to -fno-implicit-instantiation.
   template void call_once(once_flag&, void (thread::*&&)(), reference_wrapper<thread>&&);
 #endif
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std