]> granicus.if.org Git - clang/commitdiff
Patch to issue warning when colllection expresion's type
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 12 Aug 2010 22:25:42 +0000 (22:25 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 12 Aug 2010 22:25:42 +0000 (22:25 +0000)
does not implement 'countByEnumeratingWithState' API.
Implements radar 7634669.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaStmt.cpp
test/CodeGenObjC/for-in.m
test/SemaObjCXX/instantiate-stmt.mm

index 9663acc6a3c2003e69700b20a7502c72233cb21d..ba156b16cfb3438e2af3e278041cc194b13b69e0 100644 (file)
@@ -3170,6 +3170,8 @@ def err_selector_element_type : Error<
   "selector element type %0 is not a valid object">;
 def err_collection_expr_type : Error<
   "collection expression type %0 is not a valid object">;
+def warn_collection_expr_type : Warning<
+  "collection expression type %0 may not respond to %1">;
 
 def err_invalid_conversion_between_ext_vectors : Error<
   "invalid conversion between ext-vector type %0 and %1">;
index 097ea68655fe7af7aefb0acc9a8b290a2fcfcd58..73e142c782e57112544da4629a65ef8819d4c7b7 100644 (file)
@@ -941,6 +941,27 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
     if (!SecondType->isObjCObjectPointerType())
       Diag(ForLoc, diag::err_collection_expr_type)
         << SecondType << Second->getSourceRange();
+    else if (const ObjCObjectPointerType *OPT =
+             SecondType->getAsObjCInterfacePointerType()) {
+      llvm::SmallVector<IdentifierInfo *, 4> KeyIdents;
+      IdentifierInfo* selIdent = 
+        &Context.Idents.get("countByEnumeratingWithState");
+      KeyIdents.push_back(selIdent);
+      selIdent = &Context.Idents.get("objects");
+      KeyIdents.push_back(selIdent);
+      selIdent = &Context.Idents.get("count");
+      KeyIdents.push_back(selIdent);
+      Selector CSelector = Context.Selectors.getSelector(3, &KeyIdents[0]);
+      if (ObjCInterfaceDecl *IDecl = OPT->getInterfaceDecl()) {
+        if (!IDecl->isForwardDecl() && 
+            !IDecl->lookupInstanceMethod(CSelector)) {
+          // Must further look into privaye implementation methods.
+          if (!LookupPrivateInstanceMethod(CSelector, IDecl))
+            Diag(ForLoc, diag::warn_collection_expr_type)
+              << SecondType << CSelector << Second->getSourceRange();
+        }
+      }
+    }
   }
   first.release();
   second.release();
index 354ff32c0ef95bceed34c4498053af9fe3d517d4..7e6098a7eb57331363f7d635106cd6b763056f12 100644 (file)
@@ -23,7 +23,7 @@ void t0() {
 
   p("array.length: %d\n", [array count]);
   unsigned index = 0;
-  for (NSString *i in array) {
+  for (NSString *i in array) { // expected-warning {{collection expression type 'NSArray *' may not respond}}
     p("element %d: %s\n", index++, [i cString]);
   }
 }
@@ -33,7 +33,7 @@ void t1() {
 
   p("array.length: %d\n", [array count]);
   unsigned index = 0;
-  for (NSString *i in array) {
+  for (NSString *i in array) { // expected-warning {{collection expression type 'NSArray *' may not respond}}
     index++;
     if (index == 10)
       continue;
index e92f8e8d4f0c0b2486211ed909589aba499bcc25..5e8ec61573d4153d03e84eedae3fb820b8531e7c 100644 (file)
@@ -25,6 +25,7 @@ template void synchronized_test(int); // expected-note{{in instantiation of}}
 
 // fast enumeration
 @interface NSArray
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount;
 @end
 
 @interface NSString