https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97059
Bug ID: 97059 Summary: C++20: compound requirement uses inconsistent return type (adds ref) Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: dimitri.gorokhovik at free dot fr Target Milestone: --- The following code: #include <concepts> template <std::size_t N> struct s { constexpr static auto const n = N; }; template <typename T> concept S = requires (T t) { { t.n } -> std::same_as <const std::size_t #if NOBUG & #endif >; requires std::is_same_v <decltype (t.n), const std::size_t>; }; decltype (auto) f (S s) { return s.n; }; static_assert (std::is_same_v <decltype (f (s <1> {})), std::size_t>); static_assert (S <s <1>>); when compiled as: g++ -std=c++20 -fconcepts-ts -fconcepts-diagnostics-depth=25 -Wall -Wextra -W -O3 -o bug-4.o -c bug-4.cpp breaks (messages below). Compilation succeeds when NOBUG is defined, i.e., the compound requirement '{ t.n } ->' produces the return type as 'const std::size_t &' instead of 'const std::size_t'. Which is inconsistent elsewhere (see the source code above). Version: g++ (GCC) 11.0.0 20200910 (experimental) Diagnostic messages: bug-4.cpp:15:53: error: no matching function for call to ‘f(s<1>)’ 15 | static_assert (std::is_same_v <decltype (f (s <1> {})), std::size_t>); | ^ bug-4.cpp:13:17: note: candidate: ‘template<class auto:1> requires S<auto:1> decltype(auto) f(auto:1)’ 13 | decltype (auto) f (S v) { return v.n; }; | ^ bug-4.cpp:13:17: note: template argument deduction/substitution failed: bug-4.cpp:13:17: note: constraints not satisfied bug-4.cpp: In substitution of ‘template<class auto:1> requires S<auto:1> decltype(auto) f(auto:1) [with auto:1 = s<1>]’: bug-4.cpp:15:53: required from here bug-4.cpp:7:9: required for the satisfaction of ‘S<auto:1>’ [with auto:1 = s<1>] bug-4.cpp:7:13: in requirements with ‘T t’ [with T = s<1>] bug-4.cpp:9:5: note: ‘t.n’ does not satisfy return-type-requirement, because 9 | { t.n } -> std::same_as <const std::size_t>; | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bug-4.cpp:9:5: error: deduced expression type does not satisfy placeholder constraints bug-4.cpp:9:5: note: constraints not satisfied In file included from bug-4.cpp:1: /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:57:15: required for the satisfaction of ‘__same_as<_Tp, _Up>’ [with _Tp = const long unsigned int&; _Up = const long unsigned int] /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:62:13: required for the satisfaction of ‘same_as<const long unsigned int&, const long unsigned int>’ /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:57:32: note: the expression ‘is_same_v<_Tp, _Up> [with _Tp = const long unsigned int&; _Up = const long unsigned int]’ evaluated to ‘false’ 57 | concept __same_as = std::is_same_v<_Tp, _Up>; | ~~~~~^~~~~~~~~~~~~~~~~~~ bug-4.cpp:15:53: error: no matching function for call to ‘f(s<1>)’ 15 | static_assert (std::is_same_v <decltype (f (s <1> {})), std::size_t>); | ^ bug-4.cpp:13:17: note: candidate: ‘template<class auto:1> requires S<auto:1> decltype(auto) f(auto:1)’ 13 | decltype (auto) f (S v) { return v.n; }; | ^ bug-4.cpp:13:17: note: template argument deduction/substitution failed: bug-4.cpp:13:17: note: constraints not satisfied bug-4.cpp: In substitution of ‘template<class auto:1> requires S<auto:1> decltype(auto) f(auto:1) [with auto:1 = s<1>]’: bug-4.cpp:15:53: required from here bug-4.cpp:7:9: required for the satisfaction of ‘S<auto:1>’ [with auto:1 = s<1>] bug-4.cpp:7:13: in requirements with ‘T t’ [with T = s<1>] bug-4.cpp:9:5: note: ‘t.n’ does not satisfy return-type-requirement, because 9 | { t.n } -> std::same_as <const std::size_t>; | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bug-4.cpp:9:5: error: deduced expression type does not satisfy placeholder constraints bug-4.cpp:9:5: note: constraints not satisfied In file included from bug-4.cpp:1: /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:57:15: required for the satisfaction of ‘__same_as<_Tp, _Up>’ [with _Tp = const long unsigned int&; _Up = const long unsigned int] /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:62:13: required for the satisfaction of ‘same_as<const long unsigned int&, const long unsigned int>’ /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:57:32: note: the expression ‘is_same_v<_Tp, _Up> [with _Tp = const long unsigned int&; _Up = const long unsigned int]’ evaluated to ‘false’ 57 | concept __same_as = std::is_same_v<_Tp, _Up>; | ~~~~~^~~~~~~~~~~~~~~~~~~ bug-4.cpp:15:21: error: template argument 1 is invalid 15 | static_assert (std::is_same_v <decltype (f (s <1> {})), std::size_t>); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bug-4.cpp:16:16: error: static assertion failed 16 | static_assert (S <s <1>>); | ^~~~~~~~~ bug-4.cpp:16:16: note: constraints not satisfied bug-4.cpp:7:9: required by the constraints of ‘template<class T> concept S’ bug-4.cpp:7:13: in requirements with ‘T t’ [with T = s<1>] bug-4.cpp:9:5: note: ‘t.n’ does not satisfy return-type-requirement, because 9 | { t.n } -> std::same_as <const std::size_t>; | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bug-4.cpp:9:5: error: deduced expression type does not satisfy placeholder constraints bug-4.cpp:9:5: note: constraints not satisfied In file included from bug-4.cpp:1: /home/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:57:15: required for the satisfaction of ‘__same_as<_Tp, _Up>’ [with _Tp = const long unsigned int&; _Up = const long unsigned int] /home/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:62:13: required for the satisfaction of ‘same_as<const long unsigned int&, const long unsigned int>’ /home/dgorokho/gcc-trunk/trunk/dist/include/c++/11.0.0/concepts:57:32: note: the expression ‘is_same_v<_Tp, _Up> [with _Tp = const long unsigned int&; _Up = const long unsigned int]’ evaluated to ‘false’ 57 | concept __same_as = std::is_same_v<_Tp, _Up>; | ~~~~~^~~~~~~~~~~~~~~~~~~