$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/armv5tel-unknown-linux-gnueabi/4.9.2/lto-wrapper Target: armv5tel-unknown-linux-gnueabi Configured with: /build/gcc/src/gcc-4.9-20141224/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://github.com/archlinuxarm/PKGBUILDs/issues --enable-languages=c,c++,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --disable-multilib --disable-werror --enable-checking=release --host=armv5tel-unknown-linux-gnueabi --build=armv5tel-unknown-linux-gnueabi --with-arch=armv5te --with-float=soft Thread model: posix gcc version 4.9.2 20141224 (prerelease) (GCC) Test case from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=727621 : #include <future> int main() { std::future<bool> fb = std::async([]{ return false; }); return 0; } yields: future.cc: In function ‘int main()’: future.cc:5:27: error: variable ‘std::future<bool> fb’ has initializer but incomplete type std::future<bool> fb = std::async([]{ return false; }); ^ future.cc:5:62: error: invalid use of incomplete type ‘class std::future<bool>’ std::future<bool> fb = std::async([]{ return false; }); ^ In file included from future.cc:1:0: /usr/include/c++/4.9.2/future:114:11: error: declaration of ‘class std::future<bool>’ class future; ^ /usr/include/c++/4.9.2/future: At global scope: /usr/include/c++/4.9.2/future:176:5: error: ‘std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = main()::<lambda()>; _Args = {}; typename std::result_of<_Functor(_ArgTypes ...)>::type = bool]’, declared using local type ‘main()::<lambda()>’, is used but never defined [-fpermissive] async(_Fn&& __fn, _Args&&... __args); ^
Confirmed with -march=armv5te on all platforms. The only thing I can think of off the top of my head that is different for armv5te compared to armv7-a is that on armv5te we end up going through the kernel helper function for all atomic and sync type operations, there is no inlining and maybe that's what is broken in some sense here. Would help for some comments from a libstdc++ / C++ person.
I think this is expected, the std:future type and std::async function are declared unconditionally, but the definitions are guarded by: #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ && (ATOMIC_INT_LOCK_FREE > 1) If your target doesn't meet those conditions then you don't get to use std::future
i.e. it's not broken, it's missing, and that's by design.
(In reply to Jonathan Wakely from comment #3) > i.e. it's not broken, it's missing, and that's by design. Right so if I parse that correctly, it boils down to implementation of atomics with calls to kernel helper function vs the lack of it IIUC. Not really a libstdc++ issue but more of an issue with the way in which atomics are implemented on arch's that don't have the actual instruction support but are implemented through kernel helper functions. It appears as though this breaks quite a few packages on older versions of the architecture so that's interesting. Ramana
(In reply to Jonathan Wakely from comment #3) > i.e. it's not broken, it's missing, and that's by design. So is it the intention of the GCC developers that program writers targeting such platforms simply avoid these facilities and use std::thread/mutex instead?
(In reply to Bastiaan Jacques from comment #5) > (In reply to Jonathan Wakely from comment #3) > > i.e. it's not broken, it's missing, and that's by design. > > So is it the intention of the GCC developers that program writers targeting > such platforms simply avoid these facilities and use std::thread/mutex > instead? Or they could contribute an implementation that works for their target. The intention of the developers is that the feature should work correctly, and if that isn't possible with the current implementation for some target, then the feature should be disabled on that target. And that's what you see.
Created attachment 39971 [details] Not yet fully tested patch for std::future fix I'm currently in process fixing this bug. But I have to delay running tests and other verification for tomorrow. The patch is compile tested on Debian armel vm.
The patch is a pessimization for non-armv5 targets, we don't want to change the targets that already work correctly. I'll look at a better way to do it (maybe encapsulating the ref-count more neatly) this week.
atomicity.h uses exactly same builtins if _GLIBCXX_ATOMIC_BUILTINS is set 1. Difference include check for __gthread_active_p check and annotations for race detector. Annotations are empty macros in default build. Same code is uses for all other atomic operations in libstdc++. I'm finally having an working armv5te build from gcc-6-branch. I'm currently waiting the second unit test run to complete. If there is no unexpected failures from futures or exceptions I fill submit the complete patch later today.
> I'm finally having an working armv5te build is this supposed to work for armv4t as well?
Author: redi Date: Wed Jan 4 10:54:59 2017 New Revision: 244051 URL: https://gcc.gnu.org/viewcvs?rev=244051&root=gcc&view=rev Log: Support exception propagation without lock-free atomic int 2017-01-04 Pauli Nieminen <suokkos@gmail.com> Jonathan Wakely <jwakely@redhat.com> PR libstdc++/64735 * acinclude.m4 (GLIBCXX_CHECK_EXCEPTION_PTR_SYMVER): Define. * config.h.in: Regenerate. * config/abi/pre/gnu.ver [HAVE_EXCEPTION_PTR_SINCE_GCC46] (GLIBCXX_3.4.15, GLIBCXX_3.4.21, CXXABI_1.3.3, CXXABI_1.3.5): Make exports for exception_ptr, nested_exception, and future conditional. [HAVE_EXCEPTION_PTR_SINCE_GCC46] (GLIBCXX_3.4.23, CXXABI_1.3.11): Add exports for exception_ptr, nested_exception, and future conditional. * configure: Regenerate. * configure.ac: Use GLIBCXX_CHECK_EXCEPTION_PTR_SYMVER. * include/std/future: Remove check for ATOMIC_INT_LOCK_FREE * libsupc++/eh_atomics.h: New file for internal use only. (__eh_atomic_inc, __eh_atomic_dec): New. * libsupc++/eh_ptr.cc (exception_ptr::_M_addref) (exception_ptr::_M_release) (__gxx_dependent_exception_cleanup) (rethrow_exception): Use eh_atomics.h reference counting helpers. * libsupc++/eh_throw.cc (__gxx_exception_cleanup): Likewise. * libsupc++/eh_tm.cc (free_any_cxa_exception): Likewise. * libsupc++/exception: Remove check for ATOMIC_INT_LOCK_FREE. * libsupc++/exception_ptr.h: Likewise. * libsupc++/guard.cc: Include header for ATOMIC_INT_LOCK_FREE macro. * libsupc++/nested_exception.cc: Remove check for ATOMIC_INT_LOCK_FREE. * libsupc++/nested_exception.h: Likewise. * src/c++11/future.cc: Likewise. * testsuite/18_support/exception_ptr/*: Remove atomic builtins checks. * testsuite/18_support/nested_exception/*: Likewise. * testsuite/30_threads/async/*: Likewise. * testsuite/30_threads/future/*: Likewise. * testsuite/30_threads/headers/future/types_std_c++0x.cc: Likewise. * testsuite/30_threads/packaged_task/*: Likewise. * testsuite/30_threads/promise/*: Likewise. * testsuite/30_threads/shared_future/*: Likewise. Added: trunk/libstdc++-v3/libsupc++/eh_atomics.h Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/acinclude.m4 trunk/libstdc++-v3/config.h.in trunk/libstdc++-v3/config/abi/pre/gnu.ver trunk/libstdc++-v3/configure trunk/libstdc++-v3/configure.ac trunk/libstdc++-v3/include/std/future trunk/libstdc++-v3/libsupc++/eh_ptr.cc trunk/libstdc++-v3/libsupc++/eh_throw.cc trunk/libstdc++-v3/libsupc++/eh_tm.cc trunk/libstdc++-v3/libsupc++/exception trunk/libstdc++-v3/libsupc++/exception_ptr.h trunk/libstdc++-v3/libsupc++/guard.cc trunk/libstdc++-v3/libsupc++/nested_exception.cc trunk/libstdc++-v3/libsupc++/nested_exception.h trunk/libstdc++-v3/src/c++11/future.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/40296.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/62258.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/64241.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/lifespan.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/make_exception_ptr.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/make_exception_ptr_2.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/move.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/requirements.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/requirements_neg.cc trunk/libstdc++-v3/testsuite/18_support/exception_ptr/rethrow_exception.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/51438.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/62154.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/68139.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/cons.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/nested_ptr.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_if_nested.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_nested.cc trunk/libstdc++-v3/testsuite/18_support/nested_exception/throw_with_nested.cc trunk/libstdc++-v3/testsuite/30_threads/async/42819.cc trunk/libstdc++-v3/testsuite/30_threads/async/49668.cc trunk/libstdc++-v3/testsuite/30_threads/async/54297.cc trunk/libstdc++-v3/testsuite/30_threads/async/any.cc trunk/libstdc++-v3/testsuite/30_threads/async/async.cc trunk/libstdc++-v3/testsuite/30_threads/async/except.cc trunk/libstdc++-v3/testsuite/30_threads/async/forced_unwind.cc trunk/libstdc++-v3/testsuite/30_threads/async/launch.cc trunk/libstdc++-v3/testsuite/30_threads/async/lwg2021.cc trunk/libstdc++-v3/testsuite/30_threads/async/sync.cc trunk/libstdc++-v3/testsuite/30_threads/future/cons/assign_neg.cc trunk/libstdc++-v3/testsuite/30_threads/future/cons/constexpr.cc trunk/libstdc++-v3/testsuite/30_threads/future/cons/copy_neg.cc trunk/libstdc++-v3/testsuite/30_threads/future/cons/default.cc trunk/libstdc++-v3/testsuite/30_threads/future/cons/move.cc trunk/libstdc++-v3/testsuite/30_threads/future/cons/move_assign.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/45133.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/get.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/get2.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/share.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/valid.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/wait.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/wait_for.cc trunk/libstdc++-v3/testsuite/30_threads/future/members/wait_until.cc trunk/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc trunk/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/49668.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/60564.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/1.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/2.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/3.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/56492.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc2.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/move.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/move_assign.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/forced_unwind.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/at_thread_exit.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke5.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/swap.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/valid.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc trunk/libstdc++-v3/testsuite/30_threads/packaged_task/uses_allocator.cc trunk/libstdc++-v3/testsuite/30_threads/promise/60966.cc trunk/libstdc++-v3/testsuite/30_threads/promise/69106.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/1.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc2.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc trunk/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/at_thread_exit.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/get_future2.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc trunk/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc trunk/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc trunk/libstdc++-v3/testsuite/30_threads/promise/uses_allocator.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/constexpr.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/default.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/45133.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/get.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/get2.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/valid.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/wait.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/wait_for.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/wait_until.cc trunk/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc
This is fixed on trunk now, without pessimizing targets that already support exception propagation.
*** Bug 58938 has been marked as a duplicate of this bug. ***
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c commit r11-8198-g6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Apr 14 20:48:54 2021 +0100 libstdc++: Move atomic functions to libsupc++ [PR 96657] The changes for PR libstdc++/64735 mean that libsupc++ function might now depend on the __exchange_and_add and __atomic_add functions defined in config/cpu/*/atomicity.h which is not compiled into libsupc++. This causes a link failure for some targets when trying to use libsupc++ without the rest of libstdc++. This patch simply moves the definitions of those functions into libsupc++ so that they are available there. libstdc++-v3/ChangeLog: PR libstdc++/96657 * libsupc++/Makefile.am: Add atomicity.cc here. * src/c++98/Makefile.am: Remove it from here. * libsupc++/Makefile.in: Regenerate. * src/c++98/Makefile.in: Regenerate. * testsuite/18_support/exception_ptr/96657.cc: New test.
The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:f2074277aa3ce0848429e34d6149ba26ff3b708e commit r10-9997-gf2074277aa3ce0848429e34d6149ba26ff3b708e Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Apr 14 20:48:54 2021 +0100 libstdc++: Move atomic functions to libsupc++ [PR 96657] The changes for PR libstdc++/64735 mean that libsupc++ function might now depend on the __exchange_and_add and __atomic_add functions defined in config/cpu/*/atomicity.h which is not compiled into libsupc++. This causes a link failure for some targets when trying to use libsupc++ without the rest of libstdc++. This patch simply moves the definitions of those functions into libsupc++ so that they are available there. libstdc++-v3/ChangeLog: PR libstdc++/96657 * libsupc++/Makefile.am: Add atomicity.cc here. * src/c++98/Makefile.am: Remove it from here. * libsupc++/Makefile.in: Regenerate. * src/c++98/Makefile.in: Regenerate. * testsuite/18_support/exception_ptr/96657.cc: New test. (cherry picked from commit 6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c)
The releases/gcc-9 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:ba5e10a8c84f56bb2838adb6d1cc9b74741ac4f1 commit r9-9640-gba5e10a8c84f56bb2838adb6d1cc9b74741ac4f1 Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Apr 14 20:48:54 2021 +0100 libstdc++: Move atomic functions to libsupc++ [PR 96657] The changes for PR libstdc++/64735 mean that libsupc++ function might now depend on the __exchange_and_add and __atomic_add functions defined in config/cpu/*/atomicity.h which is not compiled into libsupc++. This causes a link failure for some targets when trying to use libsupc++ without the rest of libstdc++. This patch simply moves the definitions of those functions into libsupc++ so that they are available there. libstdc++-v3/ChangeLog: PR libstdc++/96657 * libsupc++/Makefile.am: Add atomicity.cc here. * src/c++98/Makefile.am: Remove it from here. * libsupc++/Makefile.in: Regenerate. * src/c++98/Makefile.in: Regenerate. * testsuite/18_support/exception_ptr/96657.cc: New test. (cherry picked from commit 6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c)