diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2017-07-11 10:18:35 +0000 |
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2017-07-11 10:18:35 +0000 |
| commit | 4b9f80cc032d5e01d35fe6efa006433bc8d7b443 (patch) | |
| tree | 04e38bccc30e522d400de690bece0a3455d82f17 | |
| parent | 6a4c12fb338f359953ef7d04c9efe680a41392dc (diff) | |
| download | bcm5719-llvm-4b9f80cc032d5e01d35fe6efa006433bc8d7b443.tar.gz bcm5719-llvm-4b9f80cc032d5e01d35fe6efa006433bc8d7b443.zip | |
[ObjC] Check that a subscript methods is declared for a qualified id type
Objective-C subscript expressions report errors when a subscript method is not
declared in the base class. However, prior to this commit, qualified id types
were not checked. This commit ensures that an appropriate error is reported
when a subscript method is not declared in any of the protocols that are
included in the qualified id type.
rdar://33213924
llvm-svn: 307642
| -rw-r--r-- | clang/lib/Sema/SemaPseudoObject.cpp | 9 | ||||
| -rw-r--r-- | clang/test/SemaObjC/objc-container-subscripting-1.m | 5 | ||||
| -rw-r--r-- | clang/test/SemaObjC/objc-container-subscripting-2.m | 19 |
3 files changed, 23 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index b6b429d1f25..d159172a699 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -1176,8 +1176,6 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType, true /*instance*/); - bool receiverIdType = (BaseT->isObjCIdType() || - BaseT->isObjCQualifiedIdType()); if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) { AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(), @@ -1203,7 +1201,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { } if (!AtIndexGetter) { - if (!receiverIdType) { + if (!BaseT->isObjCIdType()) { S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found) << BaseExpr->getType() << 0 << arrayRef; return false; @@ -1284,9 +1282,6 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { } AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType, true /*instance*/); - - bool receiverIdType = (BaseT->isObjCIdType() || - BaseT->isObjCQualifiedIdType()); if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) { TypeSourceInfo *ReturnTInfo = nullptr; @@ -1321,7 +1316,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { } if (!AtIndexSetter) { - if (!receiverIdType) { + if (!BaseT->isObjCIdType()) { S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found) << BaseExpr->getType() << 1 << arrayRef; diff --git a/clang/test/SemaObjC/objc-container-subscripting-1.m b/clang/test/SemaObjC/objc-container-subscripting-1.m index a58a7c3bda8..b5ed5a68dd8 100644 --- a/clang/test/SemaObjC/objc-container-subscripting-1.m +++ b/clang/test/SemaObjC/objc-container-subscripting-1.m @@ -16,8 +16,7 @@ id oldObject = array[10]; // expected-warning {{instance method '-objectAtIndexe array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}} id<P> p_array; -oldObject = p_array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}} +oldObject = p_array[10]; // expected-error {{expected method to read array element not found on object of type 'id<P>'}} -p_array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}} +p_array[10] = 0; // expected-error {{expected method to write array element not found on object of type 'id<P>'}} } - diff --git a/clang/test/SemaObjC/objc-container-subscripting-2.m b/clang/test/SemaObjC/objc-container-subscripting-2.m index 62320fcebb7..6e7ee7c40e5 100644 --- a/clang/test/SemaObjC/objc-container-subscripting-2.m +++ b/clang/test/SemaObjC/objc-container-subscripting-2.m @@ -28,3 +28,22 @@ void test_unused() { dict[array]; // expected-warning {{container access result unused - container access should not be used for side effects}} } +void testQualifiedId(id<P> qualifiedId) { + id object = qualifiedId[10]; // expected-error {{expected method to read array element not found on object of type 'id<P>'}} + qualifiedId[10] = qualifiedId; // expected-error {{expected method to write array element not found on object of type 'id<P>'}} +} + +void testUnqualifiedId(id unqualId) { + id object = unqualId[10]; + unqualId[10] = object; +} + +@protocol Subscriptable +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +void testValidQualifiedId(id<Subscriptable> qualifiedId) { + id object = qualifiedId[10]; + qualifiedId[10] = object; +} |

