From: John McCall Date: Thu, 7 Jan 2010 02:04:15 +0000 (+0000) Subject: Improve the lead diagnostic for C++ object subscript expressions with X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1eb3e1003d5cda4d47f54321d81d678c26981e7a;p=clang Improve the lead diagnostic for C++ object subscript expressions with no viable overloads. Use a different message when the class provides no operator[] overloads at all; use it for operator(), too. Partially addresses PR 5900. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92894 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 710e977261..8470ad9850 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -928,6 +928,10 @@ def err_ovl_ambiguous_oper : Error< def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">; def err_ovl_deleted_oper : Error< "overload resolution selected %select{unavailable|deleted}0 operator '%1'">; +def err_ovl_no_viable_subscript : + Error<"no viable overloaded operator[] for type %0">; +def err_ovl_no_oper : + Error<"type %0 does not provide a %select{subscript|call}1 operator">; def err_ovl_no_viable_object_call : Error< "no matching function for call to object of type %0">; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index cec167953c..d2bd4eea98 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5449,16 +5449,17 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, } case OR_No_Viable_Function: { - // No viable function; try to create a built-in operation, which will - // produce an error. Then, show the non-viable candidates. - OwningExprResult Result = - CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc); - assert(Result.isInvalid() && - "C++ subscript operator overloading is missing candidates!"); - if (Result.isInvalid()) - PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, - "[]", LLoc); - return move(Result); + if (CandidateSet.empty()) + Diag(LLoc, diag::err_ovl_no_oper) + << Args[0]->getType() << /*subscript*/ 0 + << Args[0]->getSourceRange() << Args[1]->getSourceRange(); + else + Diag(LLoc, diag::err_ovl_no_viable_subscript) + << Args[0]->getType() + << Args[0]->getSourceRange() << Args[1]->getSourceRange(); + PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, + "[]", LLoc); + return ExprError(); } case OR_Ambiguous: @@ -5712,9 +5713,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, break; case OR_No_Viable_Function: - Diag(Object->getSourceRange().getBegin(), - diag::err_ovl_no_viable_object_call) - << Object->getType() << Object->getSourceRange(); + if (CandidateSet.empty()) + Diag(Object->getSourceRange().getBegin(), diag::err_ovl_no_oper) + << Object->getType() << /*call*/ 1 + << Object->getSourceRange(); + else + Diag(Object->getSourceRange().getBegin(), + diag::err_ovl_no_viable_object_call) + << Object->getType() << Object->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); break; diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index a20c69b8d5..5c4db7f7f8 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -324,3 +324,27 @@ namespace pr5512 { a += x; } } + +// PR5900 +namespace pr5900 { + struct NotAnArray {}; + void test0() { + NotAnArray x; + x[0] = 0; // expected-error {{does not provide a subscript operator}} + } + + struct NonConstArray { + int operator[](unsigned); // expected-note {{candidate}} + }; + int test1() { + const NonConstArray x; + return x[0]; // expected-error {{no viable overloaded operator[] for type}} + } + + // Not really part of this PR, but implemented at the same time. + struct NotAFunction {}; + void test2() { + NotAFunction x; + x(); // expected-error {{does not provide a call operator}} + } +} diff --git a/test/SemaTemplate/instantiate-subscript.cpp b/test/SemaTemplate/instantiate-subscript.cpp index a7187516da..8c119ec8c6 100644 --- a/test/SemaTemplate/instantiate-subscript.cpp +++ b/test/SemaTemplate/instantiate-subscript.cpp @@ -16,7 +16,7 @@ struct ConvertibleToInt { template struct Subscript0 { void test(T t, U u) { - Result &result = t[u]; // expected-error{{subscripted value is not}} + Result &result = t[u]; // expected-error{{no viable overloaded operator[] for type}} } };