summaryrefslogtreecommitdiffstats
path: root/test/SemaObjC/unused.m
blob: f31e4709f534bb33a7c6014ea05fd59d62746f2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// RUN: %clang_cc1 -verify -Wused-but-marked-unused -Wno-objc-protocol-method-implementation -Wunused -Wunused-parameter -fsyntax-only -Wno-objc-root-class %s

int printf(const char *, ...);

@interface Greeter
+ (void) hello;
@end

@implementation Greeter
+ (void) hello { printf("Hello, World!\n"); }
@end

int test1(void) {
  [Greeter hello];
  return 0;
}

@interface NSObject @end
@interface NSString : NSObject 
- (int)length;
@end

void test2() {
  @"pointless example call for test purposes".length; // expected-warning {{property access result unused - getters should not be used for side effects}}
}

@interface foo
- (int)meth: (int)x : (int)y : (int)z ;
@end

@implementation foo
- (int) meth: (int)x: // expected-warning {{'x' used as the name of the previous parameter rather than as part of the selector}} \
                      // expected-note {{introduce a parameter name to make 'x' part of the selector}} \
                      // expected-note {{or insert whitespace before ':' to use 'x' as parameter name and have an empty entry in the selector}}

(int)y:  // expected-warning {{unused}}  expected-warning {{'y' used as the name of the previous parameter rather than as part of the selector}} \
         // expected-note {{introduce a parameter name to make 'y' part of the selector}} \
         // expected-note {{or insert whitespace before ':' to use 'y' as parameter name and have an empty entry in the selector}}
(int) __attribute__((unused))z { return x; }
@end

//===------------------------------------------------------------------------===
// The next test shows how clang accepted attribute((unused)) on ObjC
// instance variables, which GCC does not.
//===------------------------------------------------------------------------===

#if __has_feature(attribute_objc_ivar_unused)
#define UNUSED_IVAR __attribute__((unused))
#else
#error __attribute__((unused)) not supported on ivars
#endif

@interface TestUnusedIvar {
  id y __attribute__((unused)); // no-warning
  id x UNUSED_IVAR; // no-warning
}
@end

// rdar://10777111
static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}}

// rdar://12233989
@interface TestTransitiveUnused
- (void) a __attribute__((unused));
- (void) b __attribute__((unused));
@end

@interface TestTransitiveUnused(CAT)
@end

@implementation TestTransitiveUnused(CAT)
- (void) b {}
- (void) a { [self b]; }
@end

// Test that objc_precise_lifetime suppresses
// unused variable warnings.
extern void rdar15596883_foo(void);
void rdar15596883(id x) {
  __attribute__((objc_precise_lifetime)) id y = x; // no-warning
  rdar15596883_foo();
}

@interface PropertyObject : NSObject 
@property int length;
@end

@protocol P
@property int property;
@end

void test3(PropertyObject *o)
{
  [o length]; // No warning. property name used in direct method call.
}

void test4(id o)
{
  [o length]; // No warning.
}

void test5(id <P> p)
{
    [p property]; // No warning. property name used in direct method call.
}

// rdar://19773512
@interface Model
@property (nonatomic, retain, setter=setOrCreateGroup:, getter=getOrCreateGroup) id group;
@end

@implementation Model {
    id _group;
}
- (void)method {
    [self getOrCreateGroup];
    self.getOrCreateGroup; // expected-warning {{property access result unused - getters should not be used for side effects}}
    self.group; // expected-warning {{property access result unused - getters should not be used for side effects}}
    self.group = (void*)0;
    [self setOrCreateGroup : ((void*)0)];
    
}
- (id)getOrCreateGroup {
    if (!_group) {
        _group = @"group";
    }
    return _group;
}
@end