1// RUN: %clang_analyze_cc1 -fblocks -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// Do not warn for the implementation in the superclass itself. 73@implementation UIViewController 74- (void)addChildViewController:(UIViewController *)childController {} 75- (void)viewDidAppear:(BOOL)animated {} 76- (void)viewDidDisappear:(BOOL)animated {} 77- (void)viewDidUnload {} 78- (void)viewDidLoad {} 79- (void)viewWillUnload {} 80- (void)viewWillAppear:(BOOL)animated {} 81- (void)viewWillDisappear:(BOOL)animated {} 82- (void)didReceiveMemoryWarning {} 83- (void)removeFromParentViewController {} 84- (void)transitionFromViewController:(UIViewController *)fromViewController 85 toViewController:(UIViewController *)toViewController 86 duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options 87 animations:(void (^)(void))animations 88 completion:(void (^)(BOOL finished))completion {} 89@end 90 91// Warn if UIViewController is our superclass and we do not call super 92@interface TestB : UIViewController {} 93@end 94@implementation TestB 95 96- (void)addChildViewController:(UIViewController *)childController { 97 int addChildViewController = 5; 98 for (int i = 0; i < addChildViewController; i++) 99 [self viewDidAppear:i]; 100} // expected-warning {{The 'addChildViewController:' instance method in UIViewController subclass 'TestB' is missing a [super addChildViewController:] call}} 101- (void)viewDidAppear:(BOOL)animated {} // expected-warning {{The 'viewDidAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidAppear:] call}} 102- (void)viewDidDisappear:(BOOL)animated {} // expected-warning {{The 'viewDidDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidDisappear:] call}} 103- (void)viewDidUnload {} // expected-warning {{The 'viewDidUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewDidUnload] call}} 104- (void)viewDidLoad {} // expected-warning {{The 'viewDidLoad' instance method in UIViewController subclass 'TestB' is missing a [super viewDidLoad] call}} 105- (void)viewWillUnload {} // expected-warning {{The 'viewWillUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewWillUnload] call}} 106- (void)viewWillAppear:(BOOL)animated {} // expected-warning {{The 'viewWillAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillAppear:] call}} 107- (void)viewWillDisappear:(BOOL)animated {} // expected-warning {{The 'viewWillDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillDisappear:] call}} 108- (void)didReceiveMemoryWarning {} // expected-warning {{The 'didReceiveMemoryWarning' instance method in UIViewController subclass 'TestB' is missing a [super didReceiveMemoryWarning] call}} 109- (void)removeFromParentViewController {} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestB' is missing a [super removeFromParentViewController] call}} 110 111// Do not warn for methods were it shouldn't 112- (void)shouldAutorotate {} 113@end 114 115// Do not warn if UIViewController is our superclass but we did call super 116@interface TestC : UIViewController {} 117@end 118@implementation TestC 119 120- (BOOL)methodReturningStuff { 121 return 1; 122} 123 124- (void)methodDoingStuff { 125 [super removeFromParentViewController]; 126} 127 128- (void)addChildViewController:(UIViewController *)childController { 129 [super addChildViewController:childController]; 130} 131 132- (void)viewDidAppear:(BOOL)animated { 133 [super viewDidAppear:animated]; 134} 135 136- (void)viewDidDisappear:(BOOL)animated { 137 [super viewDidDisappear:animated]; 138} 139 140- (void)viewDidUnload { 141 [super viewDidUnload]; 142} 143 144- (void)viewDidLoad { 145 [super viewDidLoad]; 146} 147 148- (void)viewWillUnload { 149 [super viewWillUnload]; 150} 151 152- (void)viewWillAppear:(BOOL)animated { 153 int i = 0; // Also don't start warning just because we do additional stuff 154 i++; 155 [self viewDidDisappear:i]; 156 [super viewWillAppear:animated]; 157} 158 159- (void)viewWillDisappear:(BOOL)animated { 160 [super viewWillDisappear:[self methodReturningStuff]]; 161} 162 163- (void)didReceiveMemoryWarning { 164 [super didReceiveMemoryWarning]; 165} 166 167// We expect a warning here because at the moment the super-call can't be 168// done from another method. 169- (void)removeFromParentViewController { 170 [self methodDoingStuff]; 171} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestC' is missing a [super removeFromParentViewController] call}} 172@end 173 174 175// Do warn for UIResponder subclasses that don't call super 176@interface TestD : UIResponder {} 177@end 178@implementation TestD 179 180- (BOOL)resignFirstResponder { 181 return 0; 182} // expected-warning {{The 'resignFirstResponder' instance method in UIResponder subclass 'TestD' is missing a [super resignFirstResponder] call}} 183@end 184 185// Do not warn for UIResponder subclasses that do the right thing 186@interface TestE : UIResponder {} 187@end 188@implementation TestE 189 190- (BOOL)resignFirstResponder { 191 return [super resignFirstResponder]; 192} 193@end 194 195// Do warn for NSResponder subclasses that don't call super 196@interface TestF : NSResponder {} 197@end 198@implementation TestF 199 200- (void)restoreStateWithCoder:(NSCoder *)coder { 201} // expected-warning {{The 'restoreStateWithCoder:' instance method in NSResponder subclass 'TestF' is missing a [super restoreStateWithCoder:] call}} 202- (void)encodeRestorableStateWithCoder:(NSCoder *)coder { 203} // expected-warning {{The 'encodeRestorableStateWithCoder:' instance method in NSResponder subclass 'TestF' is missing a [super encodeRestorableStateWithCoder:] call}} 204@end 205 206// Do not warn for NSResponder subclasses that do the right thing 207@interface TestG : NSResponder {} 208@end 209@implementation TestG 210 211- (void)restoreStateWithCoder:(NSCoder *)coder { 212 [super restoreStateWithCoder:coder]; 213} 214- (void)encodeRestorableStateWithCoder:(NSCoder *)coder { 215 [super encodeRestorableStateWithCoder:coder]; 216} 217@end 218 219// Do warn for NSDocument subclasses that don't call super 220@interface TestH : NSDocument {} 221@end 222@implementation TestH 223 224- (void)restoreStateWithCoder:(NSCoder *)coder { 225} // expected-warning {{The 'restoreStateWithCoder:' instance method in NSDocument subclass 'TestH' is missing a [super restoreStateWithCoder:] call}} 226- (void)encodeRestorableStateWithCoder:(NSCoder *)coder { 227} // expected-warning {{The 'encodeRestorableStateWithCoder:' instance method in NSDocument subclass 'TestH' is missing a [super encodeRestorableStateWithCoder:] call}} 228@end 229 230// Do not warn for NSDocument subclasses that do the right thing 231@interface TestI : NSDocument {} 232@end 233@implementation TestI 234 235- (void)restoreStateWithCoder:(NSCoder *)coder { 236 [super restoreStateWithCoder:coder]; 237} 238- (void)encodeRestorableStateWithCoder:(NSCoder *)coder { 239 [super encodeRestorableStateWithCoder:coder]; 240} 241@end