summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-07-11 10:18:35 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-07-11 10:18:35 +0000
commit4b9f80cc032d5e01d35fe6efa006433bc8d7b443 (patch)
tree04e38bccc30e522d400de690bece0a3455d82f17
parent6a4c12fb338f359953ef7d04c9efe680a41392dc (diff)
downloadbcm5719-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.cpp9
-rw-r--r--clang/test/SemaObjC/objc-container-subscripting-1.m5
-rw-r--r--clang/test/SemaObjC/objc-container-subscripting-2.m19
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;
+}
OpenPOWER on IntegriCloud