1*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=((id)0)" -verify %s 2*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=(id)0" -verify %s 3*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=0" -verify %s 4*67e74705SXin Li 5*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -fobjc-arc "-Dnil=((id)0)" -verify %s 6*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -fobjc-arc "-Dnil=(id)0" -verify %s 7*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -fobjc-arc "-Dnil=0" -verify %s 8*67e74705SXin Li 9*67e74705SXin Li// (test the warning flag as well) 10*67e74705SXin Li 11*67e74705SXin Litypedef signed char BOOL; 12*67e74705SXin Li 13*67e74705SXin Li@interface BaseObject 14*67e74705SXin Li+ (instancetype)new; 15*67e74705SXin Li@end 16*67e74705SXin Li 17*67e74705SXin Li@interface NSObject : BaseObject 18*67e74705SXin Li- (BOOL)isEqual:(id)other; 19*67e74705SXin Li@end 20*67e74705SXin Li 21*67e74705SXin Li@interface NSNumber : NSObject 22*67e74705SXin Li+ (NSNumber *)numberWithInt:(int)value; 23*67e74705SXin Li+ (NSNumber *)numberWithDouble:(double)value; 24*67e74705SXin Li+ (NSNumber *)numberWithBool:(BOOL)value; 25*67e74705SXin Li@end 26*67e74705SXin Li 27*67e74705SXin Li@interface NSArray : NSObject 28*67e74705SXin Li+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; 29*67e74705SXin Li@end 30*67e74705SXin Li 31*67e74705SXin Li@interface NSDictionary : NSObject 32*67e74705SXin Li+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; 33*67e74705SXin Li@end 34*67e74705SXin Li 35*67e74705SXin Li@interface NSString : NSObject 36*67e74705SXin Li@end 37*67e74705SXin Li 38*67e74705SXin Livoid testComparisonsWithFixits(id obj) { 39*67e74705SXin Li if (obj == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 40*67e74705SXin Li if (obj != @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 41*67e74705SXin Li if (@"" == obj) return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 42*67e74705SXin Li if (@"" == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 43*67e74705SXin Li 44*67e74705SXin Li if (@[] == obj) return; // expected-warning{{direct comparison of an array literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 45*67e74705SXin Li if (@{} == obj) return; // expected-warning{{direct comparison of a dictionary literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 46*67e74705SXin Li if (@12 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 47*67e74705SXin Li if (@1.0 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 48*67e74705SXin Li if (@__objc_yes == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 49*67e74705SXin Li if (@(1+1) == obj) return; // expected-warning{{direct comparison of a boxed expression has undefined behavior}} expected-note{{use 'isEqual:' instead}} 50*67e74705SXin Li} 51*67e74705SXin Li 52*67e74705SXin Li 53*67e74705SXin Li@interface BadEqualReturnString : NSString 54*67e74705SXin Li- (void)isEqual:(id)other; 55*67e74705SXin Li@end 56*67e74705SXin Li 57*67e74705SXin Li@interface BadEqualArgString : NSString 58*67e74705SXin Li- (BOOL)isEqual:(int)other; 59*67e74705SXin Li@end 60*67e74705SXin Li 61*67e74705SXin Li 62*67e74705SXin Livoid testComparisonsWithoutFixits() { 63*67e74705SXin Li if ([BaseObject new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 64*67e74705SXin Li 65*67e74705SXin Li if ([BadEqualReturnString new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 66*67e74705SXin Li if ([BadEqualArgString new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 67*67e74705SXin Li 68*67e74705SXin Li if (@"" < @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 69*67e74705SXin Li if (@"" > @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 70*67e74705SXin Li if (@"" <= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 71*67e74705SXin Li if (@"" >= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} 72*67e74705SXin Li} 73*67e74705SXin Li 74*67e74705SXin Li 75*67e74705SXin Li#pragma clang diagnostic push 76*67e74705SXin Li#pragma clang diagnostic ignored "-Wobjc-string-compare" 77*67e74705SXin Li 78*67e74705SXin Livoid testWarningFlags(id obj) { 79*67e74705SXin Li if (obj == @"") return; // no-warning 80*67e74705SXin Li if (@"" == obj) return; // no-warning 81*67e74705SXin Li 82*67e74705SXin Li if (obj == @1) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 83*67e74705SXin Li if (@1 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}} 84*67e74705SXin Li} 85*67e74705SXin Li 86*67e74705SXin Li#pragma clang diagnostic pop 87*67e74705SXin Li 88*67e74705SXin Li 89*67e74705SXin Livoid testNilComparison() { 90*67e74705SXin Li // Don't warn when comparing to nil in a macro. 91*67e74705SXin Li#define RETURN_IF_NIL(x) if (x == nil || nil == x) return 92*67e74705SXin Li RETURN_IF_NIL(@""); 93*67e74705SXin Li RETURN_IF_NIL(@1); 94*67e74705SXin Li RETURN_IF_NIL(@1.0); 95*67e74705SXin Li RETURN_IF_NIL(@[]); 96*67e74705SXin Li RETURN_IF_NIL(@{}); 97*67e74705SXin Li RETURN_IF_NIL(@__objc_yes); 98*67e74705SXin Li RETURN_IF_NIL(@(1+1)); 99*67e74705SXin Li} 100*67e74705SXin Li 101*67e74705SXin Livoid PR15257(Class c) { 102*67e74705SXin Li return c == @""; // expected-warning{{direct comparison of a string literal has undefined behavior}} 103*67e74705SXin Li} 104