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