xref: /aosp_15_r20/external/clang/test/SemaObjC/objc-literal-comparison.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
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