xref: /llvm-project/clang/test/SemaObjC/unused.m (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
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
3int 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
13int test1(void) {
14  [Greeter hello];
15  return 0;
16}
17
18@interface NSObject @end
19@interface NSString : NSObject
20- (int)length;
21@end
22
23void test2(void) {
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 {{'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
59static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}}
60
61@interface TestTransitiveUnused
62- (void) a __attribute__((unused));
63- (void) b __attribute__((unused));
64@end
65
66@interface TestTransitiveUnused(CAT)
67@end
68
69@implementation TestTransitiveUnused(CAT)
70- (void) b {}
71- (void) a { [self b]; }
72@end
73
74// Test that objc_precise_lifetime suppresses
75// unused variable warnings.
76extern void rdar15596883_foo(void);
77void rdar15596883(id x) {
78  __attribute__((objc_precise_lifetime)) id y = x; // no-warning
79  rdar15596883_foo();
80}
81
82@interface PropertyObject : NSObject
83@property int length;
84@end
85
86@protocol P
87@property int property;
88@end
89
90void test3(PropertyObject *o)
91{
92  [o length]; // No warning. property name used in direct method call.
93}
94
95void test4(id o)
96{
97  [o length]; // No warning.
98}
99
100void test5(id <P> p)
101{
102    [p property]; // No warning. property name used in direct method call.
103}
104
105@interface Model
106@property (nonatomic, retain, setter=setOrCreateGroup:, getter=getOrCreateGroup) id group;
107@end
108
109@implementation Model {
110    id _group;
111}
112- (void)method {
113    [self getOrCreateGroup];
114    self.getOrCreateGroup; // expected-warning {{property access result unused - getters should not be used for side effects}}
115    self.group; // expected-warning {{property access result unused - getters should not be used for side effects}}
116    self.group = (void*)0;
117    [self setOrCreateGroup : ((void*)0)];
118
119}
120- (id)getOrCreateGroup {
121    if (!_group) {
122        _group = @"group";
123    }
124    return _group;
125}
126@end
127
128