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 | |
16 | struct Foo { |
17 | __unsafe_unretained id Field1; |
18 | id Field2; |
19 | int IntField; |
20 | }; |
21 | |
22 | void 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)(void); |
33 | // CHECK-FIXES: __unsafe_unretained void (^BlockArg1)(void); |
34 | __unsafe_unretained void (^BlockArg2)(void); |
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 | |
66 | void 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 | |
99 | void 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 | |