I think this falls under https://github.com/itanium-cxx-abi/cxx-abi/issues/24. I suggest adding the example to that issue.

Tom.

On 3/3/21 11:50 AM, v.S. F. via Std-Discussion wrote:

A virtual function cannot have a trailing requires-clause. However, while a virtual function is present in a class or class template, currently there is nothing prohibiting a non-virtual non-member function with the same parameter-type-list, the same cv-qualifiers (if any) and ref-qualifier (if any), and a trialing requires-clause to be declared in the same class or class template, because the two declarations do not correspond ([basic.scope.scope]/(3.3.1)).

So following code is currently well-formed, where both the virtual and the non-virtual overloads are odr-used:

template<int N>

struct Foo {

virtual int bar() const { return N; }

int bar() const requires (N > 0) { return 0; }

};

int main()

{

Foo<42>{}.bar();

}

But such overloading cannot be properly supported on Itanium C++ ABI, where two Foo<42>::bar overloads share the same mangled name "_ZNK3FooILi42EE3barEv. Clang 11 accepts it with option -std=c++2a -O2 (https://gcc.godbolt.org/z/fP4YTf) but rejects it with option -std=c++2a (https://gcc.godbolt.org/z/rE8sjP).

On the other hand, such overloading can be supported by MSVC, because mangled names of virtual and non-virtual functions are always different on MS ABI.

I think this kind of overloading should be conditionally supported, and diagnostic should be required on platforms that cannot support it properly.

(I have mailed to wmm@edg.com twice for this issue but have not been replied yet.)

Jiang An