1// RUN: %check_clang_tidy %s objc-nsinvocation-argument-lifetime %t 2 3__attribute__((objc_root_class)) 4@interface NSObject 5@end 6 7@interface NSInvocation : NSObject 8- (void)getArgument:(void *)Arg atIndex:(int)Index; 9- (void)getReturnValue:(void *)ReturnValue; 10@end 11 12@interface OtherClass : NSObject 13- (void)getArgument:(void *)Arg atIndex:(int)Index; 14@end 15 16struct Foo { 17 __unsafe_unretained id Field1; 18 id Field2; 19 int IntField; 20}; 21 22void foo(NSInvocation *Invocation) { 23 __unsafe_unretained id Arg2; 24 id Arg3; 25 // CHECK-FIXES: __unsafe_unretained id Arg3; 26 NSObject __strong *Arg4; 27 // CHECK-FIXES: NSObject __unsafe_unretained *Arg4; 28 __weak id Arg5; 29 // CHECK-FIXES: __unsafe_unretained id Arg5; 30 id ReturnValue; 31 // CHECK-FIXES: __unsafe_unretained id ReturnValue; 32 void (^BlockArg1)(); 33 // CHECK-FIXES: __unsafe_unretained void (^BlockArg1)(); 34 __unsafe_unretained void (^BlockArg2)(); 35 int IntVar; 36 struct Foo Bar; 37 38 [Invocation getArgument:&Arg2 atIndex:2]; 39 [Invocation getArgument:&IntVar atIndex:2]; 40 41 [Invocation getArgument:&Arg3 atIndex:3]; 42 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 43 44 [Invocation getArgument:&Arg4 atIndex:4]; 45 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 46 47 [Invocation getArgument:&Arg5 atIndex:5]; 48 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 49 50 [Invocation getArgument:&BlockArg1 atIndex:6]; 51 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 52 53 [Invocation getArgument:&BlockArg2 atIndex:6]; 54 55 [Invocation getReturnValue:&ReturnValue]; 56 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: NSInvocation '-getReturnValue:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 57 58 [Invocation getArgument:(void *)0 atIndex:6]; 59 60 [Invocation getArgument:&Bar.Field1 atIndex:2]; 61 [Invocation getArgument:&Bar.Field2 atIndex:2]; 62 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 63 [Invocation getArgument:&Bar.IntField atIndex:2]; 64} 65 66void bar(OtherClass *OC) { 67 id Arg; 68 [OC getArgument:&Arg atIndex:2]; 69} 70 71@interface TestClass : NSObject { 72@public 73 id Argument1; 74 __unsafe_unretained id Argument2; 75 struct Foo Bar; 76 int IntIvar; 77} 78@end 79 80@implementation TestClass 81 82- (void)processInvocation:(NSInvocation *)Invocation { 83 [Invocation getArgument:&Argument1 atIndex:2]; 84 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 85 [Invocation getArgument:&self->Argument1 atIndex:2]; 86 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 87 [Invocation getArgument:&Argument2 atIndex:2]; 88 [Invocation getArgument:&self->Argument2 atIndex:2]; 89 [Invocation getArgument:&self->IntIvar atIndex:2]; 90 91 [Invocation getReturnValue:&(self->Bar.Field1)]; 92 [Invocation getReturnValue:&(self->Bar.Field2)]; 93 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: NSInvocation '-getReturnValue:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 94 [Invocation getReturnValue:&(self->Bar.IntField)]; 95} 96 97@end 98 99void baz(NSInvocation *Invocation, TestClass *Obj) { 100 [Invocation getArgument:&Obj->Argument1 atIndex:2]; 101 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: NSInvocation '-getArgument:atIndex:' should only pass pointers to objects with ownership __unsafe_unretained [objc-nsinvocation-argument-lifetime] 102 [Invocation getArgument:&Obj->Argument2 atIndex:2]; 103} 104