]> granicus.if.org Git - clang/commitdiff
Improve the lead diagnostic for C++ object subscript expressions with
authorJohn McCall <rjmccall@apple.com>
Thu, 7 Jan 2010 02:04:15 +0000 (02:04 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 7 Jan 2010 02:04:15 +0000 (02:04 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaOverload.cpp
test/SemaCXX/overloaded-operator.cpp
test/SemaTemplate/instantiate-subscript.cpp

index 710e97726110e398cd4b955d94a5409100ef7ada..8470ad98508bda53261d60bc8aeb32976bd1f335 100644 (file)
@@ -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">;
index cec167953c88ec5d123839992c3b150e5765df47..d2bd4eea98f7861f092939ac5eadd348d22c1720 100644 (file)
@@ -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;
 
index a20c69b8d5d1df2bcece06f79428b25d67b8fe23..5c4db7f7f8bec4ebae1742c5c4b74f98c4a31034 100644 (file)
@@ -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}}
+  }
+}
index a7187516da398519542b6cd915e833af6f76f0d7..8c119ec8c6de819314e1ec32ff8a9be4474e32a4 100644 (file)
@@ -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}}
   }
 };