http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52104
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-02-03 10:48:16 UTC --- Are you sure this is using native TLS? This part of the 49204 commit: (__future_base::_Async_state_common::_M_join): Serialize attempts to join thread. adds: void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); } which is called from the destructor, which is defined in future.o That calls call_once, which creates the missing symbol: template<typename _Callable, typename... _Args> void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args) { #ifdef _GLIBCXX_HAVE_TLS auto __bound_functor = std::__bind_simple(std::forward<_Callable>(__f), std::forward<_Args>(__args)...); __once_callable = &__bound_functor; __once_call = &__once_call_impl<decltype(__bound_functor)>; #else unique_lock<mutex> __functor_lock(__get_once_mutex()); auto __callable = std::__bind_simple(std::forward<_Callable>(__f), std::forward<_Args>(__args)...); __once_functor = [&]() { __callable(); }; __set_once_functor_lock_ptr(&__functor_lock); #endif So the lambda and std::function are only used when _GLIBCXX_HAVE_TLS is not defined