From b145ee6cc7d7db42ca4351ff3fe91f04e86a2f67 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 26 Jan 2011 21:20:37 +0000 Subject: [PATCH] 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 --- include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++ lib/Sema/SemaOverload.cpp | 18 +++++++++++++++++- test/CXX/over/over.load/p2-0x.cpp | 11 +++++++---- 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 void f(T*) &; template void f(T*) &&; - template void g(T*) &; - template void g(T*); // FIXME: expected an error here + template void g(T*) &; // expected-note{{previous declaration}} + template 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}} }; -- 2.40.0