xref: /aosp_15_r20/external/clang/test/SemaObjC/protocols-suppress-conformance.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1  -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class
2*67e74705SXin Li
3*67e74705SXin Li// Mark this protocol as requiring all of its methods and properties
4*67e74705SXin Li// to be explicitly implemented in the adopting class.
5*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation))
6*67e74705SXin Li@protocol Protocol
7*67e74705SXin Li- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
8*67e74705SXin Li@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
9*67e74705SXin Li@end
10*67e74705SXin Li
11*67e74705SXin Li// In this example, ClassA adopts the protocol.  We won't
12*67e74705SXin Li// provide the implementation here, but this protocol will
13*67e74705SXin Li// be adopted later by a subclass.
14*67e74705SXin Li@interface ClassA <Protocol>
15*67e74705SXin Li- (void) theBestOfTimes;
16*67e74705SXin Li@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
17*67e74705SXin Li@end
18*67e74705SXin Li
19*67e74705SXin Li// This class subclasses ClassA (which also adopts 'Protocol').
20*67e74705SXin Li@interface ClassB : ClassA <Protocol>
21*67e74705SXin Li@end
22*67e74705SXin Li
23*67e74705SXin Li@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
24*67e74705SXin Li@end
25*67e74705SXin Li
26*67e74705SXin Li@interface ClassB_Good : ClassA <Protocol>
27*67e74705SXin Li@end
28*67e74705SXin Li
29*67e74705SXin Li@implementation ClassB_Good // no-warning
30*67e74705SXin Li- (void) theBestOfTimes {}
31*67e74705SXin Li@dynamic theWorstOfTimes;
32*67e74705SXin Li@end
33*67e74705SXin Li
34*67e74705SXin Li@interface ClassB_AlsoGood : ClassA <Protocol>
35*67e74705SXin Li@property (readonly) id theWorstOfTimes; // expected-warning {{auto property synthesis will not synthesize property 'theWorstOfTimes'; it will be implemented by its superclass}}
36*67e74705SXin Li@end
37*67e74705SXin Li
38*67e74705SXin Li// Default synthesis acts as if @dynamic
39*67e74705SXin Li// had been written for 'theWorstOfTimes' because
40*67e74705SXin Li// it is declared in ClassA.  This is okay, since
41*67e74705SXin Li// the author of ClassB_AlsoGood needs explicitly
42*67e74705SXin Li// write @property in the @interface.
43*67e74705SXin Li@implementation ClassB_AlsoGood  // expected-note {{detected while default synthesizing properties in class implementation}}
44*67e74705SXin Li- (void) theBestOfTimes {}
45*67e74705SXin Li@end
46*67e74705SXin Li
47*67e74705SXin Li// Test that inherited protocols do not get the explicit conformance requirement.
48*67e74705SXin Li@protocol Inherited
49*67e74705SXin Li- (void) fairIsFoul;
50*67e74705SXin Li@end
51*67e74705SXin Li
52*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation))
53*67e74705SXin Li@protocol Derived <Inherited>
54*67e74705SXin Li- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}
55*67e74705SXin Li@end
56*67e74705SXin Li
57*67e74705SXin Li@interface ClassC <Inherited>
58*67e74705SXin Li@end
59*67e74705SXin Li
60*67e74705SXin Li@interface ClassD : ClassC <Derived>
61*67e74705SXin Li@end
62*67e74705SXin Li
63*67e74705SXin Li@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
64*67e74705SXin Li@end
65*67e74705SXin Li
66*67e74705SXin Li// Test that the attribute is used correctly.
67*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}}
68*67e74705SXin Li@protocol AnotherProtocol @end
69*67e74705SXin Li
70*67e74705SXin Li// Cannot put the attribute on classes or other non-protocol declarations.
71*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
72*67e74705SXin Li@interface AnotherClass @end
73*67e74705SXin Li
74*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
75*67e74705SXin Liint x;
76*67e74705SXin Li
77*67e74705SXin Li// Test that inherited protocols with the attribute
78*67e74705SXin Li// are treated properly.
79*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation))
80*67e74705SXin Li@protocol ProtocolA
81*67e74705SXin Li@required
82*67e74705SXin Li- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
83*67e74705SXin Li- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
84*67e74705SXin Li@end
85*67e74705SXin Li
86*67e74705SXin Li@protocol ProtocolB <ProtocolA>
87*67e74705SXin Li@required
88*67e74705SXin Li- (void)dunwich;
89*67e74705SXin Li- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}
90*67e74705SXin Li@end
91*67e74705SXin Li
92*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation))
93*67e74705SXin Li@protocol ProtocolB_Explicit <ProtocolA>
94*67e74705SXin Li@required
95*67e74705SXin Li- (void)dunwich;
96*67e74705SXin Li- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
97*67e74705SXin Li@end
98*67e74705SXin Li
99*67e74705SXin Li@protocol ProtocolC
100*67e74705SXin Li@required
101*67e74705SXin Li- (void)rlyeh;
102*67e74705SXin Li- (void)innsmouth;
103*67e74705SXin Li- (void)dunwich;
104*67e74705SXin Li@end
105*67e74705SXin Li
106*67e74705SXin Li@interface MyObject <ProtocolC> @end
107*67e74705SXin Li
108*67e74705SXin Li// Provide two variants of a base class, one that adopts ProtocolA and
109*67e74705SXin Li// one that does not.
110*67e74705SXin Li@interface Lovecraft <ProtocolA> @end
111*67e74705SXin Li@interface Lovecraft_2 @end
112*67e74705SXin Li
113*67e74705SXin Li// Provide two variants of a subclass that conform to ProtocolB.  One
114*67e74705SXin Li// subclasses from a class that conforms to ProtocolA, the other that
115*67e74705SXin Li// does not.
116*67e74705SXin Li//
117*67e74705SXin Li// From those, provide two variants that conformat to ProtocolB_Explicit
118*67e74705SXin Li// instead.
119*67e74705SXin Li@interface Shoggoth : Lovecraft <ProtocolB> @end
120*67e74705SXin Li@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end
121*67e74705SXin Li@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end
122*67e74705SXin Li@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end
123*67e74705SXin Li
124*67e74705SXin Li@implementation MyObject
125*67e74705SXin Li- (void)innsmouth {}
126*67e74705SXin Li- (void)rlyeh {}
127*67e74705SXin Li- (void)dunwich {}
128*67e74705SXin Li@end
129*67e74705SXin Li
130*67e74705SXin Li@implementation Lovecraft
131*67e74705SXin Li- (void)innsmouth {}
132*67e74705SXin Li- (void)rlyeh {}
133*67e74705SXin Li@end
134*67e74705SXin Li
135*67e74705SXin Li@implementation Shoggoth
136*67e74705SXin Li- (void)dunwich {}
137*67e74705SXin Li@end
138*67e74705SXin Li
139*67e74705SXin Li@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\
140*67e74705SXin Li                           // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
141*67e74705SXin Li                           // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}}
142*67e74705SXin Li- (void)dunwich {}
143*67e74705SXin Li@end
144*67e74705SXin Li
145*67e74705SXin Li@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}
146*67e74705SXin Li- (void)dunwich {}
147*67e74705SXin Li@end
148*67e74705SXin Li
149*67e74705SXin Li@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\
150*67e74705SXin Li                                    // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
151*67e74705SXin Li                                    // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}}
152*67e74705SXin Li- (void)dunwich {}
153*67e74705SXin Li@end
154*67e74705SXin Li
155*67e74705SXin Li// Categories adopting a protocol with explicit conformance need to implement that protocol.
156*67e74705SXin Li@interface Parent
157*67e74705SXin Li- (void) theBestOfTimes;
158*67e74705SXin Li@property (readonly) id theWorstOfTimes;
159*67e74705SXin Li@end
160*67e74705SXin Li
161*67e74705SXin Li@interface Derived : Parent
162*67e74705SXin Li@end
163*67e74705SXin Li
164*67e74705SXin Li@interface Derived (MyCat) <Protocol>
165*67e74705SXin Li@end
166*67e74705SXin Li
167*67e74705SXin Li@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
168*67e74705SXin Li@end
169*67e74705SXin Li
170*67e74705SXin Li__attribute__((objc_protocol_requires_explicit_implementation))  // expected-error{{attribute 'objc_protocol_requires_explicit_implementation' can only be applied to @protocol definitions, not forward declarations}}
171*67e74705SXin Li@protocol NotDefined;
172*67e74705SXin Li
173*67e74705SXin Li// Another complete hierarchy.
174*67e74705SXin Li __attribute__((objc_protocol_requires_explicit_implementation))
175*67e74705SXin Li@protocol Ex2FooBar
176*67e74705SXin Li- (void)methodA;
177*67e74705SXin Li@end
178*67e74705SXin Li
179*67e74705SXin Li __attribute__((objc_protocol_requires_explicit_implementation))
180*67e74705SXin Li@protocol Ex2ProtocolA
181*67e74705SXin Li- (void)methodB;
182*67e74705SXin Li@end
183*67e74705SXin Li
184*67e74705SXin Li __attribute__((objc_protocol_requires_explicit_implementation))
185*67e74705SXin Li@protocol Ex2ProtocolB <Ex2ProtocolA>
186*67e74705SXin Li- (void)methodA; // expected-note {{method 'methodA' declared here}}
187*67e74705SXin Li@end
188*67e74705SXin Li
189*67e74705SXin Li// NOT required
190*67e74705SXin Li@protocol Ex2ProtocolC <Ex2ProtocolA>
191*67e74705SXin Li- (void)methodB;
192*67e74705SXin Li- (void)methodA;
193*67e74705SXin Li@end
194*67e74705SXin Li
195*67e74705SXin Li@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar>
196*67e74705SXin Li@end
197*67e74705SXin Li@implementation Ex2ClassA
198*67e74705SXin Li- (void)methodB {}
199*67e74705SXin Li- (void)methodA {}
200*67e74705SXin Li@end
201*67e74705SXin Li
202*67e74705SXin Li@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB>
203*67e74705SXin Li@end
204*67e74705SXin Li
205*67e74705SXin Li@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}
206*67e74705SXin Li@end
207*67e74705SXin Li
208