https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110765
Bug ID: 110765 Summary: [13 regression] constraints on parameters of derived type in CRTP base Product: gcc Version: 13.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: h2+bugs at fsfe dot org Target Milestone: --- Created attachment 55595 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55595&action=edit GCC12's intermediate code; build with -std=c++20 I have large parts of library code that fail to build with GCC13, although they build with GCC10-12 and Clang-16. I have attached GCC12's intermediate code that compiles cleanly with GCC12 but fails to build with GCC13. The error is the same as when building the actual code. See logs below. Playing a bit around with the code seems to indicate that constrained friend declarations in the CRTP base that references the derived class could be the problem: Triggering code: ```cpp friend constexpr auto tag_invoke(custom::to_char, derived_type const a) noexcept requires(requires { { a.to_char() }; }) { return a.to_char(); } ``` Workaround: ```cpp friend constexpr auto tag_invoke(custom::to_char, std::same_as<derived_type> auto const a) noexcept requires(requires { { a.to_char() }; }) { return a.to_char(); } ``` It seems that GCC13 tries to check the constraints on the derived class earlier than previous GCCs and Clang, and apparently before the type is complete. Passes: % g++12 --version g++12 (FreeBSD Ports Collection) 12.2.0 %g++12 -std=c++20 a-test.ii % Fails: % g++13 --version g++13 (FreeBSD Ports Collection) 13.1.1 20230701 % g++13 -std=c++20 a-test.ii In file included from /usr/local/lib/gcc12/include/c++/bits/stl_pair.h:60, from /usr/local/lib/gcc12/include/c++/bits/stl_algobase.h:64, from /usr/local/lib/gcc12/include/c++/vector:60, from /home/hannes/devel/biocpp-core/include/bio/alphabet/nucleotide/dna4.hpp:16, from test.cpp:1: /usr/local/lib/gcc12/include/c++/type_traits:1522:12: error: expected identifier before '__is_nothrow_convertible' 1522 | struct __is_nothrow_convertible | ^~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/lib/gcc12/include/c++/type_traits:1522:12: error: expected unqualified-id before '__is_nothrow_convertible' /usr/local/lib/gcc12/include/c++/type_traits:3083:66: error: template argument 2 is invalid 3083 | __is_nothrow_convertible<typename _Result::type, _Ret>> | ^~ In file included from /usr/local/lib/gcc12/include/c++/memory:76, from /home/hannes/devel/biocpp-core/include/bio/meta/detail/type_inspection.hpp:21, from /home/hannes/devel/biocpp-core/include/bio/alphabet/concept.hpp:22, from /home/hannes/devel/biocpp-core/include/bio/alphabet/base.hpp:20, from /home/hannes/devel/biocpp-core/include/bio/alphabet/nucleotide/nucleotide_base.hpp:16, from /home/hannes/devel/biocpp-core/include/bio/alphabet/nucleotide/dna4.hpp:18: /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:536:15: error: expected identifier before '__remove_cv' 536 | using __remove_cv = typename remove_cv<_Up>::type; | ^~~~~~~~~~~ /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:536:27: error: expected '(' before '=' token 536 | using __remove_cv = typename remove_cv<_Up>::type; | ^ | ( /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:536:27: error: expected type-specifier before '=' token /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:536:27: error: expected unqualified-id before '=' token /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:542:69: error: wrong number of template arguments (1, should be 2) 542 | __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; | ^~ /usr/local/lib/gcc12/include/c++/type_traits:635:12: note: provided for 'template<class, class> struct std::is_same' 635 | struct is_same; | ^~~~~~~ /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:542:71: error: template argument 1 is invalid 542 | __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; | ^ /usr/local/lib/gcc12/include/c++/bits/unique_ptr.h:542:73: error: template argument 2 is invalid 542 | __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; | ^ /usr/local/lib/gcc12/include/c++/type_traits: In instantiation of 'struct std::is_nothrow_destructible<bio::alphabet::dna4>': /home/hannes/devel/biocpp-core/include/bio/alphabet/base.hpp:260:27: recursively required from 'consteval auto bio::alphabet::tag_invoke(custom::size, dna4) requires constexpr_default_initializable<derived_type>' /home/hannes/devel/biocpp-core/include/bio/alphabet/base.hpp:260:27: required from 'class bio::alphabet::base<bio::alphabet::dna4, 4, char>' /home/hannes/devel/biocpp-core/include/bio/alphabet/nucleotide/nucleotide_base.hpp:41:7: required from 'class bio::alphabet::nucleotide_base<bio::alphabet::dna4, 4>' /home/hannes/devel/biocpp-core/include/bio/alphabet/nucleotide/dna4.hpp:48:21: required from here /usr/local/lib/gcc12/include/c++/type_traits:964:52: error: static assertion failed: template argument must be a complete class or an unbounded array 964 | static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ /usr/local/lib/gcc12/include/c++/type_traits:964:52: note: 'std::__is_complete_or_unbounded<__type_identity<bio::alphabet::dna4> >((std::__type_identity<bio::alphabet::dna4>(), std::__type_identity<bio::alphabet::dna4>()))' evaluates to false test.cpp:3:30: error: static assertion failed 3 | static_assert(bio::alphabet::alphabet<bio::alphabet::dna4>); | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test.cpp:3:30: note: constraints not satisfied In file included from /usr/local/lib/gcc12/include/c++/compare:39, from /usr/local/lib/gcc12/include/c++/bits/stl_pair.h:65: /usr/local/lib/gcc12/include/c++/concepts:132:13: required for the satisfaction of 'destructible<_Tp>' [with _Tp = bio::alphabet::dna4] /usr/local/lib/gcc12/include/c++/concepts:136:13: required for the satisfaction of 'constructible_from<_Tp, _Tp>' [with _Tp = bio::alphabet::dna4] /usr/local/lib/gcc12/include/c++/concepts:150:13: required for the satisfaction of 'move_constructible<_Tp>' [with _Tp = bio::alphabet::dna4] /usr/local/lib/gcc12/include/c++/concepts:155:13: required for the satisfaction of 'copy_constructible<t>' [with t = bio::alphabet::dna4] /home/hannes/devel/biocpp-core/include/bio/alphabet/concept.hpp:562:9: required for the satisfaction of 'semialphabet<t>' [with t = bio::alphabet::dna4] /usr/local/lib/gcc12/include/c++/concepts:132:28: note: the expression 'is_nothrow_destructible_v<_Tp> [with _Tp = bio::alphabet::dna4]' evaluated to 'false' 132 | concept destructible = is_nothrow_destructible_v<_Tp>; |