Jordan Rose | 3cf9a72 | 2012-10-30 01:21:35 +0000 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=alpha.osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s |
| 2 | |
| 3 | @protocol NSObject |
| 4 | - (id)retain; |
| 5 | - (oneway void)release; |
| 6 | @end |
| 7 | @interface NSObject <NSObject> {} |
| 8 | - (id)init; |
| 9 | + (id)alloc; |
| 10 | @end |
| 11 | |
| 12 | typedef char BOOL; |
| 13 | typedef double NSTimeInterval; |
| 14 | typedef enum UIViewAnimationOptions { |
| 15 | UIViewAnimationOptionLayoutSubviews = 1 << 0 |
| 16 | } UIViewAnimationOptions; |
| 17 | |
| 18 | @interface UIViewController : NSObject {} |
| 19 | - (void)addChildViewController:(UIViewController *)childController; |
| 20 | - (void)viewDidAppear:(BOOL)animated; |
| 21 | - (void)viewDidDisappear:(BOOL)animated; |
| 22 | - (void)viewDidUnload; |
| 23 | - (void)viewDidLoad; |
| 24 | - (void)viewWillUnload; |
| 25 | - (void)viewWillAppear:(BOOL)animated; |
| 26 | - (void)viewWillDisappear:(BOOL)animated; |
| 27 | - (void)didReceiveMemoryWarning; |
| 28 | - (void)removeFromParentViewController; |
| 29 | - (void)transitionFromViewController:(UIViewController *)fromViewController |
| 30 | toViewController:(UIViewController *)toViewController |
| 31 | duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options |
| 32 | animations:(void (^)(void))animations |
| 33 | completion:(void (^)(BOOL finished))completion; |
| 34 | @end |
| 35 | |
| 36 | // Do not warn if UIViewController isn't our superclass |
| 37 | @interface TestA |
| 38 | @end |
| 39 | @implementation TestA |
| 40 | |
| 41 | - (void)addChildViewController:(UIViewController *)childController {} |
| 42 | - (void)viewDidAppear:(BOOL)animated {} |
| 43 | - (void)viewDidDisappear:(BOOL)animated {} |
| 44 | - (void)viewDidUnload {} |
| 45 | - (void)viewDidLoad {} |
| 46 | - (void)viewWillUnload {} |
| 47 | - (void)viewWillAppear:(BOOL)animated {} |
| 48 | - (void)viewWillDisappear:(BOOL)animated {} |
| 49 | - (void)didReceiveMemoryWarning {} |
| 50 | - (void)removeFromParentViewController {} |
| 51 | |
| 52 | @end |
| 53 | |
| 54 | // Warn if UIViewController is our superclass and we do not call super |
| 55 | @interface TestB : UIViewController {} |
| 56 | @end |
| 57 | @implementation TestB |
| 58 | |
| 59 | - (void)addChildViewController:(UIViewController *)childController { |
| 60 | int addChildViewController = 5; |
| 61 | for (int i = 0; i < addChildViewController; i++) |
| 62 | [self viewDidAppear:i]; |
| 63 | } // expected-warning {{The 'addChildViewController:' instance method in UIViewController subclass 'TestB' is missing a [super addChildViewController:] call}} |
| 64 | - (void)viewDidAppear:(BOOL)animated {} // expected-warning {{The 'viewDidAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidAppear:] call}} |
| 65 | - (void)viewDidDisappear:(BOOL)animated {} // expected-warning {{The 'viewDidDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidDisappear:] call}} |
| 66 | - (void)viewDidUnload {} // expected-warning {{The 'viewDidUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewDidUnload] call}} |
| 67 | - (void)viewDidLoad {} // expected-warning {{The 'viewDidLoad' instance method in UIViewController subclass 'TestB' is missing a [super viewDidLoad] call}} |
| 68 | - (void)viewWillUnload {} // expected-warning {{The 'viewWillUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewWillUnload] call}} |
| 69 | - (void)viewWillAppear:(BOOL)animated {} // expected-warning {{The 'viewWillAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillAppear:] call}} |
| 70 | - (void)viewWillDisappear:(BOOL)animated {} // expected-warning {{The 'viewWillDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillDisappear:] call}} |
| 71 | - (void)didReceiveMemoryWarning {} // expected-warning {{The 'didReceiveMemoryWarning' instance method in UIViewController subclass 'TestB' is missing a [super didReceiveMemoryWarning] call}} |
| 72 | - (void)removeFromParentViewController {} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestB' is missing a [super removeFromParentViewController] call}} |
| 73 | |
| 74 | // Do not warn for methods were it shouldn't |
| 75 | - (void)shouldAutorotate {}; |
| 76 | @end |
| 77 | |
| 78 | // Do not warn if UIViewController is our superclass but we did call super |
| 79 | @interface TestC : UIViewController {} |
| 80 | @end |
| 81 | @implementation TestC |
| 82 | |
| 83 | - (BOOL)methodReturningStuff { |
| 84 | return 1; |
| 85 | } |
| 86 | |
| 87 | - (void)methodDoingStuff { |
| 88 | [super removeFromParentViewController]; |
| 89 | } |
| 90 | |
| 91 | - (void)addChildViewController:(UIViewController *)childController { |
| 92 | [super addChildViewController:childController]; |
| 93 | } |
| 94 | |
| 95 | - (void)viewDidAppear:(BOOL)animated { |
| 96 | [super viewDidAppear:animated]; |
| 97 | } |
| 98 | |
| 99 | - (void)viewDidDisappear:(BOOL)animated { |
| 100 | [super viewDidDisappear:animated]; |
| 101 | } |
| 102 | |
| 103 | - (void)viewDidUnload { |
| 104 | [super viewDidUnload]; |
| 105 | } |
| 106 | |
| 107 | - (void)viewDidLoad { |
| 108 | [super viewDidLoad]; |
| 109 | } |
| 110 | |
| 111 | - (void)viewWillUnload { |
| 112 | [super viewWillUnload]; |
| 113 | } |
| 114 | |
| 115 | - (void)viewWillAppear:(BOOL)animated { |
| 116 | int i = 0; // Also don't start warning just because we do additional stuff |
| 117 | i++; |
| 118 | [self viewDidDisappear:i]; |
| 119 | [super viewWillAppear:animated]; |
| 120 | } |
| 121 | |
| 122 | - (void)viewWillDisappear:(BOOL)animated { |
| 123 | [super viewWillDisappear:[self methodReturningStuff]]; |
| 124 | } |
| 125 | |
| 126 | - (void)didReceiveMemoryWarning { |
| 127 | [super didReceiveMemoryWarning]; |
| 128 | } |
| 129 | |
| 130 | // We expect a warning here because at the moment the super-call can't be |
| 131 | // done from another method. |
| 132 | - (void)removeFromParentViewController { |
| 133 | [self methodDoingStuff]; |
| 134 | } // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestC' is missing a [super removeFromParentViewController] call}} |
| 135 | @end |