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