Roy Jacobson 3c75feab3b [clang] Compare constraints before diagnosing mismatched ref qualifiers (GH58962)
As noticed in GH58962, we should only diagnose illegal overloads of member functions
when the ref qualifiers don't match if the trailing constraints are the same.

The fix is to move the existing constraints check earlier in Sema::IsOverload.

Closes https://github.com/llvm/llvm-project/issues/58962

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D138749
2022-11-29 14:57:26 +02:00

54 lines
1.7 KiB
C++

// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
// Member function declarations with the same name and the same
// parameter-type-list as well as mem- ber function template
// declarations with the same name, the same parameter-type-list, and
// the same template parameter lists cannot be overloaded if any of
// them, but not all, have a ref-qualifier (8.3.5).
class Y {
void h() &;
void h() const &;
void h() &&;
void i() &; // expected-note{{previous declaration}}
void i() const; // expected-error{{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&'}}
template<typename T> void f(T*) &;
template<typename T> void f(T*) &&;
template<typename T> void g(T*) &; // expected-note{{previous declaration}}
template<typename T> void g(T*); // expected-error{{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&'}}
void k(); // expected-note{{previous declaration}}
void k() &&; // expected-error{{cannot overload a member function with ref-qualifier '&&' with a member function without a ref-qualifier}}
};
#if __cplusplus >= 202002L
namespace GH58962 {
template<typename T>
__add_rvalue_reference(T) declval();
template<unsigned R>
struct type
{
void func() requires (R == 0);
void func() & requires (R == 1);
void func() && requires (R == 2);
};
template<typename T>
concept test = requires { declval<T>().func(); };
static_assert(test<type<0>&>);
static_assert(test<type<0>&&>);
static_assert(test<type<1>&>);
static_assert(not test<type<1>&&>);
static_assert(not test<type<2>&>);
static_assert(test<type<2>&&>);
}
#endif