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

            Bug ID: 118463
           Summary: requires-clause considered ill-formed but not leading
                    to clause failure
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ing.russomauro at gmail dot com
  Target Milestone: ---

In the following code (https://godbolt.org/z/nPW7Mds6Y):

gcc does not like the expression used for the requires-clause of the first
overload. Indeed, gcc seems to consider it as ill-formed, without finally
choosing the constraints to be just failed.

I am not currently aware of all rules about concepts, but MVSC and Clang accept
the call to the implicitly instantiated f<B>, whereas gcc does not.
Note also that, in case of enabling the call to f<A>, then gcc still complains
about the requires-clause of the first overload, while also reefrring about an
ambiguous result of overload resolution, which is a bit weird to read together
the complain of ill-formed first overload.

Reconnecting to PR 118398, is the expression "k<T>();" another case of non -
immediate context ? I guess not.


//#include <concepts>
#include <iostream>
//#include <type_traits>

struct A{
    int x;
};

struct B{
    int y;
};

template<typename T>
requires (!requires{k<T>();}) // accepted by Clang and MVSC, not gcc, with
error
                              // " no arguments ... that depend on a template
                              //   parameter, so a declaration ... must be
                              //   available "
//requires (!requires{k();}) // second alternative:
                             // accepted by Clang and MVSC, not gcc (with the
                             // same kind of compilation error)
//requires (!requires(T t){k(t);}) this alternative is accepted by gcc, too.
void f()
{std::cout << "first overload\n";}

template<typename T>
requires requires(T t){t.x;}
void f()
{std::cout << "second overload\n";}


int main(){
    // f<A>(); // all consider it ambiguous, even gcc, that refers ambiguity
    //         a bit weirdly, that is, despite gcc raises the error on 'k'
    //         for the requires-clause of the first overload.

    f<B>();

    return 0;
}

Reply via email to