diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 21 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/for-in.m | 4 | ||||
| -rw-r--r-- | clang/test/SemaObjCXX/instantiate-stmt.mm | 1 |
4 files changed, 26 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9663acc6a3c..ba156b16cfb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 097ea68655f..73e142c782e 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/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<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(); diff --git a/clang/test/CodeGenObjC/for-in.m b/clang/test/CodeGenObjC/for-in.m index 354ff32c0ef..7e6098a7eb5 100644 --- a/clang/test/CodeGenObjC/for-in.m +++ b/clang/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/clang/test/SemaObjCXX/instantiate-stmt.mm b/clang/test/SemaObjCXX/instantiate-stmt.mm index e92f8e8d4f0..5e8ec61573d 100644 --- a/clang/test/SemaObjCXX/instantiate-stmt.mm +++ b/clang/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 |

