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 12 typedef char BOOL; 13 typedef double NSTimeInterval; 14 typedef 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