https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71125

            Bug ID: 71125
           Summary: [concepts] Spurious 'invalid reference to function
                    concept error' issued when overloads are not all
                    declared with the concept specifier
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tom at honermann dot net
                CC: andrew.n.sutton at gmail dot com, asutton at gcc dot gnu.org
  Target Milestone: ---

I believe the following code is well-formed.

$ cat t.cpp
// This test case demonstrates a spurious reference to function concept error.
// The error is emitted when:
// 1: a constexpr function is declared without the concept specifier, and
// 2: an overload declared with the concept specifier follows, and
// 3: overload resolution of a function invocation in a requires clause of a
//    following constrained function declaration selects the first declaration.

template<typename T>
constexpr bool C1() { return true; }
template<typename T, typename U>
concept bool C1() { return true; }
template<typename T>
  requires C1<T>() // spurious error: invalid reference to function concept
‘template<class T, class U> constexpr bool C1()’
void f1() {}

// Removing the unused overload avoids the error:
template<typename T>
constexpr bool C2() { return true; }
template<typename T>
  requires C2<T>() // Ok.
void f2() {}

// Swapping the order of the declarations avoids the error:
template<typename T, typename U>
concept bool C3() { return true; }
template<typename T>
constexpr bool C3() { return true; }
template<typename T>
  requires C3<T>() // Ok.
void f3() {}

// Swapping the overload that is resolved avoids the error:
template<typename T>
constexpr bool C4() { return true; }
template<typename T, typename U>
concept bool C4() { return true; }
template<typename T>
  requires C4<T,int>() // Ok.
void f4() {}

// Swapping which overload is declared with the concept specifier avoids the
error:
template<typename T>
concept bool C5() { return true; }
template<typename T, typename U>
constexpr bool C5() { return true; }
template<typename T>
  requires C5<T>() // Ok.
void f5() {}


$ svn info   # From my local svn gcc repo.
Path: .
Working Copy Root Path: /home/tom/src/gcc-trunk
URL: svn://gcc.gnu.org/svn/gcc/trunk
Relative URL: ^/trunk
Repository Root: svn://gcc.gnu.org/svn/gcc
Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4
Revision: 236239
Node Kind: directory
Schedule: normal
Last Changed Author: uros
Last Changed Rev: 236238
Last Changed Date: 2016-05-14 05:07:13 -0400 (Sat, 14 May 2016)


$ g++ --version
g++ (GCC) 7.0.0 20160514 (experimental)
...

$ g++ -c -fconcepts -std=c++1z t.cpp
t.cpp:13:12: error: invalid reference to function concept ‘template<class T,
class U> constexpr bool C1()’
   requires C1<T>() // spurious error: invalid reference to function concept
‘template<class T, class U> constexpr bool C1()’
            ^~~~~

Reply via email to