1 | // RUN: %clang_cc1 -verify -Wused-but-marked-unused -Wno-objc-protocol-method-implementation -Wunused -Wunused-parameter -fsyntax-only -Wno-objc-root-class %s |
2 | |
3 | int printf(const char *, ...); |
4 | |
5 | @interface Greeter |
6 | + (void) hello; |
7 | @end |
8 | |
9 | @implementation Greeter |
10 | + (void) hello { printf("Hello, World!\n"); } |
11 | @end |
12 | |
13 | int test1(void) { |
14 | [Greeter hello]; |
15 | return 0; |
16 | } |
17 | |
18 | @interface NSObject @end |
19 | @interface NSString : NSObject |
20 | - (int)length; |
21 | @end |
22 | |
23 | void test2() { |
24 | @"pointless example call for test purposes".length; // expected-warning {{property access result unused - getters should not be used for side effects}} |
25 | } |
26 | |
27 | @interface foo |
28 | - (int)meth: (int)x : (int)y : (int)z ; |
29 | @end |
30 | |
31 | @implementation foo |
32 | - (int) meth: (int)x: // expected-warning {{'x' used as the name of the previous parameter rather than as part of the selector}} \ |
33 | // expected-note {{introduce a parameter name to make 'x' part of the selector}} \ |
34 | // expected-note {{or insert whitespace before ':' to use 'x' as parameter name and have an empty entry in the selector}} |
35 | |
36 | (int)y: // expected-warning {{unused}} expected-warning {{'y' used as the name of the previous parameter rather than as part of the selector}} \ |
37 | // expected-note {{introduce a parameter name to make 'y' part of the selector}} \ |
38 | // expected-note {{or insert whitespace before ':' to use 'y' as parameter name and have an empty entry in the selector}} |
39 | (int) __attribute__((unused))z { return x; } |
40 | @end |
41 | |
42 | //===------------------------------------------------------------------------=== |
43 | // The next test shows how clang accepted attribute((unused)) on ObjC |
44 | // instance variables, which GCC does not. |
45 | //===------------------------------------------------------------------------=== |
46 | |
47 | #if __has_feature(attribute_objc_ivar_unused) |
48 | #define UNUSED_IVAR __attribute__((unused)) |
49 | #else |
50 | #error __attribute__((unused)) not supported on ivars |
51 | #endif |
52 | |
53 | @interface TestUnusedIvar { |
54 | id y __attribute__((unused)); // no-warning |
55 | id x UNUSED_IVAR; // no-warning |
56 | } |
57 | @end |
58 | |
59 | // rdar://10777111 |
60 | static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}} |
61 | |
62 | // rdar://12233989 |
63 | @interface TestTransitiveUnused |
64 | - (void) a __attribute__((unused)); |
65 | - (void) b __attribute__((unused)); |
66 | @end |
67 | |
68 | @interface TestTransitiveUnused(CAT) |
69 | @end |
70 | |
71 | @implementation TestTransitiveUnused(CAT) |
72 | - (void) b {} |
73 | - (void) a { [self b]; } |
74 | @end |
75 | |
76 | // Test that objc_precise_lifetime suppresses |
77 | // unused variable warnings. |
78 | extern void rdar15596883_foo(void); |
79 | void rdar15596883(id x) { |
80 | __attribute__((objc_precise_lifetime)) id y = x; // no-warning |
81 | rdar15596883_foo(); |
82 | } |
83 | |
84 | @interface PropertyObject : NSObject |
85 | @property int length; |
86 | @end |
87 | |
88 | @protocol P |
89 | @property int property; |
90 | @end |
91 | |
92 | void test3(PropertyObject *o) |
93 | { |
94 | [o length]; // No warning. property name used in direct method call. |
95 | } |
96 | |
97 | void test4(id o) |
98 | { |
99 | [o length]; // No warning. |
100 | } |
101 | |
102 | void test5(id <P> p) |
103 | { |
104 | [p property]; // No warning. property name used in direct method call. |
105 | } |
106 | |
107 | // rdar://19773512 |
108 | @interface Model |
109 | @property (nonatomic, retain, setter=setOrCreateGroup:, getter=getOrCreateGroup) id group; |
110 | @end |
111 | |
112 | @implementation Model { |
113 | id _group; |
114 | } |
115 | - (void)method { |
116 | [self getOrCreateGroup]; |
117 | self.getOrCreateGroup; // expected-warning {{property access result unused - getters should not be used for side effects}} |
118 | self.group; // expected-warning {{property access result unused - getters should not be used for side effects}} |
119 | self.group = (void*)0; |
120 | [self setOrCreateGroup : ((void*)0)]; |
121 | |
122 | } |
123 | - (id)getOrCreateGroup { |
124 | if (!_group) { |
125 | _group = @"group"; |
126 | } |
127 | return _group; |
128 | } |
129 | @end |
130 | |
131 | |