Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -1589,12 +1589,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_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_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_type : 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 " @@ -1815,10 +1823,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: cfe/trunk/lib/Sema/SemaOverload.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp +++ cfe/trunk/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,28 @@ << 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(); + } + + case BadConversionSequence::no_conversion: + case BadConversionSequence::unrelated_class: + break; } return Diag(From->getLocStart(), - diag::err_implicit_object_parameter_init) + diag::err_member_function_call_bad_type) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); } Index: cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp =================================================================== --- cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp +++ cfe/trunk/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,18 @@ void g(); + void c() const; // expected-note {{'c' declared here}} + void v() volatile; // expected-note {{'v' declared here}} + void r() __restrict__; // expected-note {{'r' declared here}} + void cr() const __restrict__; // expected-note {{'cr' declared here}} + void cv() const volatile; + void vr() volatile __restrict__; // expected-note {{'vr' declared here}} + void cvr() const volatile __restrict__; + + 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&) &&; @@ -32,7 +43,7 @@ float &h2() const&&; }; -void X0::g() { +void X0::g() { // expected-note {{'g' declared here}} int &ir1 = f(); int &ir2 = X0::f(); } @@ -69,3 +80,26 @@ float &fr3 = xvalue().h2(); float &fr4 = prvalue().h2(); } + +void test_diagnostics(const volatile X0 &__restrict__ cvr) { + cvr.g(); // expected-error {{'this' argument to member function 'g' has type 'const volatile X0', but function is not marked const or volatile}} + cvr.c(); // expected-error {{not marked volatile}} + cvr.v(); // expected-error {{not marked const}} + cvr.r(); // expected-error {{not marked const or volatile}} + cvr.cr(); // expected-error {{not marked volatile}} + cvr.cv(); + cvr.vr(); // expected-error {{not marked const}} + cvr.cvr(); + + 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(); +} Index: cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp =================================================================== --- cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -215,7 +215,7 @@ template void i(T t) { for (auto u : t) { // expected-error {{invalid range expression of type 'X::A *'; no viable 'begin' function available}} \ - expected-error {{member function 'begin' not viable}} \ + expected-error {{'this' argument to member function 'begin' has type 'const X::A', but function is not marked const}} \ expected-note {{when looking up 'begin' function}} } Index: cfe/trunk/test/SemaCXX/copy-initialization.cpp =================================================================== --- cfe/trunk/test/SemaCXX/copy-initialization.cpp +++ cfe/trunk/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 { Index: cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp =================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp +++ cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp @@ -96,8 +96,8 @@ //expected-error@81 {{statement requires expression of integer type ('extended_examples::A1' invalid)}} //expected-error@85 {{statement requires expression of integer type ('extended_examples::B2' invalid)}} #else -//expected-error@81 {{cannot initialize object parameter of type 'extended_examples::A1' with an expression of type 'extended_examples::A1'}} -//expected-error@85 {{cannot initialize object parameter of type 'extended_examples::B2' with an expression of type 'extended_examples::B2'}} +//expected-error@81 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@54 {{'operator int' declared here}} +//expected-error@85 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@75 {{'operator int' declared here}} #endif namespace extended_examples_cxx1y { @@ -149,9 +149,9 @@ #ifdef CXX1Y //expected-error@139 {{statement requires expression of integer type ('extended_examples_cxx1y::A2' invalid)}} #else -//expected-error@138 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A1' with an expression of type 'extended_examples_cxx1y::A1'}} -//expected-error@139 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A2' with an expression of type 'extended_examples_cxx1y::A2'}} -//expected-error@143 {{cannot initialize object parameter of type 'extended_examples_cxx1y::D' with an expression of type 'extended_examples_cxx1y::D'}} +//expected-error@138 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@106 {{'operator int' declared here}} +//expected-error@139 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@111 {{'operator int' declared here}} +//expected-error@143 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@131 {{'operator int' declared here}} #endif namespace extended_examples_array_bounds { Index: cfe/trunk/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp =================================================================== --- cfe/trunk/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp +++ cfe/trunk/test/SemaCXX/cxx2a-pointer-to-const-ref-member.cpp @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -std=c++2a %s -verify struct X { - void ref() & {} + void ref() & {} // expected-note{{'ref' declared here}} void cref() const& {} }; void test() { - X{}.ref(); // expected-error{{cannot initialize object parameter of type 'X' with an expression of type 'X'}} + X{}.ref(); // expected-error{{'this' argument to member function 'ref' is an rvalue, but function has non-const lvalue ref-qualifier}} X{}.cref(); // expected-no-error (X{}.*&X::ref)(); // expected-error-re{{pointer-to-member function type 'void (X::*)() {{.*}}&' can only be called on an lvalue}}