aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/test/clang-tidy/checkers/objc
diff options
context:
space:
mode:
authorRichard <legalize@xmission.com>2022-06-16 19:02:47 -0600
committerRichard <legalize@xmission.com>2022-06-22 12:13:34 -0600
commit89a1d03e2b379e325daa5249411e414bbd995b5e (patch)
tree9b1c9bad407c0fab8815cdd4780b80ace670050e /clang-tools-extra/test/clang-tidy/checkers/objc
parent130167ed1effa36aa56c83c4293e732e5163d993 (diff)
downloadllvm-89a1d03e2b379e325daa5249411e414bbd995b5e.zip
llvm-89a1d03e2b379e325daa5249411e414bbd995b5e.tar.gz
llvm-89a1d03e2b379e325daa5249411e414bbd995b5e.tar.bz2
[clang-tidy] Organize test files into subdirectories by module (NFC)
Eliminate clutter by reorganizing the Lit test files for clang-tidy: - Move checkers/<module>-* to checkers/<module>/*. - Move module specific inputs from Inputs to <module>/Inputs. Remove any module prefix from the file or subdirectory name as they are no longer needed. - Introduce a Lit substitution %clang_tidy_headers for the system headers in checkers/Inputs/Headers and use this throughout. This avoids referencing system headers through a relative path to the parent directory and makes it clear that these fake system headers are shared among all modules. - Update add_new_check.py to follow the above conventions when creating the boiler plate test files for a new check. - Update Contributing.rst to describe per-module Inputs directory and fix link to test source code. Differential Revision: https://reviews.llvm.org/D128072
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/checkers/objc')
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/Inputs/assert/XCTestAssertions.h30
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/assert-equals.m25
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/avoid-nserror-init.m12
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/dealloc-in-category.m47
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing-custom.m39
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing.m21
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/missing-hash.m68
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/nsinvocation-argument-lifetime.m103
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/property-declaration.m55
-rw-r--r--clang-tools-extra/test/clang-tidy/checkers/objc/super-self.m86
10 files changed, 486 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/Inputs/assert/XCTestAssertions.h b/clang-tools-extra/test/clang-tidy/checkers/objc/Inputs/assert/XCTestAssertions.h
new file mode 100644
index 0000000..c2e3fba
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/Inputs/assert/XCTestAssertions.h
@@ -0,0 +1,30 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+#define THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+
+#define _XCTPrimitiveAssertEqual(test, expression1, expressionStr1, \
+ expression2, expressionStr2, ...) \
+ ({ \
+ __typeof__(expression1) expressionValue1 = (expression1); \
+ __typeof__(expression2) expressionValue2 = (expression2); \
+ if (expressionValue1 != expressionValue2) { \
+ } \
+ })
+
+#define _XCTPrimitiveAssertEqualObjects(test, expression1, expressionStr1, \
+ expression2, expressionStr2, ...) \
+ ({ \
+ __typeof__(expression1) expressionValue1 = (expression1); \
+ __typeof__(expression2) expressionValue2 = (expression2); \
+ if (expressionValue1 != expressionValue2) { \
+ } \
+ })
+
+#define XCTAssertEqual(expression1, expression2, ...) \
+ _XCTPrimitiveAssertEqual(nil, expression1, @ #expression1, expression2, \
+ @ #expression2, __VA_ARGS__)
+
+#define XCTAssertEqualObjects(expression1, expression2, ...) \
+ _XCTPrimitiveAssertEqualObjects(nil, expression1, @ #expression1, \
+ expression2, @ #expression2, __VA_ARGS__)
+
+#endif // THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/assert-equals.m b/clang-tools-extra/test/clang-tidy/checkers/objc/assert-equals.m
new file mode 100644
index 0000000..e7787cf
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/assert-equals.m
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s objc-assert-equals %t -- -- -I %S/Inputs/assert
+#include "XCTestAssertions.h"
+// Can't reference NSString directly so we use this getStr() instead.
+__typeof(@"abc") getStr(void) {
+ return @"abc";
+}
+void foo(void) {
+ XCTAssertEqual(getStr(), @"abc");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+ // CHECK-FIXES: XCTAssertEqualObjects(getStr(), @"abc");
+ XCTAssertEqual(@"abc", @"abc");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+ // CHECK-FIXES: XCTAssertEqualObjects(@"abc", @"abc");
+ XCTAssertEqual(@"abc", getStr());
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+ // CHECK-FIXES: XCTAssertEqualObjects(@"abc", getStr());
+ XCTAssertEqual(getStr(), getStr());
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+ // CHECK-FIXES: XCTAssertEqualObjects(getStr(), getStr());
+ // Primitive types should be ok
+ XCTAssertEqual(123, 123);
+ XCTAssertEqual(123.0, 123.45);
+ // FIXME: This is the case where we don't diagnose properly.
+ // XCTAssertEqual(@"abc" != @"abc", @"xyz" != @"xyz")
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/avoid-nserror-init.m b/clang-tools-extra/test/clang-tidy/checkers/objc/avoid-nserror-init.m
new file mode 100644
index 0000000..7794077
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/avoid-nserror-init.m
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s objc-avoid-nserror-init %t
+@interface NSError
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@implementation foo
+- (void)bar {
+ NSError *error = [[NSError alloc] init];
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use errorWithDomain:code:userInfo: or initWithDomain:code:userInfo: to create a new NSError [objc-avoid-nserror-init]
+}
+@end
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/dealloc-in-category.m b/clang-tools-extra/test/clang-tidy/checkers/objc/dealloc-in-category.m
new file mode 100644
index 0000000..4785503
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/dealloc-in-category.m
@@ -0,0 +1,47 @@
+// RUN: %check_clang_tidy %s objc-dealloc-in-category %t
+
+@interface NSObject
+// Used to quash warning about missing base class.
+- (void)dealloc;
+@end
+
+@interface Foo : NSObject
+@end
+
+@implementation Foo
+- (void)dealloc {
+ // No warning should be generated here.
+}
+@end
+
+@interface Bar : NSObject
+@end
+
+@interface Bar (BarCategory)
+@end
+
+@implementation Bar (BarCategory)
++ (void)dealloc {
+ // Should not trigger on class methods.
+}
+
+- (void)dealloc {
+ // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: category 'BarCategory' should not implement -dealloc [objc-dealloc-in-category]
+}
+@end
+
+@interface Baz : NSObject
+@end
+
+@implementation Baz
+- (void)dealloc {
+ // Should not trigger on implementation in the class itself, even with
+ // it declared in the category (below).
+}
+@end
+
+@interface Baz (BazCategory)
+// A declaration in a category @interface does not by itself provide an
+// overriding implementation, and should not generate a warning.
+- (void)dealloc;
+@end
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing-custom.m b/clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing-custom.m
new file mode 100644
index 0000000..59e6a88
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing-custom.m
@@ -0,0 +1,39 @@
+// RUN: %check_clang_tidy %s objc-forbidden-subclassing %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: objc-forbidden-subclassing.ClassNames, value: "Foo;Quux"}]}' \
+// RUN: --
+
+@interface UIImagePickerController
+@end
+
+// Make sure custom config options replace (not add to) the default list.
+@interface Waldo : UIImagePickerController
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: Objective-C interface 'Waldo' subclasses 'UIImagePickerController', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Foo
+@end
+
+@interface Bar : Foo
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Bar' subclasses 'Foo', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+// Check subclasses of subclasses.
+@interface Baz : Bar
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Baz' subclasses 'Foo', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Quux
+@end
+
+// Check that more than one forbidden superclass can be specified.
+@interface Xyzzy : Quux
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Xyzzy' subclasses 'Quux', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Plugh
+@end
+
+@interface Corge : Plugh
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: Objective-C interface 'Corge' subclasses 'Plugh', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing.m b/clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing.m
new file mode 100644
index 0000000..3ad38bf
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/forbidden-subclassing.m
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s objc-forbidden-subclassing %t
+
+@interface UIImagePickerController
+@end
+
+@interface Foo : UIImagePickerController
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Foo' subclasses 'UIImagePickerController', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+// Check subclasses of subclasses.
+@interface Bar : Foo
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Objective-C interface 'Bar' subclasses 'UIImagePickerController', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
+
+@interface Baz
+@end
+
+// Make sure innocent subclasses aren't caught by the check.
+@interface Blech : Baz
+// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: Objective-C interface 'Blech' subclasses 'Baz', which is not intended to be subclassed [objc-forbidden-subclassing]
+@end
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/missing-hash.m b/clang-tools-extra/test/clang-tidy/checkers/objc/missing-hash.m
new file mode 100644
index 0000000..b9cc9d0
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/missing-hash.m
@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s objc-missing-hash %t
+
+typedef _Bool BOOL;
+#define YES 1
+#define NO 0
+typedef unsigned int NSUInteger;
+typedef void *id;
+
+@interface NSObject
+- (NSUInteger)hash;
+- (BOOL)isEqual:(id)object;
+@end
+
+@interface MissingHash : NSObject
+@end
+
+@implementation MissingHash
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'MissingHash' implements -isEqual: without implementing -hash [objc-missing-hash]
+
+- (BOOL)isEqual:(id)object {
+ return YES;
+}
+
+@end
+
+@interface HasHash : NSObject
+@end
+
+@implementation HasHash
+
+- (NSUInteger)hash {
+ return 0;
+}
+
+- (BOOL)isEqual:(id)object {
+ return YES;
+}
+
+@end
+
+@interface NSArray : NSObject
+@end
+
+@interface MayHaveInheritedHash : NSArray
+@end
+
+@implementation MayHaveInheritedHash
+
+- (BOOL)isEqual:(id)object {
+ return YES;
+}
+
+@end
+
+@interface AnotherRootClass
+@end
+
+@interface NotDerivedFromNSObject : AnotherRootClass
+@end
+
+@implementation NotDerivedFromNSObject
+
+- (BOOL)isEqual:(id)object {
+ return NO;
+}
+
+@end
+
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/nsinvocation-argument-lifetime.m b/clang-tools-extra/test/clang-tidy/checkers/objc/nsinvocation-argument-lifetime.m
new file mode 100644
index 0000000..3583a3e
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/nsinvocation-argument-lifetime.m
@@ -0,0 +1,103 @@
+// RUN: %check_clang_tidy %s objc-nsinvocation-argument-lifetime %t
+
+__attribute__((objc_root_class))
+@interface NSObject
+@end
+
+@interface NSInvocation : NSObject
+- (void)getArgument:(void *)Arg atIndex:(int)Index;
+- (void)getReturnValue:(void *)ReturnValue;
+@end
+
+@interface OtherClass : NSObject
+- (void)getArgument:(void *)Arg atIndex:(int)Index;
+@end
+
+struct Foo {
+ __unsafe_unretained id Field1;
+ id Field2;
+ int IntField;
+};
+
+void foo(NSInvocation *Invocation) {
+ __unsafe_unretained id Arg2;
+ id Arg3;
+ // CHECK-FIXES: __unsafe_unretained id Arg3;
+ NSObject __strong *Arg4;
+ // CHECK-FIXES: NSObject __unsafe_unretained *Arg4;
+ __weak id Arg5;
+ // CHECK-FIXES: __unsafe_unretained id Arg5;
+ id ReturnValue;
+ // CHECK-FIXES: __unsafe_unretained id ReturnValue;
+ void (^BlockArg1)(void);
+ // CHECK-FIXES: __unsafe_unretained void (^BlockArg1)(void);
+ __unsafe_unretained void (^BlockArg2)(void);
+ int IntVar;
+ struct Foo Bar;
+
+ [Invocation getArgument:&Arg2 atIndex:2];
+ [Invocation getArgument:&IntVar atIndex:2];
+
+ [Invocation getArgument:&Arg3 atIndex:3];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+
+ [Invocation getArgument:&Arg4 atIndex:4];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+
+ [Invocation getArgument:&Arg5 atIndex:5];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+
+ [Invocation getArgument:&BlockArg1 atIndex:6];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+
+ [Invocation getArgument:&BlockArg2 atIndex:6];
+
+ [Invocation getReturnValue:&ReturnValue];
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: NSInvocation '-getReturnValue:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+
+ [Invocation getArgument:(void *)0 atIndex:6];
+
+ [Invocation getArgument:&Bar.Field1 atIndex:2];
+ [Invocation getArgument:&Bar.Field2 atIndex:2];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+ [Invocation getArgument:&Bar.IntField atIndex:2];
+}
+
+void bar(OtherClass *OC) {
+ id Arg;
+ [OC getArgument:&Arg atIndex:2];
+}
+
+@interface TestClass : NSObject {
+@public
+ id Argument1;
+ __unsafe_unretained id Argument2;
+ struct Foo Bar;
+ int IntIvar;
+}
+@end
+
+@implementation TestClass
+
+- (void)processInvocation:(NSInvocation *)Invocation {
+ [Invocation getArgument:&Argument1 atIndex:2];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+ [Invocation getArgument:&self->Argument1 atIndex:2];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+ [Invocation getArgument:&Argument2 atIndex:2];
+ [Invocation getArgument:&self->Argument2 atIndex:2];
+ [Invocation getArgument:&self->IntIvar atIndex:2];
+
+ [Invocation getReturnValue:&(self->Bar.Field1)];
+ [Invocation getReturnValue:&(self->Bar.Field2)];
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: NSInvocation '-getReturnValue:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+ [Invocation getReturnValue:&(self->Bar.IntField)];
+}
+
+@end
+
+void baz(NSInvocation *Invocation, TestClass *Obj) {
+ [Invocation getArgument:&Obj->Argument1 atIndex:2];
+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime]
+ [Invocation getArgument:&Obj->Argument2 atIndex:2];
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/property-declaration.m b/clang-tools-extra/test/clang-tidy/checkers/objc/property-declaration.m
new file mode 100644
index 0000000..b56bdcd
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/property-declaration.m
@@ -0,0 +1,55 @@
+// RUN: %check_clang_tidy %s objc-property-declaration %t
+@class CIColor;
+@class NSArray;
+@class NSData;
+@class NSString;
+@class UIViewController;
+
+typedef void *CGColorRef;
+
+@interface Foo
+@property(assign, nonatomic) int NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'NotCamelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int notCamelCase;
+@property(assign, nonatomic) int camelCase;
+@property(strong, nonatomic) NSString *URLString;
+@property(strong, nonatomic) NSString *bundleID;
+@property(strong, nonatomic) NSData *RGBABytes;
+@property(strong, nonatomic) UIViewController *notificationsVC;
+@property(strong, nonatomic) NSString *URL_string;
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: property name 'URL_string' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@property(strong, nonatomic) NSString *supportURLsCamelCase;
+@property(strong, nonatomic) NSString *supportURLCamelCase;
+@property(strong, nonatomic) NSString *VCsPluralToAdd;
+@property(assign, nonatomic) int centerX;
+@property(assign, nonatomic) int enable2GBackgroundFetch;
+@property(assign, nonatomic) int shouldUseCFPreferences;
+@property(assign, nonatomic) int enableGLAcceleration;
+@property(assign, nonatomic) int ID;
+@property(assign, nonatomic) int hasADog;
+@property(nonatomic, readonly) CGColorRef CGColor;
+@property(nonatomic, readonly) CIColor *CIColor;
+@property(nonatomic, copy) NSArray *IDs;
+@end
+
+@interface Foo (Bar)
+@property(assign, nonatomic) int abc_NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abc_NotCamelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@property(assign, nonatomic) int abCD_camelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abCD_camelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int abcd_camelCase;
+@property(assign, nonatomic) int abCD_NotCamelCase;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abCD_NotCamelCase' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+// CHECK-FIXES: @property(assign, nonatomic) int abcd_notCamelCase;
+@property(assign, nonatomic) int wrongFormat_;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'wrongFormat_' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@property(strong, nonatomic) NSString *URLStr;
+@property(assign, nonatomic) int abc_camelCase;
+@property(strong, nonatomic) NSString *abc_URL;
+@property(strong, nonatomic) NSString *opac2_sourceComponent;
+@end
+
+@interface Foo ()
+@property(assign, nonatomic) int abc_inClassExtension;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: property name 'abc_inClassExtension' not using lowerCamelCase style or not prefixed in a category, according to the Apple Coding Guidelines [objc-property-declaration]
+@end \ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/objc/super-self.m b/clang-tools-extra/test/clang-tidy/checkers/objc/super-self.m
new file mode 100644
index 0000000..9653cd2
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/objc/super-self.m
@@ -0,0 +1,86 @@
+// RUN: %check_clang_tidy %s objc-super-self %t
+
+@interface NSObject
+- (instancetype)init;
+- (instancetype)self;
+@end
+
+@interface NSObjectDerivedClass : NSObject
+@end
+
+@implementation NSObjectDerivedClass
+
+- (instancetype)init {
+ return [super self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [super init];
+}
+
+- (instancetype)initWithObject:(NSObject *)obj {
+ self = [super self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: self = [super init];
+ if (self) {
+ // ...
+ }
+ return self;
+}
+
+#define INITIALIZE() [super self]
+
+- (instancetype)initWithObject:(NSObject *)objc a:(int)a {
+ return INITIALIZE();
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return INITIALIZE();
+}
+
+#define INITIALIZER_IMPL() return [super self]
+
+- (instancetype)initWithObject:(NSObject *)objc b:(int)b {
+ INITIALIZER_IMPL();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: INITIALIZER_IMPL();
+}
+
+#define INITIALIZER_METHOD self
+
+- (instancetype)initWithObject:(NSObject *)objc c:(int)c {
+ return [super INITIALIZER_METHOD];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [super INITIALIZER_METHOD];
+}
+
+#define RECEIVER super
+
+- (instancetype)initWithObject:(NSObject *)objc d:(int)d {
+ return [RECEIVER self];
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious invocation of 'self' in initializer; did you mean to invoke a superclass initializer? [objc-super-self]
+// CHECK-FIXES: return [RECEIVER self];
+}
+
+- (instancetype)foo {
+ return [super self];
+}
+
+- (instancetype)bar {
+ return [self self];
+}
+
+@end
+
+@interface RootClass
+- (instancetype)init;
+- (instancetype)self;
+@end
+
+@interface NotNSObjectDerivedClass : RootClass
+@end
+
+@implementation NotNSObjectDerivedClass
+
+- (instancetype)init {
+ return [super self];
+}
+
+@end
+