104 lines · plain
1// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=((id)0)" -verify %s2// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=(id)0" -verify %s3// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=0" -verify %s4 5// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -fobjc-arc "-Dnil=((id)0)" -verify %s6// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -fobjc-arc "-Dnil=(id)0" -verify %s7// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -fobjc-arc "-Dnil=0" -verify %s8 9// (test the warning flag as well)10 11typedef signed char BOOL;12 13@interface BaseObject14+ (instancetype)new;15@end16 17@interface NSObject : BaseObject18- (BOOL)isEqual:(id)other;19@end20 21@interface NSNumber : NSObject22+ (NSNumber *)numberWithInt:(int)value;23+ (NSNumber *)numberWithDouble:(double)value;24+ (NSNumber *)numberWithBool:(BOOL)value;25@end26 27@interface NSArray : NSObject28+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;29@end30 31@interface NSDictionary : NSObject32+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;33@end34 35@interface NSString : NSObject36@end37 38void testComparisonsWithFixits(id obj) {39 if (obj == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}40 if (obj != @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}41 if (@"" == obj) return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}42 if (@"" == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}43 44 if (@[] == obj) return; // expected-warning{{direct comparison of an array literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}45 if (@{} == obj) return; // expected-warning{{direct comparison of a dictionary literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}46 if (@12 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}47 if (@1.0 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}48 if (@__objc_yes == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}49 if (@(1+1) == obj) return; // expected-warning{{direct comparison of a boxed expression has undefined behavior}} expected-note{{use 'isEqual:' instead}}50}51 52 53@interface BadEqualReturnString : NSString54- (void)isEqual:(id)other;55@end56 57@interface BadEqualArgString : NSString58- (BOOL)isEqual:(int)other;59@end60 61 62void testComparisonsWithoutFixits() {63 if ([BaseObject new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}64 65 if ([BadEqualReturnString new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}66 if ([BadEqualArgString new] == @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}67 68 if (@"" < @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}69 if (@"" > @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}70 if (@"" <= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}71 if (@"" >= @"") return; // expected-warning{{direct comparison of a string literal has undefined behavior}}72}73 74 75#pragma clang diagnostic push76#pragma clang diagnostic ignored "-Wobjc-string-compare"77 78void testWarningFlags(id obj) {79 if (obj == @"") return; // no-warning80 if (@"" == obj) return; // no-warning81 82 if (obj == @1) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}83 if (@1 == obj) return; // expected-warning{{direct comparison of a numeric literal has undefined behavior}} expected-note{{use 'isEqual:' instead}}84}85 86#pragma clang diagnostic pop87 88 89void testNilComparison() {90 // Don't warn when comparing to nil in a macro.91#define RETURN_IF_NIL(x) if (x == nil || nil == x) return92 RETURN_IF_NIL(@"");93 RETURN_IF_NIL(@1);94 RETURN_IF_NIL(@1.0);95 RETURN_IF_NIL(@[]);96 RETURN_IF_NIL(@{});97 RETURN_IF_NIL(@__objc_yes);98 RETURN_IF_NIL(@(1+1));99}100 101void PR15257(Class c) {102 return c == @""; // expected-warning{{direct comparison of a string literal has undefined behavior}}103}104