forked from OSchip/llvm-project
[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
This commit is contained in:
parent
6a4c12fb33
commit
4b9f80cc03
|
@ -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;
|
||||
|
|
|
@ -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>'}}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue