`test/streams_tests.cpp` fails to compile on SunOS / illumos #29884

issue hebasto opened this issue on April 15, 2024
  1. hebasto commented at 9:02 PM on April 15, 2024: member

    While testing bitcoin/bitcoin#29484, which seems not related to this bug, I've notice the following failure:

    $ ./autogen.sh
    $ ./configure
    $ gmake -C src test/test_bitcoin
    ...
      CXX      test/test_bitcoin-streams_tests.o
    In file included from test/streams_tests.cpp:5:
    ./streams.h: In instantiation of 'SpanReader& SpanReader::operator>>(T&&) [with T = signed char&]':
    test/streams_tests.cpp:148:15:   required from here
    ./streams.h:114:22: error: no matching function for call to 'Unserialize(SpanReader&, signed char&)'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    In file included from ./streams.h:9:
    ./serialize.h:284:48: note: candidate: 'template<class Stream, class V>  requires  CharNotInt8<V> void Unserialize(Stream&, V)' (deleted)
      284 | template <typename Stream, CharNotInt8 V> void Unserialize(Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
          |                                                ^~~~~~~~~~~
    ./serialize.h:284:48: note:   template argument deduction/substitution failed:
    ./serialize.h:284:48: note: constraints not satisfied
    In file included from /usr/gcc/13/include/c++/13.2.0/compare:37,
                     from /usr/gcc/13/include/c++/13.2.0/bits/stl_pair.h:65,
                     from /usr/gcc/13/include/c++/13.2.0/bits/stl_algobase.h:64,
                     from /usr/gcc/13/include/c++/13.2.0/algorithm:60,
                     from ./prevector.h:13,
                     from ./serialize.h:12:
    /usr/gcc/13/include/c++/13.2.0/concepts: In substitution of 'template<class Stream, class V>  requires  CharNotInt8<V> void Unserialize(Stream&, V) [with Stream = SpanReader; V = signed char]':
    ./streams.h:114:22:   required from 'SpanReader& SpanReader::operator>>(T&&) [with T = signed char&]'
    test/streams_tests.cpp:148:15:   required from here
    /usr/gcc/13/include/c++/13.2.0/concepts:57:15:   required for the satisfaction of '__same_as<_Tp, _Up>' [with _Tp = signed char; _Up = char]
    /usr/gcc/13/include/c++/13.2.0/concepts:62:13:   required for the satisfaction of 'same_as<T, char>' [with T = signed char]
    ./serialize.h:268:9:   required for the satisfaction of 'CharNotInt8<V>' [with V = signed char]
    /usr/gcc/13/include/c++/13.2.0/concepts:57:32: note: the expression 'is_same_v<_Tp, _Up> [with _Tp = signed char; _Up = char]' evaluated to 'false'
       57 |       concept __same_as = std::is_same_v<_Tp, _Up>;
          |                           ~~~~~^~~~~~~~~~~~~~~~~~~
    ./streams.h: In instantiation of 'SpanReader& SpanReader::operator>>(T&&) [with T = signed char&]':
    test/streams_tests.cpp:148:15:   required from here
    ./serialize.h:285:33: note: candidate: 'template<class Stream> void Unserialize(Stream&, std::byte&)'
      285 | template <typename Stream> void Unserialize(Stream& s, std::byte& a) { a = std::byte{ser_readdata8(s)}; }
          |                                 ^~~~~~~~~~~
    ./serialize.h:285:33: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'std::byte&'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:286:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, int8_t&)'
      286 | template<typename Stream> inline void Unserialize(Stream& s, int8_t& a  ) { a = ser_readdata8(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:286:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'int8_t&' {aka 'char&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:287:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, uint8_t&)'
      287 | template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a ) { a = ser_readdata8(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:287:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'uint8_t&' {aka 'unsigned char&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:288:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, int16_t&)'
      288 | template<typename Stream> inline void Unserialize(Stream& s, int16_t& a ) { a = ser_readdata16(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:288:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'int16_t&' {aka 'short int&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:289:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, uint16_t&)'
      289 | template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a) { a = ser_readdata16(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:289:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'uint16_t&' {aka 'short unsigned int&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:290:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, int32_t&)'
      290 | template<typename Stream> inline void Unserialize(Stream& s, int32_t& a ) { a = ser_readdata32(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:290:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'int32_t&' {aka 'int&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:291:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, uint32_t&)'
      291 | template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a) { a = ser_readdata32(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:291:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'uint32_t&' {aka 'unsigned int&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:292:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, int64_t&)'
      292 | template<typename Stream> inline void Unserialize(Stream& s, int64_t& a ) { a = ser_readdata64(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:292:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'int64_t&' {aka 'long int&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:293:39: note: candidate: 'template<class Stream> void Unserialize(Stream&, uint64_t&)'
      293 | template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a) { a = ser_readdata64(s); }
          |                                       ^~~~~~~~~~~
    ./serialize.h:293:39: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'uint64_t&' {aka 'long unsigned int&'}
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:294:53: note: candidate: 'template<class Stream, class B, int N>  requires  BasicByte<B> void Unserialize(Stream&, B (&)[N])'
      294 | template <typename Stream, BasicByte B, int N> void Unserialize(Stream& s, B (&a)[N]) { s.read(MakeWritableByteSpan(a)); }
          |                                                     ^~~~~~~~~~~
    ./serialize.h:294:53: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'B [N]' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:295:61: note: candidate: 'template<class Stream, class B, long unsigned int N>  requires  BasicByte<B> void Unserialize(Stream&, std::array<_Tp, _Nm>&)'
      295 | template <typename Stream, BasicByte B, std::size_t N> void Unserialize(Stream& s, std::array<B, N>& a) { s.read(MakeWritableByteSpan(a)); }
          |                                                             ^~~~~~~~~~~
    ./serialize.h:295:61: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::array<_Tp, _Nm>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:296:46: note: candidate: 'template<class Stream, class B>  requires  BasicByte<B> void Unserialize(Stream&, Span<O>)'
      296 | template <typename Stream, BasicByte B> void Unserialize(Stream& s, Span<B> span) { s.read(AsWritableBytes(span)); }
          |                                              ^~~~~~~~~~~
    ./serialize.h:296:46: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'Span<O>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:299:40: note: candidate: 'template<class Stream> void Unserialize(Stream&, bool&)'
      299 | template <typename Stream> inline void Unserialize(Stream& s, bool& a) { uint8_t f = ser_readdata8(s); a = f; }
          |                                        ^~~~~~~~~~~
    ./serialize.h:299:40: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   cannot convert 'obj' (type 'signed char') to type 'bool&'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:809:6: note: candidate: 'template<class Stream, class C> void Unserialize(Stream&, std::__cxx11::basic_string<C>&)'
      809 | void Unserialize(Stream& is, std::basic_string<C>& str)
          |      ^~~~~~~~~~~
    ./serialize.h:809:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::__cxx11::basic_string<C>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:835:6: note: candidate: 'template<class Stream, unsigned int N, class T> void Unserialize(Stream&, prevector<N, T>&)'
      835 | void Unserialize(Stream& is, prevector<N, T>& v)
          |      ^~~~~~~~~~~
    ./serialize.h:835:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'prevector<N, T>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:878:6: note: candidate: 'template<class Stream, class T, class A> void Unserialize(Stream&, std::vector<_ValT, _Allocator>&)'
      878 | void Unserialize(Stream& is, std::vector<T, A>& v)
          |      ^~~~~~~~~~~
    ./serialize.h:878:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::vector<_ValT, _Allocator>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:908:6: note: candidate: 'template<class Stream, class K, class T> void Unserialize(Stream&, std::pair<_Tp1, _Tp2>&)'
      908 | void Unserialize(Stream& is, std::pair<K, T>& item)
          |      ^~~~~~~~~~~
    ./serialize.h:908:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::pair<_Tp1, _Tp2>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:928:6: note: candidate: 'template<class Stream, class K, class T, class Pred, class A> void Unserialize(Stream&, std::map<K, T, Pred, A>&)'
      928 | void Unserialize(Stream& is, std::map<K, T, Pred, A>& m)
          |      ^~~~~~~~~~~
    ./serialize.h:928:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::map<K, T, Pred, A>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:955:6: note: candidate: 'template<class Stream, class K, class Pred, class A> void Unserialize(Stream&, std::set<K, Pred, A>&)'
      955 | void Unserialize(Stream& is, std::set<K, Pred, A>& m)
          |      ^~~~~~~~~~~
    ./serialize.h:955:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::set<K, Pred, A>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:997:6: note: candidate: 'template<class Stream, class T> void Unserialize(Stream&, std::shared_ptr<const T>&)'
      997 | void Unserialize(Stream& is, std::shared_ptr<const T>& p)
          |      ^~~~~~~~~~~
    ./serialize.h:997:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::shared_ptr<const T>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:980:6: note: candidate: 'template<class Stream, class T> void Unserialize(Stream&, std::unique_ptr<const T>&)'
      980 | void Unserialize(Stream& is, std::unique_ptr<const T>& p)
          |      ^~~~~~~~~~~
    ./serialize.h:980:6: note:   template argument deduction/substitution failed:
    ./streams.h:114:22: note:   mismatched types 'std::unique_ptr<const T>' and 'signed char'
      114 |         ::Unserialize(*this, obj);
          |         ~~~~~~~~~~~~~^~~~~~~~~~~~
    ./serialize.h:774:6: note: candidate: 'template<class Stream, class T>  requires  Unserializable<T, Stream> void Unserialize(Stream&, T&&)'
      774 | void Unserialize(Stream& is, T&& a)
          |      ^~~~~~~~~~~
    ./serialize.h:774:6: note:   template argument deduction/substitution failed:
    ./serialize.h:774:6: note: constraints not satisfied
    ./serialize.h: In substitution of 'template<class Stream, class T>  requires  Unserializable<T, Stream> void Unserialize(Stream&, T&&) [with Stream = SpanReader; T = signed char&]':
    ./streams.h:114:22:   required from 'SpanReader& SpanReader::operator>>(T&&) [with T = signed char&]'
    test/streams_tests.cpp:148:15:   required from here
    ./serialize.h:771:9:   required for the satisfaction of 'Unserializable<T, Stream>' [with T = signed char&; Stream = SpanReader]
    ./serialize.h:771:26:   in requirements with 'T a', 'Stream s' [with T = signed char&; Stream = SpanReader]
    ./serialize.h:771:65: note: the required expression 'a.Unserialize(s)' is invalid
      771 | concept Unserializable = requires(T a, Stream s) { a.Unserialize(s); };
          |                                                    ~~~~~~~~~~~~~^~~
    ./streams.h: In instantiation of 'SpanReader& SpanReader::operator>>(T&&) [with T = signed char&]':
    test/streams_tests.cpp:148:15:   required from here
    ...
    

    I believe, it has been broken since #12254.


    System and compiler details:

    $ uname -a
    SunOS openindiana 5.11 illumos-064d431af1 i86pc i386 i86pc
    $ g++ --version
    g++ (OpenIndiana 13.2.0-oi-3) 13.2.0
    Copyright (C) 2023 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    
  2. hebasto added the label Bug on Apr 15, 2024
  3. hebasto added the label Build system on Apr 15, 2024
  4. hebasto added the label Linux/Unix on Apr 15, 2024
  5. maflcko commented at 7:37 AM on April 16, 2024: member

    Using char is not allowed in serialization code, because the sign of char is unknown/unclear. However, on some systems, int8_t==char, which means that signed char has no serialization helper.

    This could be fixed in the serialization code by replacing int8_t by a concept of !CharNotInt8 || std::same_as<T, signed char>. However, my preference would be to completely avoid signed char and just use int8_t in the serialization code. That is, fix the test to use int8_t.

  6. hebasto commented at 8:53 AM on April 16, 2024: member

    However, my preference would be to completely avoid signed char and just use int8_t in the serialization code. That is, fix the test to use int8_t.

    I lean to agree, considering that signed char is used in tests only.

  7. maflcko commented at 9:04 AM on April 16, 2024: member

    Happy to review a pull, if someone creates one.

  8. hebasto commented at 8:31 PM on April 18, 2024: member

    Happy to review a pull, if someone creates one.

    Please see #29907.

  9. fanquake closed this on May 4, 2024

  10. fanquake referenced this in commit 61d3280c3a on May 4, 2024
  11. PastaPastaPasta referenced this in commit 4e8fbdd865 on Oct 25, 2024
  12. PastaPastaPasta referenced this in commit 61a5832a6a on Oct 26, 2024
  13. bitcoin locked this on May 4, 2025

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-29 15:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me