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>;
      |                           ~~~~~^~~~~~~~~~~~~~~~~~~

Reply via email to