Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1582,12 +1582,20 @@ def ext_pure_function_definition : ExtWarn< "function definition with pure-specifier is a Microsoft extension">, InGroup; -def err_implicit_object_parameter_init : Error< - "cannot initialize object parameter of type %0 with an expression " - "of type %1">; def err_qualified_member_of_unrelated : Error< "%q0 is not a member of class %1">; +def err_member_function_call_bad_ref : Error< + "'this' argument to member function %0 is an %select{lvalue|rvalue}1, " + "but function has %select{non-const lvalue|rvalue}2 ref-qualifier">; +def err_member_function_call_bad_cvr : Error< + "'this' argument to member function %0 has type %1, but function is not marked " + "%select{const|restrict|const or restrict|volatile|const or volatile|" + "volatile or restrict|const, volatile, or restrict}2">; +def err_member_function_call_other : Error< + "cannot initialize object parameter of type %0 with an expression " + "of type %1">; + def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning< "call to pure virtual member function %0 has undefined behavior; " "overrides of %0 in subclasses are not available in the " @@ -1808,10 +1816,6 @@ def err_init_list_bad_dest_type : Error< "%select{|non-aggregate }0type %1 cannot be initialized with an initializer " "list">; -def err_member_function_call_bad_cvr : Error<"member function %0 not viable: " - "'this' argument has type %1, but function is not marked " - "%select{const|restrict|const or restrict|volatile|const or volatile|" - "volatile or restrict|const, volatile, or restrict}2">; def err_reference_bind_to_bitfield : Error< "%select{non-const|volatile}0 reference cannot bind to " Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5145,7 +5145,8 @@ *this, From->getLocStart(), From->getType(), FromClassification, Method, Method->getParent()); if (ICS.isBad()) { - if (ICS.Bad.Kind == BadConversionSequence::bad_qualifiers) { + switch (ICS.Bad.Kind) { + case BadConversionSequence::bad_qualifiers: { Qualifiers FromQs = FromRecordType.getQualifiers(); Qualifiers ToQs = DestType.getQualifiers(); unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers(); @@ -5158,10 +5159,27 @@ << Method->getDeclName(); return ExprError(); } + break; + } + + case BadConversionSequence::lvalue_ref_to_rvalue: + case BadConversionSequence::rvalue_ref_to_lvalue: { + bool IsRValueQualified = + Method->getRefQualifier() == RefQualifierKind::RQ_RValue; + Diag(From->getLocStart(), diag::err_member_function_call_bad_ref) + << Method->getDeclName() << FromClassification.isRValue() + << IsRValueQualified; + Diag(Method->getLocation(), diag::note_previous_decl) + << Method->getDeclName(); + return ExprError(); + } + + default: + break; } return Diag(From->getLocStart(), - diag::err_implicit_object_parameter_init) + diag::err_member_function_call_other) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); } Index: test/CXX/over/over.match/over.match.funcs/p4-0x.cpp =================================================================== --- test/CXX/over/over.match/over.match.funcs/p4-0x.cpp +++ test/CXX/over/over.match/over.match.funcs/p4-0x.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics template T &lvalue(); template T &&xvalue(); @@ -20,6 +19,10 @@ void g(); + void lvalue() &; // expected-note 2 {{'lvalue' declared here}} + void const_lvalue() const&; + void rvalue() &&; // expected-note {{'rvalue' declared here}} + int &operator+(const X0&) &; float &operator+(const X0&) &&; @@ -44,6 +47,18 @@ int &ir2 = lvalue().ft(1); float &fr3 = xvalue().ft(2); float &fr4 = prvalue().ft(3); + + lvalue().lvalue(); + lvalue().const_lvalue(); + lvalue().rvalue(); // expected-error {{'this' argument to member function 'rvalue' is an lvalue, but function has rvalue ref-qualifier}} + + xvalue().lvalue(); // expected-error {{'this' argument to member function 'lvalue' is an rvalue, but function has non-const lvalue ref-qualifier}} + xvalue().const_lvalue(); + xvalue().rvalue(); + + prvalue().lvalue(); // expected-error {{'this' argument to member function 'lvalue' is an rvalue, but function has non-const lvalue ref-qualifier}} + prvalue().const_lvalue(); + prvalue().rvalue(); } void test_ref_qualifier_binding_with_surrogates() { Index: test/SemaCXX/copy-initialization.cpp =================================================================== --- test/SemaCXX/copy-initialization.cpp +++ test/SemaCXX/copy-initialization.cpp @@ -26,7 +26,7 @@ }; // PR3600 -void test(const foo *P) { P->bar(); } // expected-error{{'bar' not viable: 'this' argument has type 'const foo', but function is not marked const}} +void test(const foo *P) { P->bar(); } // expected-error{{'this' argument to member function 'bar' has type 'const foo', but function is not marked const}} namespace PR6757 { struct Foo {