summaryrefslogtreecommitdiffstats
path: root/test/Analysis/superclass.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/superclass.m')
-rw-r--r--test/Analysis/superclass.m222
1 files changed, 222 insertions, 0 deletions
diff --git a/test/Analysis/superclass.m b/test/Analysis/superclass.m
new file mode 100644
index 0000000..ba5ea40
--- /dev/null
+++ b/test/Analysis/superclass.m
@@ -0,0 +1,222 @@
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=alpha.osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
+
+// Define used Classes
+@protocol NSObject
+- (id)retain;
+- (oneway void)release;
+@end
+@interface NSObject <NSObject> {}
+- (id)init;
++ (id)alloc;
+@end
+typedef char BOOL;
+typedef double NSTimeInterval;
+typedef enum UIViewAnimationOptions {
+ UIViewAnimationOptionLayoutSubviews = 1 << 0
+} UIViewAnimationOptions;
+@interface NSCoder : NSObject {}
+@end
+
+// Define the Superclasses for our Checks
+@interface UIViewController : NSObject {}
+- (void)addChildViewController:(UIViewController *)childController;
+- (void)viewDidAppear:(BOOL)animated;
+- (void)viewDidDisappear:(BOOL)animated;
+- (void)viewDidUnload;
+- (void)viewDidLoad;
+- (void)viewWillUnload;
+- (void)viewWillAppear:(BOOL)animated;
+- (void)viewWillDisappear:(BOOL)animated;
+- (void)didReceiveMemoryWarning;
+- (void)removeFromParentViewController;
+- (void)transitionFromViewController:(UIViewController *)fromViewController
+ toViewController:(UIViewController *)toViewController
+ duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options
+ animations:(void (^)(void))animations
+ completion:(void (^)(BOOL finished))completion;
+@end
+@interface UIResponder : NSObject {}
+- (BOOL)resignFirstResponder;
+@end
+@interface NSResponder : NSObject {}
+- (void)restoreStateWithCoder:(NSCoder *)coder;
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder;
+@end
+@interface NSDocument : NSObject {}
+- (void)restoreStateWithCoder:(NSCoder *)coder;
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder;
+@end
+
+// Checks
+
+// Do not warn if UIViewController/*Responder/NSDocument is not our superclass
+@interface TestA
+@end
+@implementation TestA
+
+- (void)addChildViewController:(UIViewController *)childController {}
+- (void)viewDidAppear:(BOOL)animated {}
+- (void)viewDidDisappear:(BOOL)animated {}
+- (void)viewDidUnload {}
+- (void)viewDidLoad {}
+- (void)viewWillUnload {}
+- (void)viewWillAppear:(BOOL)animated {}
+- (void)viewWillDisappear:(BOOL)animated {}
+- (void)didReceiveMemoryWarning {}
+- (void)removeFromParentViewController {}
+- (BOOL)resignFirstResponder { return 0; }
+- (void)restoreStateWithCoder:(NSCoder *)coder {}
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {}
+@end
+
+// Warn if UIViewController is our superclass and we do not call super
+@interface TestB : UIViewController {}
+@end
+@implementation TestB
+
+- (void)addChildViewController:(UIViewController *)childController {
+ int addChildViewController = 5;
+ for (int i = 0; i < addChildViewController; i++)
+ [self viewDidAppear:i];
+} // expected-warning {{The 'addChildViewController:' instance method in UIViewController subclass 'TestB' is missing a [super addChildViewController:] call}}
+- (void)viewDidAppear:(BOOL)animated {} // expected-warning {{The 'viewDidAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidAppear:] call}}
+- (void)viewDidDisappear:(BOOL)animated {} // expected-warning {{The 'viewDidDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewDidDisappear:] call}}
+- (void)viewDidUnload {} // expected-warning {{The 'viewDidUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewDidUnload] call}}
+- (void)viewDidLoad {} // expected-warning {{The 'viewDidLoad' instance method in UIViewController subclass 'TestB' is missing a [super viewDidLoad] call}}
+- (void)viewWillUnload {} // expected-warning {{The 'viewWillUnload' instance method in UIViewController subclass 'TestB' is missing a [super viewWillUnload] call}}
+- (void)viewWillAppear:(BOOL)animated {} // expected-warning {{The 'viewWillAppear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillAppear:] call}}
+- (void)viewWillDisappear:(BOOL)animated {} // expected-warning {{The 'viewWillDisappear:' instance method in UIViewController subclass 'TestB' is missing a [super viewWillDisappear:] call}}
+- (void)didReceiveMemoryWarning {} // expected-warning {{The 'didReceiveMemoryWarning' instance method in UIViewController subclass 'TestB' is missing a [super didReceiveMemoryWarning] call}}
+- (void)removeFromParentViewController {} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestB' is missing a [super removeFromParentViewController] call}}
+
+// Do not warn for methods were it shouldn't
+- (void)shouldAutorotate {}
+@end
+
+// Do not warn if UIViewController is our superclass but we did call super
+@interface TestC : UIViewController {}
+@end
+@implementation TestC
+
+- (BOOL)methodReturningStuff {
+ return 1;
+}
+
+- (void)methodDoingStuff {
+ [super removeFromParentViewController];
+}
+
+- (void)addChildViewController:(UIViewController *)childController {
+ [super addChildViewController:childController];
+}
+
+- (void)viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+}
+
+- (void)viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+}
+
+- (void)viewDidUnload {
+ [super viewDidUnload];
+}
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+}
+
+- (void)viewWillUnload {
+ [super viewWillUnload];
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+ int i = 0; // Also don't start warning just because we do additional stuff
+ i++;
+ [self viewDidDisappear:i];
+ [super viewWillAppear:animated];
+}
+
+- (void)viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:[self methodReturningStuff]];
+}
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+}
+
+// We expect a warning here because at the moment the super-call can't be
+// done from another method.
+- (void)removeFromParentViewController {
+ [self methodDoingStuff];
+} // expected-warning {{The 'removeFromParentViewController' instance method in UIViewController subclass 'TestC' is missing a [super removeFromParentViewController] call}}
+@end
+
+
+// Do warn for UIResponder subclasses that don't call super
+@interface TestD : UIResponder {}
+@end
+@implementation TestD
+
+- (BOOL)resignFirstResponder {
+ return 0;
+} // expected-warning {{The 'resignFirstResponder' instance method in UIResponder subclass 'TestD' is missing a [super resignFirstResponder] call}}
+@end
+
+// Do not warn for UIResponder subclasses that do the right thing
+@interface TestE : UIResponder {}
+@end
+@implementation TestE
+
+- (BOOL)resignFirstResponder {
+ return [super resignFirstResponder];
+}
+@end
+
+// Do warn for NSResponder subclasses that don't call super
+@interface TestF : NSResponder {}
+@end
+@implementation TestF
+
+- (void)restoreStateWithCoder:(NSCoder *)coder {
+} // expected-warning {{The 'restoreStateWithCoder:' instance method in NSResponder subclass 'TestF' is missing a [super restoreStateWithCoder:] call}}
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
+} // expected-warning {{The 'encodeRestorableStateWithCoder:' instance method in NSResponder subclass 'TestF' is missing a [super encodeRestorableStateWithCoder:] call}}
+@end
+
+// Do not warn for NSResponder subclasses that do the right thing
+@interface TestG : NSResponder {}
+@end
+@implementation TestG
+
+- (void)restoreStateWithCoder:(NSCoder *)coder {
+ [super restoreStateWithCoder:coder];
+}
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
+ [super encodeRestorableStateWithCoder:coder];
+}
+@end
+
+// Do warn for NSDocument subclasses that don't call super
+@interface TestH : NSDocument {}
+@end
+@implementation TestH
+
+- (void)restoreStateWithCoder:(NSCoder *)coder {
+} // expected-warning {{The 'restoreStateWithCoder:' instance method in NSDocument subclass 'TestH' is missing a [super restoreStateWithCoder:] call}}
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
+} // expected-warning {{The 'encodeRestorableStateWithCoder:' instance method in NSDocument subclass 'TestH' is missing a [super encodeRestorableStateWithCoder:] call}}
+@end
+
+// Do not warn for NSDocument subclasses that do the right thing
+@interface TestI : NSDocument {}
+@end
+@implementation TestI
+
+- (void)restoreStateWithCoder:(NSCoder *)coder {
+ [super restoreStateWithCoder:coder];
+}
+- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
+ [super encodeRestorableStateWithCoder:coder];
+}
+@end \ No newline at end of file
OpenPOWER on IntegriCloud