aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-26 21:20:37 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-26 21:20:37 +0000
commitb145ee6cc7d7db42ca4351ff3fe91f04e86a2f67 (patch)
tree3feec0884a90652a1ca8b00bfbf0d173d3fc5b93
parent8ec14e605725a87991f622d63f547f877ba59fef (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124321 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--lib/Sema/SemaOverload.cpp18
-rw-r--r--test/CXX/over/over.load/p2-0x.cpp11
3 files changed, 29 insertions, 5 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b186ca79ed..3d9d8d38be 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6d5eb8038d..0b01332700 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -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;
diff --git a/test/CXX/over/over.load/p2-0x.cpp b/test/CXX/over/over.load/p2-0x.cpp
index 93ca0222a3..f0ace9044a 100644
--- a/test/CXX/over/over.load/p2-0x.cpp
+++ b/test/CXX/over/over.load/p2-0x.cpp
@@ -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}}
};