From: Fariborz Jahanian Date: Thu, 12 Aug 2010 22:25:42 +0000 (+0000) Subject: Patch to issue warning when colllection expresion's type X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ea16110ce3a4fbb205735f0a55050bc11292e82c;p=clang Patch to issue warning when colllection expresion's type 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 9663acc6a3..ba156b16cf 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 097ea68655..73e142c782 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -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 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(); diff --git a/test/CodeGenObjC/for-in.m b/test/CodeGenObjC/for-in.m index 354ff32c0e..7e6098a7eb 100644 --- a/test/CodeGenObjC/for-in.m +++ b/test/CodeGenObjC/for-in.m @@ -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; diff --git a/test/SemaObjCXX/instantiate-stmt.mm b/test/SemaObjCXX/instantiate-stmt.mm index e92f8e8d4f..5e8ec61573 100644 --- a/test/SemaObjCXX/instantiate-stmt.mm +++ b/test/SemaObjCXX/instantiate-stmt.mm @@ -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