1 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++2a 2 3 int foo(int x) { 4 return x == x; // expected-warning {{self-comparison always evaluates to true}} 5 } 6 7 struct X { 8 bool operator==(const X &x) const; 9 }; 10 11 struct A { 12 int x; 13 X x2; 14 int a[3]; 15 int b[3]; 16 bool f() { return x == x; } // expected-warning {{self-comparison always evaluates to true}} 17 bool g() { return x2 == x2; } // no-warning 18 bool h() { return a == b; } // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}} 19 bool i() { 20 int c[3]; 21 return a == c; // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}} 22 } 23 }; 24 25 namespace NA { extern "C" int x[3]; } 26 namespace NB { extern "C" int x[3]; } 27 bool k = NA::x == NB::x; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}} 28 29 template<typename T> struct Y { static inline int n; }; 30 bool f() { 31 return 32 Y<int>::n == Y<int>::n || // expected-warning {{self-comparison always evaluates to true}} 33 Y<void>::n == Y<int>::n; 34 } 35 template<typename T, typename U> 36 bool g() { 37 // FIXME: Ideally we'd produce a self-comparison warning on the first of these. 38 return 39 Y<T>::n == Y<T>::n || 40 Y<T>::n == Y<U>::n; 41 } 42 template bool g<int, int>(); // should not produce any warnings 43 44 namespace member_tests { 45 struct B { 46 int field; 47 static int static_field; 48 int test(B b) { 49 return field == field; // expected-warning {{self-comparison always evaluates to true}} 50 return static_field == static_field; // expected-warning {{self-comparison always evaluates to true}} 51 return static_field == b.static_field; // expected-warning {{self-comparison always evaluates to true}} 52 return B::static_field == this->static_field; // expected-warning {{self-comparison always evaluates to true}} 53 return this == this; // expected-warning {{self-comparison always evaluates to true}} 54 55 return field == b.field; 56 return this->field == b.field; 57 } 58 }; 59 60 enum { 61 I0, 62 I1, 63 I2, 64 }; 65 66 struct S { 67 int field; 68 static int static_field; 69 int array[4]; 70 }; 71 72 struct T { 73 int field; 74 static int static_field; 75 int array[4]; 76 S s; 77 }; 78 79 int struct_test(S s1, S s2, S *s3, T t) { 80 return s1.field == s1.field; // expected-warning {{self-comparison always evaluates to true}} 81 return s2.field == s2.field; // expected-warning {{self-comparison always evaluates to true}} 82 return s1.static_field == s2.static_field; // expected-warning {{self-comparison always evaluates to true}} 83 return S::static_field == s1.static_field; // expected-warning {{self-comparison always evaluates to true}} 84 return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}} 85 return t.s.static_field == S::static_field; // expected-warning {{self-comparison always evaluates to true}} 86 return s3->field == s3->field; // expected-warning {{self-comparison always evaluates to true}} 87 return s3->static_field == S::static_field; // expected-warning {{self-comparison always evaluates to true}} 88 return s1.array[0] == s1.array[0]; // expected-warning {{self-comparison always evaluates to true}} 89 return s1.array[0] == s1.array[0ull]; // expected-warning {{self-comparison always evaluates to true}} 90 return s1.array[I1] == s1.array[I1]; // expected-warning {{self-comparison always evaluates to true}} 91 return s1.array[s2.array[0]] == s1.array[s2.array[0]]; // expected-warning {{self-comparison always evaluates to true}} 92 return s3->array[t.field] == s3->array[t.field]; // expected-warning {{self-comparison always evaluates to true}} 93 94 // Try all operators 95 return t.field == t.field; // expected-warning {{self-comparison always evaluates to true}} 96 return t.field <= t.field; // expected-warning {{self-comparison always evaluates to true}} 97 return t.field >= t.field; // expected-warning {{self-comparison always evaluates to true}} 98 99 return t.field != t.field; // expected-warning {{self-comparison always evaluates to false}} 100 return t.field < t.field; // expected-warning {{self-comparison always evaluates to false}} 101 return t.field > t.field; // expected-warning {{self-comparison always evaluates to false}} 102 103 // no warning 104 return s1.field == s2.field; 105 return s2.array == s1.array; // FIXME: This always evaluates to false. expected-warning {{deprecated}} 106 return s2.array[0] == s1.array[0]; 107 return s1.array[I1] == s1.array[I2]; 108 109 return s1.static_field == t.static_field; 110 }; 111 112 struct U { 113 bool operator!=(const U&); 114 }; 115 116 bool operator==(const U&, const U&); 117 118 // May want to warn on this in the future. 119 int user_defined(U u) { 120 return u == u; 121 return u != u; 122 } 123 124 } // namespace member_tests 125