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
This commit is contained in:
John McCall 2010-01-07 02:04:15 +00:00
Родитель 782f2f52b7
Коммит 1eb3e1003d
4 изменённых файлов: 48 добавлений и 14 удалений

Просмотреть файл

@ -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">;

Просмотреть файл

@ -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())
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 move(Result);
return ExprError();
}
case OR_Ambiguous:
@ -5712,6 +5713,11 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
break;
case OR_No_Viable_Function:
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();

Просмотреть файл

@ -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}}
}
}

Просмотреть файл

@ -16,7 +16,7 @@ struct ConvertibleToInt {
template<typename T, typename U, typename Result>
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}}
}
};