Created attachment 234920 [details] test.cpp The attached testcase fails in clang-14, but not in clang-13 and earlier. Failure message: > $ clang++14 test.cpp > ld: error: undefined hidden symbol: std::__1::enable_if<(is_move_constructible<int>::value) && (is_move_assignable<int>::value), void>::type std::__1::swap<int>(int&, int&) > >>> referenced by test.cpp > >>> /tmp/test-e3003a.o:(main) > clang-14: error: linker command failed with exit code 1 (use -v to see invocation) '#include <stdexcept>' is not a proper header for std::swap, so a correct outcome should be one of these two: * fail to find std::swap -- error: no member named 'swap' in namespace 'std' * succeed (through proxy header inclusion) The above error message is incorrect and irrelevant. It indicates a problem in the toolchain. This is a regression in clang-14. The problem was discovered due to a failure in science/helfem on 14-CURRENT.
Is this just the LLVM vintage (14), also applying to the same vintage but outside FreeBSD contexts? If yes, it would seem to need to be submitted upstream (LLVM) and FreeBSD would later pick up whatever LLVM does about it. If this is somehow FreeBSD-only, any clue about how?
I'm inclined to say "you're holding it wrong" here, but this discussion should really be taken upstream. Previously, when only including <stdexcept>, you were just lucky that the swap definition was pulled in transitively via <type_traits> (and that was also completely by accident), and it seemed to sort-of work. At some point upstream committed https://github.com/llvm/llvm-project/commit/6adbc83ee9e46b476e0f75d5671c3a21f675a936: commit 6adbc83ee9e46b476e0f75d5671c3a21f675a936 Author: Christopher Di Bella <cjdb@google.com> Date: Sat Jun 5 02:47:47 2021 +0000 [libcxx][modularisation] moves <utility> content out of <type_traits> Moves: * `std::move`, `std::forward`, `std::declval`, and `std::swap` into `__utility/${FUNCTION_NAME}`. * `std::swap_ranges` and `std::iter_swap` into `__algorithm/${FUNCTION_NAME}` Differential Revision: https://reviews.llvm.org/D103734 This moved stuff that should really be in <utility>, such as swap() into more modular headers, and it had the side effect of only leaving a partial swap declaration in <type_traits> that is explicitly *not* exposed (via the _LIBCPP_INLINE_VISIBILITY macro): template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 __swap_result_t<_Tp> swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && is_nothrow_move_assignable<_Tp>::value); I am unsure why this declaration has been left in, though. If I simply comment it out, the compile error for your test case at least becomes a lot clearer: bug264877/test.cpp:9:7: error: no member named 'swap' in namespace 'std' std::swap(X1, X2); ~~~~~^ However, the decltype of swap() is used in a few macros after that, so completely removing it might not be the best course of action.
Reported upstream: https://github.com/llvm/llvm-project/issues/56206
(In reply to Dimitry Andric from comment #3) I note that the upstream issue is still open as of 20240120.
(In reply to Mark Linimon from comment #4) Yeah it's still the same with clang + lib++ 18: $ cc -v FreeBSD clang version 18.0.0git (https://github.com/llvm/llvm-project.git llvmorg-18-init-16864-g3b3ee1f53424) Target: x86_64-unknown-freebsd15.0 Thread model: posix InstalledDir: /usr/bin $ c++ -O2 -pipe test-stdexcept.cpp -o test-stdexcept ld: error: undefined hidden symbol: std::__1::enable_if<is_move_constructible<int>::value && is_move_assignable<int>::value, void>::type std::__1::swap[abi:se180000]<int>(int&, int&) >>> referenced by test-stdexcept.cpp >>> /home/dim/tmp/test-stdexcept-3a5a3e.o:(main) c++: error: linker command failed with exit code 1 (use -v to see invocation) *** Error code 1