[PATCH] D66831: [ObjC] Fix type checking for qualified id block parameters.
Volodymyr Sapsai via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 17:48:09 PST 2020
vsapsai added a comment.
In D66831#1901972 <https://reviews.llvm.org/D66831#1901972>, @smeenai wrote:
> I'm not very familiar with Objective-C semantics. Does saying `@interface J : I <Q>` mean we're overriding the conformance being specified by `@interface I <P>`? In that case, the Clang 10 error makes sense to me.
`@interface J : I <Q>` isn't overriding the conformance specified by `@interface I <P>`, it adds conformance to Q.
In D66831#1901972 <https://reviews.llvm.org/D66831#1901972>, @smeenai wrote:
> In practice though, classes like `UIImage` are declared as inheriting from `NSObject<NSSecureCoding>`, so passing a `UIImage *` to a block with a parameter of type `id<NSObject>` gives an error with Clang 10.
I didn't try your example in a debugger but I believe we should warn here because code invoking the block is not guaranteed to call it with `UIImage *`, only with `id<NSObject>`. And using `UIImage *` inside the block is dangerous. To expand on your example
@protocol P
@end
@protocol Q
- (void)specificMethod;
@end
@interface I <P>
@end
@interface J : I <Q>
- (void)specificMethod;
@end
void f(void (^block)(id<P>)) {
I *i = [I new];
block(i);
}
void g() {
f(^(J *j){
[j specificMethod]; // not recognized selector
});
}
According to this explanation `@interface J : I` should also cause errors but I think it works because assigning to/from `id<Protocol>` is somewhat hand-wavy and not very strict.
Also consider specifying protocols the other way around
@protocol P
@end
@protocol Q
@end
@interface I <P>
@end
@interface J : I <Q>
@end
void f(void (^)(J *));
void g() {
f(^(id<P> p){});
f(^(id<Q> q){});
}
I think it shouldn't be an error but clang-9 complains.
Repository:
rL LLVM
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66831/new/
https://reviews.llvm.org/D66831
More information about the cfe-commits
mailing list