rnpgp / sexpp

C++ Library for SEXP (S-expressions)
Other
7 stars 4 forks source link

clang-18: error: implicit instantiation of undefined template 'std::char_traits<unsigned char>' #51

Closed maflcko closed 2 months ago

maflcko commented 3 months ago

With clang-18 and libc++ compile failures are observed: (Tested via the OSS-Fuzz config)

In file included from /src/rnp/src/libsexpp/src/ext-key-format.cpp:24:
In file included from /src/rnp/src/libsexpp/include/sexpp/ext-key-format.h:26:
In file included from /usr/local/bin/../include/c++/v1/map:2529:
In file included from /usr/local/bin/../include/c++/v1/functional:526:
In file included from /usr/local/bin/../include/c++/v1/__functional/boyer_moore_searcher.h:27:
In file included from /usr/local/bin/../include/c++/v1/vector:321:
In file included from /usr/local/bin/../include/c++/v1/__format/formatter_bool.h:20:
In file included from /usr/local/bin/../include/c++/v1/__format/formatter_integral.h:21:
In file included from /usr/local/bin/../include/c++/v1/__format/formatter_output.h:22:
In file included from /usr/local/bin/../include/c++/v1/__format/parser_std_format_spec.h:39:
/usr/local/bin/../include/c++/v1/string:2374:20: error: incomplete definition of type 'std::char_traits<unsigned char>'
 2374 |         traits_type::copy(std::__to_address(__p) + __n_copy + __n_add,
      |         ~~~~~~~~~~~^~
/usr/local/bin/../include/c++/v1/string:2410:5: error: implicit instantiation of undefined template 'std::char_traits<unsigned char>'
 2410 |     traits_type::copy(std::__to_address(__p), __s, __n);
      |     ^
/usr/local/bin/../include/c++/v1/string:2495:16: note: in instantiation of function template specialization 'std::basic_string<unsigned char>::__assign_no_alias<true>' requested here
 2495 |         return __assign_no_alias<true>(__str.data(), __str.size());
      |                ^
/src/rnp/src/libsexpp/include/sexpp/sexp.h:104:26: note: in instantiation of member function 'std::basic_string<unsigned char>::operator=' requested here
  104 | class SEXP_PUBLIC_SYMBOL sexp_simple_string_t : public std::basic_string<octet_t>,
      |                          ^
/usr/local/bin/../include/c++/v1/__fwd/string.h:23:29: note: template is declared here
   23 | struct _LIBCPP_TEMPLATE_VIS char_traits;
      |                             ^

Could it make sense to update the submodule in src/libsexpp to provide an specialization of char_traits for unsigned char, or maybe it would be easier to use one of the pre-defined char_traits?

diff --git a/include/sexpp/sexp.h b/include/sexpp/sexp.h
index bb6ae4e..55e0c67 100644
--- a/include/sexpp/sexp.h
+++ b/include/sexpp/sexp.h
@@ -99,7 +99,7 @@ class sexp_input_stream_t;
  * SEXP simple string
  */

-typedef uint8_t octet_t;
+typedef char octet_t;

 class SEXP_PUBLIC_SYMBOL sexp_simple_string_t : public std::basic_string<octet_t>,
                                                 private sexp_char_defs_t {

Edit: Context:

ni4 commented 3 months ago

Thanks for noticing! CC @maxirmx

maxirmx commented 3 months ago

As far as I remember we need unsigned type. Something like char8_t as defined in C++20 Frankly speaking, I thought that char8_t was a codification of some options that were provided by default definition of std::char_traits but the life is not that friendly 👎

I would probably change SEXP simple string to std::vector. Now when there is a good test coverage it shall be safe.

maxirmx commented 3 months ago

I realized that we cannot change signature for sexp_simple_string since libsexpp is deployed as shared library

We will need to provide an specialization of char_traits for octet_t (unsigned char)