Home | History | Annotate | Download | only in Analysis
      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