]> granicus.if.org Git - clang/commitdiff
objective-c: Improve diagnostics and
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Mar 2012 17:56:49 +0000 (17:56 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Mar 2012 17:56:49 +0000 (17:56 +0000)
provide 'fixit' hint when dictionary index
is not of proper type. // rdar://11062080

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153584 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
lib/Sema/SemaPseudoObject.cpp
test/SemaObjC/objc-container-subscripting-2.m
test/SemaObjC/objc-dictionary-literal.m [new file with mode: 0644]
test/SemaObjCXX/objc-container-subscripting.mm

index 7df189d5f957940c8abe6c8bc2df601dbab870b9..2b8d0b774c04316b5ee7880c18292bb081cf9a6b 100644 (file)
@@ -3780,7 +3780,10 @@ def err_objc_multiple_subscript_type_conversion : Error<
   "multiple type conversion functions">;
 def err_objc_subscript_type_conversion : Error<
   "indexing expression is invalid because subscript type %0 is not an intergal"
-  "or objective-C pointer type">;
+  " or objective-C pointer type">;
+def err_objc_subscript_pointer : Error<
+  "indexing expression is invalid because subscript type %0 is not an"
+  " objective-C pointer">;
 def err_objc_indexing_method_result_type : Error<
   "method for accessing %select{dictionary|array}1 element must have Objective-C"
   " object return type instead of %0">;
index ae5257fecbd5573f80ea04b4c681f6e7ba961ed2..6b30643db91aa4f5e3f318e75416098d17253121 100644 (file)
@@ -3115,19 +3115,19 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;
     ResultType = PTy->getPointeeType();
-  } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) {
-     // Handle the uncommon case of "123[Ptr]".
-    BaseExpr = RHSExp;
-    IndexExpr = LHSExp;
-    ResultType = PTy->getPointeeType();
   } else if (const ObjCObjectPointerType *PTy =
-               LHSTy->getAs<ObjCObjectPointerType>()) {
+             LHSTy->getAs<ObjCObjectPointerType>()) {
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;
     Result = BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0);
     if (!Result.isInvalid())
       return Owned(Result.take());
     ResultType = PTy->getPointeeType();
+  } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) {
+     // Handle the uncommon case of "123[Ptr]".
+    BaseExpr = RHSExp;
+    IndexExpr = LHSExp;
+    ResultType = PTy->getPointeeType();
   } else if (const ObjCObjectPointerType *PTy =
                RHSTy->getAs<ObjCObjectPointerType>()) {
      // Handle the uncommon case of "123[Ptr]".
index effb372303b0e837dcb2159b05d060006553fa22..aebc0eb60842838da19fc44cc8cb137194f50a85 100644 (file)
@@ -842,14 +842,20 @@ Sema::ObjCSubscriptKind
   // If we don't have a class type in C++, there's no way we can get an
   // expression of integral or enumeration type.
   const RecordType *RecordTy = T->getAs<RecordType>();
-  if (!RecordTy)
+  if (!RecordTy && T->isObjCObjectPointerType())
     // All other scalar cases are assumed to be dictionary indexing which
     // caller handles, with diagnostics if needed.
     return OS_Dictionary;
-  if (!getLangOpts().CPlusPlus || RecordTy->isIncompleteType()) {
+  if (!getLangOpts().CPlusPlus || 
+      !RecordTy || RecordTy->isIncompleteType()) {
     // No indexing can be done. Issue diagnostics and quit.
-    Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
-    << FromE->getType();
+    const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
+    if (isa<StringLiteral>(IndexExpr))
+      Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
+        << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
+    else
+      Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
+        << T;
     return OS_Error;
   }
   
index 2564975f4d46c7890432735f6fb3d1dc55d52814..45f82e5c746954d25b94cc48c9299f7cef940a42 100644 (file)
@@ -16,8 +16,8 @@ typedef unsigned int size_t;
 id func() {
   NSMutableArray *array;
   float f; 
-  array[f] = array; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}}
-  return array[3.14]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}}
+  array[f] = array; // expected-error {{indexing expression is invalid because subscript type 'float' is not an intergal or objective-C pointer type}}
+  return array[3.14]; // expected-error {{indexing expression is invalid because subscript type 'double' is not an intergal or objective-C pointer type}}
 }
 
 void test_unused() {
diff --git a/test/SemaObjC/objc-dictionary-literal.m b/test/SemaObjC/objc-dictionary-literal.m
new file mode 100644 (file)
index 0000000..2acbc39
--- /dev/null
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+// rdar://11062080
+
+@interface NSNumber
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+@protocol NSCopying @end
+typedef unsigned long NSUInteger;
+typedef long NSInteger;
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+@end
+
+@interface NSString<NSCopying>
+@end
+
+@interface NSArray
+- (id)objectAtIndexedSubscript:(NSInteger)index;
+- (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
+@end
+
+int main() {
+       NSDictionary *dict = @{ @"name":@666 };
+        dict[@"name"] = @666;
+
+        dict["name"] = @666; // expected-error {{indexing expression is invalid because subscript type 'char *' is not an objective-C pointer}}
+
+       return 0;
+}
+
index ccbc45e3b4c97a8e9d4e2dc738c1bb2456df545f..7591c3b0986b93479de2a1bee54e0024f69150c1 100644 (file)
@@ -32,8 +32,8 @@ template void test_dictionary_subscripts(NSMutableDictionary*, id, int); // expe
 
 template<typename T, typename U, typename O>
 void test_array_subscripts(T base, U index, O obj) {
-  base[index] = obj; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}}
-  obj = base[index]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}}
+  base[index] = obj; // expected-error {{indexing expression is invalid because subscript type 'double' is not an intergal or objective-C pointer type}}
+  obj = base[index]; // expected-error {{indexing expression is invalid because subscript type 'double' is not an intergal or objective-C pointer type}}
 }
 
 template void  test_array_subscripts(NSMutableArray *, int, id);