1 // RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -Wno-unused -Wunused-comparison %s
2 
3 struct A {
4   bool operator==(const A&);
5   bool operator!=(const A&);
6   bool operator<(const A&);
7   bool operator>(const A&);
8   bool operator<=(const A&);
9   bool operator>=(const A&);
10   A operator|=(const A&);
11   operator bool();
12 };
13 
test()14 void test() {
15   int x, *p;
16   A a, b;
17 
18   x == 7; // expected-warning {{equality comparison result unused}} \
19           // expected-note {{use '=' to turn this equality comparison into an assignment}}
20   x != 7; // expected-warning {{inequality comparison result unused}} \
21           // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
22   x < 7;  // expected-warning {{relational comparison result unused}}
23   x > 7;  // expected-warning {{relational comparison result unused}}
24   x <= 7; // expected-warning {{relational comparison result unused}}
25   x >= 7; // expected-warning {{relational comparison result unused}}
26 
27   7 == x; // expected-warning {{equality comparison result unused}}
28   p == p; // expected-warning {{equality comparison result unused}} \
29           // expected-note {{use '=' to turn this equality comparison into an assignment}} \
30           // expected-warning {{self-comparison always evaluates to true}}
31   a == a; // expected-warning {{equality comparison result unused}} \
32           // expected-note {{use '=' to turn this equality comparison into an assignment}}
33   a == b; // expected-warning {{equality comparison result unused}} \
34           // expected-note {{use '=' to turn this equality comparison into an assignment}}
35   a != b; // expected-warning {{inequality comparison result unused}} \
36           // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
37   a < b;  // expected-warning {{relational comparison result unused}}
38   a > b;  // expected-warning {{relational comparison result unused}}
39   a <= b; // expected-warning {{relational comparison result unused}}
40   a >= b; // expected-warning {{relational comparison result unused}}
41 
42   A() == b; // expected-warning {{equality comparison result unused}}
43   if (42) x == 7; // expected-warning {{equality comparison result unused}} \
44                   // expected-note {{use '=' to turn this equality comparison into an assignment}}
45   else if (42) x == 7; // expected-warning {{equality comparison result unused}} \
46                        // expected-note {{use '=' to turn this equality comparison into an assignment}}
47   else x == 7; // expected-warning {{equality comparison result unused}} \
48                // expected-note {{use '=' to turn this equality comparison into an assignment}}
49   do x == 7; // expected-warning {{equality comparison result unused}} \
50              // expected-note {{use '=' to turn this equality comparison into an assignment}}
51   while (false);
52   while (false) x == 7; // expected-warning {{equality comparison result unused}} \
53                         // expected-note {{use '=' to turn this equality comparison into an assignment}}
54   for (x == 7; // expected-warning {{equality comparison result unused}} \
55                // expected-note {{use '=' to turn this equality comparison into an assignment}}
56        x == 7; // No warning -- result is used
57        x == 7) // expected-warning {{equality comparison result unused}} \
58                // expected-note {{use '=' to turn this equality comparison into an assignment}}
59     x == 7; // expected-warning {{equality comparison result unused}} \
60             // expected-note {{use '=' to turn this equality comparison into an assignment}}
61   switch (42) default: x == 7; // expected-warning {{equality comparison result unused}} \
62                                // expected-note {{use '=' to turn this equality comparison into an assignment}}
63   switch (42) case 42: x == 7; // expected-warning {{equality comparison result unused}} \
64                                // expected-note {{use '=' to turn this equality comparison into an assignment}}
65   switch (42) {
66     case 1:
67     case 2:
68     default:
69     case 3:
70     case 4:
71       x == 7; // expected-warning {{equality comparison result unused}} \
72               // expected-note {{use '=' to turn this equality comparison into an assignment}}
73   }
74 
75   (void)(x == 7);
76   (void)(p == p); // expected-warning {{self-comparison always evaluates to true}}
77   { bool b = x == 7; }
78 
79   { bool b = ({ x == 7; // expected-warning {{equality comparison result unused}} \
80                         // expected-note {{use '=' to turn this equality comparison into an assignment}}
81                 x == 7; }); } // no warning on the second, its result is used!
82 
83 #define EQ(x,y) (x) == (y)
84   EQ(x, 5);
85 #undef EQ
86 
87   (void)sizeof(1 < 2, true); // No warning; unevaluated context.
88 }
89 
90 namespace PR10291 {
91   template<typename T>
92   class X
93   {
94   public:
95 
X()96     X() : i(0) { }
97 
foo()98     void foo()
99     {
100       throw
101         i == 0u ?
102         5 : 6;
103     }
104 
105   private:
106     int i;
107   };
108 
109   X<int> x;
110 }
111 
112 namespace PR19724 {
113 class stream {
114 } cout, cin;
115 
116 stream &operator<(stream &s, int);
117 bool operator<(stream &s, stream &s2);
118 
test()119 void test() {
120   cout < 5;    // no warning, operator returns a reference
121   cout < cin;  // expected-warning {{relational comparison result unused}}
122 }
123 }
124 
125 namespace PR19791 {
126 struct S {
127   void operator!=(int);
128   int operator==(int);
129 };
130 
test()131 void test() {
132   S s;
133   s != 1;
134   s == 1;  // expected-warning{{equality comparison result unused}}
135            // expected-note@-1{{use '=' to turn this equality comparison into an assignment}}
136 }
137 }
138