1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// rdar://8191774
3
4@protocol SomeProtocol
5@end
6
7@protocol SomeProtocol1
8@end
9
10@interface SomeObject <SomeProtocol>
11@end
12
13int main () {
14    Class <SomeProtocol> classA;
15    Class <SomeProtocol> classB;
16    Class <SomeProtocol, SomeProtocol1> classC;
17    Class <SomeProtocol1> classD;
18    void * pv = 0;
19    Class c = (Class)0;;
20    if (pv)
21      return classA == pv;
22
23    if (c)
24      return classA == c;
25
26    return classA == classB  || classA == classC ||
27           classC == classA ||
28           classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol>' and 'Class<SomeProtocol1>')}}
29}
30
31// rdar://18491222
32@protocol NSObject @end
33
34@interface NSObject @end
35@protocol ProtocolX <NSObject>
36@end
37
38@protocol ProtocolY <NSObject>
39@end
40
41@interface ClassA : NSObject
42@end
43
44@interface ClassB : ClassA <ProtocolY, ProtocolX>
45@end
46
47@interface OtherClass : NSObject
48@property (nonatomic, copy) ClassB<ProtocolX> *aProperty;
49- (ClassA<ProtocolY> *)aMethod;
50- (ClassA<ProtocolY> *)anotherMethod;
51@end
52
53@implementation OtherClass
54- (ClassA<ProtocolY> *)aMethod {
55    // This does not work, even though ClassB subclasses from A and conforms to Y
56    // because the property type explicitly adds ProtocolX conformance
57    // even though ClassB already conforms to ProtocolX
58    return self.aProperty;
59}
60- (ClassA<ProtocolY> *)anotherMethod {
61    // This works, even though all it is doing is removing an explicit
62    // protocol conformance that ClassB already conforms to
63    return (ClassB *)self.aProperty;
64}
65@end
66