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() {
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
60static 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.
78extern void rdar15596883_foo(void);
79void 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
92void test3(PropertyObject *o)
93{
94  [o length]; // No warning. property name used in direct method call.
95}
96
97void test4(id o)
98{
99  [o length]; // No warning.
100}
101
102void 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