From: Argyrios Kyrtzidis Date: Tue, 16 Nov 2010 08:04:45 +0000 (+0000) Subject: Improve diagnostic for calling non-const method on const object. Fixes rdar://7743000 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64ccf2480609f4b5c27b31f6beaa157e6ec4f065;p=clang Improve diagnostic for calling non-const method on const object. Fixes rdar://7743000 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119336 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 560120b51e..ae5537ab7c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -771,6 +771,10 @@ def err_reference_bind_init_list : Error< 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_init_drops_quals : Error< "initialization of reference to type %0 with a %select{value|temporary}1 of type %2 drops " diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 0c8d78025b..65d6bc8f7a 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3187,10 +3187,26 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, ImplicitConversionSequence ICS = TryObjectArgumentInitialization(*this, From->getType(), Method, Method->getParent()); - if (ICS.isBad()) + if (ICS.isBad()) { + if (ICS.Bad.Kind == BadConversionSequence::bad_qualifiers) { + Qualifiers FromQs = FromRecordType.getQualifiers(); + Qualifiers ToQs = DestType.getQualifiers(); + unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers(); + if (CVR) { + Diag(From->getSourceRange().getBegin(), + diag::err_member_function_call_bad_cvr) + << Method->getDeclName() << FromRecordType << (CVR - 1) + << From->getSourceRange(); + Diag(Method->getLocation(), diag::note_previous_decl) + << Method->getDeclName(); + return true; + } + } + return Diag(From->getSourceRange().getBegin(), diag::err_implicit_object_parameter_init) << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); + } if (ICS.Standard.Second == ICK_Derived_To_Base) return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method); diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp index a28a1941ec..fb83dcfbd0 100644 --- a/test/SemaCXX/copy-initialization.cpp +++ b/test/SemaCXX/copy-initialization.cpp @@ -19,11 +19,11 @@ void f(Y y, int *ip, float *fp) { } struct foo { - void bar(); + void bar(); // expected-note{{declared here}} }; // PR3600 -void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'foo' with an expression of type 'const foo'}} +void test(const foo *P) { P->bar(); } // expected-error{{'bar' not viable: 'this' argument has type 'const foo', but function is not marked const}} namespace PR6757 { struct Foo {