diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-11-16 08:04:45 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-11-16 08:04:45 +0000 |
commit | 9813d3221d7d533032c44c2019e8614075d1a6c0 (patch) | |
tree | 0eed49554961d4e36cf1756d9d28ab8f84fb5221 /clang | |
parent | 1ade3267d7f445d27c1074fb5208d7e1a0808c42 (diff) | |
download | bcm5719-llvm-9813d3221d7d533032c44c2019e8614075d1a6c0.tar.gz bcm5719-llvm-9813d3221d7d533032c44c2019e8614075d1a6c0.zip |
Improve diagnostic for calling non-const method on const object. Fixes rdar://7743000
llvm-svn: 119336
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 18 | ||||
-rw-r--r-- | clang/test/SemaCXX/copy-initialization.cpp | 4 |
3 files changed, 23 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 560120b51e7..ae5537ab7c5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 0c8d78025b4..65d6bc8f7a0 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/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/clang/test/SemaCXX/copy-initialization.cpp b/clang/test/SemaCXX/copy-initialization.cpp index a28a1941ece..fb83dcfbd01 100644 --- a/clang/test/SemaCXX/copy-initialization.cpp +++ b/clang/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 { |