Implement the restriction that a function with a ref-qualifier cannot

overload a function without a ref-qualifier (C++0x
[over.load]p2). This, apparently, completes the implementation of
rvalue references for *this.

llvm-svn: 124321
This commit is contained in:
Douglas Gregor 2011-01-26 21:20:37 +00:00
parent 084e0628e0
commit c83f9865a0
3 changed files with 29 additions and 5 deletions

View File

@ -2481,6 +2481,11 @@ def err_invalid_ref_qualifier_typedef_function_type_use : Error<
"%select{static member|nonmember}0 function cannot have a ref-qualifier "
"'%select{&&|&}1'">;
def err_ref_qualifier_overload : Error<
"cannot overload a member function %select{without a ref-qualifier|with "
"ref-qualifier '&'|with ref-qualifier '&&'}0 with a member function %select{"
"without a ref-qualifier|with ref-qualifier '&'|with ref-qualifier '&&'}1">;
def err_invalid_non_static_member_use : Error<
"invalid use of nonstatic data member %0">;
def err_invalid_incomplete_type_use : Error<

View File

@ -694,8 +694,24 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
if (OldMethod && NewMethod &&
!OldMethod->isStatic() && !NewMethod->isStatic() &&
(OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers() ||
OldMethod->getRefQualifier() != NewMethod->getRefQualifier()))
OldMethod->getRefQualifier() != NewMethod->getRefQualifier())) {
if (!UseUsingDeclRules &&
OldMethod->getRefQualifier() != NewMethod->getRefQualifier() &&
(OldMethod->getRefQualifier() == RQ_None ||
NewMethod->getRefQualifier() == RQ_None)) {
// C++0x [over.load]p2:
// - Member function declarations with the same name and the same
// parameter-type-list as well as member 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).
Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
<< NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
Diag(OldMethod->getLocation(), diag::note_previous_declaration);
}
return true;
}
// The signatures match; this is not an overload.
return false;

View File

@ -10,12 +10,15 @@ class Y {
void h() &;
void h() const &;
void h() &&;
void i() &;
void i() const; // FIXME: expected an error here!
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*) &;
template<typename T> void g(T*); // FIXME: expected an error here
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}}
};