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 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 // 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