1// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
2
3// Define used Classes
4@protocol NSObject
5- (id)retain;
6- (oneway void)release;
7@end
8@interface NSObject <NSObject> {}
9- (id)init;
10+ (id)alloc;
11@end
12typedef char BOOL;
13typedef double NSTimeInterval;
14typedef enum UIViewAnimationOptions {
15    UIViewAnimationOptionLayoutSubviews = 1 <<  0
16} UIViewAnimationOptions;
17@interface NSCoder : NSObject {}
18@end
19
20// Define the Superclasses for our Checks
21@interface UIViewController : NSObject {}
22- (void)addChildViewController:(UIViewController *)childController;
23- (void)viewDidAppear:(BOOL)animated;
24- (void)viewDidDisappear:(BOOL)animated;
25- (void)viewDidUnload;
26- (void)viewDidLoad;
27- (void)viewWillUnload;
28- (void)viewWillAppear:(BOOL)animated;
29- (void)viewWillDisappear:(BOOL)animated;
30- (void)didReceiveMemoryWarning;
31- (void)removeFromParentViewController;
32- (void)transitionFromViewController:(UIViewController *)fromViewController
33  toViewController:(UIViewController *)toViewController 
34  duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options
35  animations:(void (^)(void))animations
36  completion:(void (^)(BOOL finished))completion;
37@end
38@interface UIResponder : NSObject {}
39- (BOOL)resignFirstResponder;
40@end
41@interface NSResponder : NSObject {}
42- (void)restoreStateWithCoder:(NSCoder *)coder;
43- (void)encodeRestorableStateWithCoder:(NSCoder *)coder;
44@end
45@interface NSDocument : NSObject {}
46- (void)restoreStateWithCoder:(NSCoder *)coder;
47- (void)encodeRestorableStateWithCoder:(NSCoder *)coder;
48@end
49
50// Checks
51
52// Do not warn if UIViewController/*Responder/NSDocument is not our superclass
53@interface TestA 
54@end
55@implementation TestA
56
57- (void)addChildViewController:(UIViewController *)childController {}
58- (void)viewDidAppear:(BOOL)animated {}
59- (void)viewDidDisappear:(BOOL)animated {}
60- (void)viewDidUnload {}
61- (void)viewDidLoad {}
62- (void)viewWillUnload {}
63- (void)viewWillAppear:(BOOL)animated {}
64- (void)viewWillDisappear:(BOOL)animated {}
65- (void)didReceiveMemoryWarning {}
66- (void)removeFromParentViewController {}
67- (BOOL)resignFirstResponder { return 0; }
68- (void)restoreStateWithCoder:(NSCoder *)coder {}
69- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {}
70@end
71
72// Warn if UIViewController is our superclass and we do not call super
73@interface TestB : UIViewController {}
74@end
75@implementation TestB
76
77- (void)addChildViewController:(UIViewController *)childController {  
78  int addChildViewController = 5;
79  for (int i = 0; i < addChildViewController; i++)
80  	[self viewDidAppear:i];
81} // expected-warning {{The 'addChildViewController:' instance method in UIViewController subclass 'TestB' is missing a [super addChildViewController:] call}}
82- (void)viewDidAppear:(BOOL)animated {} // expected-warning {{The 'viewDidAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidAppear:] call}}
83- (void)viewDidDisappear:(BOOL)animated {} // expected-warning {{The 'viewDidDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidDisappear:] call}}
84- (void)viewDidUnload {} // expected-warning {{The 'viewDidUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewDidUnload] call}}
85- (void)viewDidLoad {} // expected-warning {{The 'viewDidLoad' instance method in UIViewController subclass 'TestB' is missing a [super viewDidLoad] call}}
86- (void)viewWillUnload {} // expected-warning {{The 'viewWillUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewWillUnload] call}}
87- (void)viewWillAppear:(BOOL)animated {} // expected-warning {{The 'viewWillAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillAppear:] call}}
88- (void)viewWillDisappear:(BOOL)animated {} // expected-warning {{The 'viewWillDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillDisappear:] call}}
89- (void)didReceiveMemoryWarning {} // expected-warning {{The 'didReceiveMemoryWarning' instance method in UIViewController subclass 'TestB' is missing a [super didReceiveMemoryWarning] call}}
90- (void)removeFromParentViewController {} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestB' is missing a [super removeFromParentViewController] call}}
91
92// Do not warn for methods were it shouldn't
93- (void)shouldAutorotate {}
94@end
95
96// Do not warn if UIViewController is our superclass but we did call super
97@interface TestC : UIViewController {}
98@end
99@implementation TestC
100
101- (BOOL)methodReturningStuff {
102  return 1;
103}
104
105- (void)methodDoingStuff {
106  [super removeFromParentViewController];
107}
108
109- (void)addChildViewController:(UIViewController *)childController {
110  [super addChildViewController:childController];
111}
112
113- (void)viewDidAppear:(BOOL)animated {
114  [super viewDidAppear:animated];
115} 
116
117- (void)viewDidDisappear:(BOOL)animated {
118  [super viewDidDisappear:animated]; 
119}
120
121- (void)viewDidUnload {
122  [super viewDidUnload];
123}
124
125- (void)viewDidLoad {
126  [super viewDidLoad];
127}
128
129- (void)viewWillUnload {
130  [super viewWillUnload];
131} 
132
133- (void)viewWillAppear:(BOOL)animated {
134  int i = 0; // Also don't start warning just because we do additional stuff
135  i++;
136  [self viewDidDisappear:i];
137  [super viewWillAppear:animated];
138} 
139
140- (void)viewWillDisappear:(BOOL)animated {
141  [super viewWillDisappear:[self methodReturningStuff]];
142}
143
144- (void)didReceiveMemoryWarning {
145  [super didReceiveMemoryWarning];
146}
147
148// We expect a warning here because at the moment the super-call can't be 
149// done from another method.
150- (void)removeFromParentViewController { 
151  [self methodDoingStuff]; 
152} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestC' is missing a [super removeFromParentViewController] call}}
153@end
154
155
156// Do warn for UIResponder subclasses that don't call super
157@interface TestD : UIResponder {}
158@end
159@implementation TestD
160
161- (BOOL)resignFirstResponder {
162  return 0;
163} // expected-warning {{The 'resignFirstResponder' instance method in UIResponder subclass 'TestD' is missing a [super resignFirstResponder] call}}
164@end
165
166// Do not warn for UIResponder subclasses that do the right thing
167@interface TestE : UIResponder {}
168@end
169@implementation TestE
170
171- (BOOL)resignFirstResponder {
172  return [super resignFirstResponder];
173}
174@end
175
176// Do warn for NSResponder subclasses that don't call super
177@interface TestF : NSResponder {}
178@end
179@implementation TestF
180
181- (void)restoreStateWithCoder:(NSCoder *)coder {
182} // expected-warning {{The 'restoreStateWithCoder:' instance method in NSResponder subclass 'TestF' is missing a [super restoreStateWithCoder:] call}}
183- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
184} // expected-warning {{The 'encodeRestorableStateWithCoder:' instance method in NSResponder subclass 'TestF' is missing a [super encodeRestorableStateWithCoder:] call}}
185@end
186
187// Do not warn for NSResponder subclasses that do the right thing
188@interface TestG : NSResponder {}
189@end
190@implementation TestG
191
192- (void)restoreStateWithCoder:(NSCoder *)coder {
193	[super restoreStateWithCoder:coder];
194}
195- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
196	[super encodeRestorableStateWithCoder:coder];
197}
198@end
199
200// Do warn for NSDocument subclasses that don't call super
201@interface TestH : NSDocument {}
202@end
203@implementation TestH
204
205- (void)restoreStateWithCoder:(NSCoder *)coder {
206} // expected-warning {{The 'restoreStateWithCoder:' instance method in NSDocument subclass 'TestH' is missing a [super restoreStateWithCoder:] call}}
207- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
208} // expected-warning {{The 'encodeRestorableStateWithCoder:' instance method in NSDocument subclass 'TestH' is missing a [super encodeRestorableStateWithCoder:] call}}
209@end
210
211// Do not warn for NSDocument subclasses that do the right thing
212@interface TestI : NSDocument {}
213@end
214@implementation TestI
215
216- (void)restoreStateWithCoder:(NSCoder *)coder {
217	[super restoreStateWithCoder:coder];
218}
219- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
220	[super encodeRestorableStateWithCoder:coder];
221}
222@end