1// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=alpha.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