pocoproject / poco

The POCO C++ Libraries are powerful cross-platform C++ libraries for building network- and internet-based applications that run on desktop, server, mobile, IoT, and embedded systems.
https://pocoproject.org
Other
8.33k stars 2.15k forks source link

libcxx: error: implicit instantiation of undefined template 'std::char_traits<unsigned char>' #4722

Open 2xsaiko opened 2 days ago

2xsaiko commented 2 days ago

Describe the bug With LLVM/Clang/libcxx 19.1.0 on Gentoo Linux, POCO fails to compile with the following error:

In file included from /var/tmp/portage/dev-libs/poco-1.13.3/work/poco-poco-1.13.3-release/Data/src/AbstractPreparation.cpp:15:
In file included from /var/tmp/portage/dev-libs/poco-1.13.3/work/poco-poco-1.13.3-release/Data/include/Poco/Data/AbstractPreparation.h:21:
In file included from /var/tmp/portage/dev-libs/poco-1.13.3/work/poco-poco-1.13.3-release/Data/include/Poco/Data/Data.h:23:
In file included from /var/tmp/portage/dev-libs/poco-1.13.3/work/poco-poco-1.13.3-release/Foundation/include/Poco/Foundation.h:94:
/usr/include/c++/v1/string:820:42: error: implicit instantiation of undefined template 'std::char_traits<unsigned char>'
  820 |   static_assert(is_same<_CharT, typename traits_type::char_type>::value,
      |                                          ^
/usr/include/c++/v1/__type_traits/is_constructible.h:42:62: note: in instantiation of template class 'std::basic_string<unsigned char>' requested here
   42 |     : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {};
      |                                                              ^
/usr/include/c++/v1/__type_traits/is_swappable.h:43:39: note: in instantiation of template class 'std::is_move_constructible<Poco::Data::LOB<unsigned char>>' requested here
   43 | using __swap_result_t = __enable_if_t<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>;
      |                                       ^
/usr/include/c++/v1/__type_traits/is_swappable.h:50:60: note: in instantiation of template type alias '__swap_result_t' requested here
   50 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp> swap(_Tp& __x, _Tp& __y)
      |                                                            ^
/var/tmp/portage/dev-libs/poco-1.13.3/work/poco-poco-1.13.3-release/Data/include/Poco/Data/LOB.h:243:14: note: while substituting explicitly-specified template arguments into function template 'swap' 
  243 |         inline void swap<Poco::Data::BLOB>(Poco::Data::BLOB& b1, Poco::Data::BLOB& b2) noexcept
      |                     ^
/usr/include/c++/v1/__fwd/string.h:23:29: note: template is declared here
   23 | struct _LIBCPP_TEMPLATE_VIS char_traits;
      |                             ^

This error occurs because of this line which instantiates std::basic_string\<unsigned char> for BLOB which is not defined in libcxx.

I have a patch here that disables that constructor in case basic_string\<T> is not instantiable and fixes compilation.

However I'm not sure if it isn't my system that's hosed in some way since a complete compilation failure would have surely been caught already since libcxx is used for Mac builds, right?

To Reproduce Compile POCO with clang 19 linking against libcxx.

Expected behavior POCO compiles

Logs https://940705.bugs.gentoo.org/attachment.cgi?id=904816

Please add relevant environment information:

Additional context Gentoo bug 940705

2xsaiko commented 2 days ago

Ah, this is a new change in libcxx 19: https://bugs.gentoo.org/939897#c0

matejk commented 1 day ago

Poco requires standard C++-17.

IMO the compiler and libcxx that are used to show the reported problem do not handle C++-17 properly.

2xsaiko commented 1 day ago

If I look at this correctly, only char_traits\<char> is defined in the standard. https://en.cppreference.com/w/cpp/string/char_traits

matejk commented 1 day ago

Your patch looks sane. OTOH it might also make sense to provide LOB ctors only for std::string and std::wstring.

2xsaiko commented 1 day ago

I've opened a PR. Feel free to close it if you have a better solution. I tried to add a constructor that takes std::string specifically to LOB with a specialization but then realized specializations don't work like that so I assume that would have to be done using enable_if too :^)