1 // RUN: %clang_cc1 -fsyntax-only -Wparentheses -verify %s
2 
3 struct A {
4   int foo();
5   friend A operator+(const A&, const A&);
6   A operator|=(const A&);
7   operator bool();
8 };
9 
test()10 void test() {
11   int x, *p;
12   A a, b;
13 
14   // With scalars.
15   if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
16                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
17   // expected-note{{place parentheses around the assignment to silence this warning}}
18   if ((x = 7)) {}
19   do {
20   } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
21                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
22   // expected-note{{place parentheses around the assignment to silence this warning}}
23   do {
24   } while ((x = 7));
25   while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
26                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
27   // expected-note{{place parentheses around the assignment to silence this warning}}
28 
29   while ((x = 7)) {}
30   for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
31                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
32   // expected-note{{place parentheses around the assignment to silence this warning}}
33   for (; (x = 7); ) {}
34 
35   if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
36                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
37   // expected-note{{place parentheses around the assignment to silence this warning}}
38   if ((p = p)) {}
39   do {
40   } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
41                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
42   // expected-note{{place parentheses around the assignment to silence this warning}}
43   do {
44   } while ((p = p));
45   while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
46                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
47   // expected-note{{place parentheses around the assignment to silence this warning}}
48   while ((p = p)) {}
49   for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
50                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
51   // expected-note{{place parentheses around the assignment to silence this warning}}
52   for (; (p = p); ) {}
53 
54   // Initializing variables (shouldn't warn).
55   if (int y = x) {}
56   while (int y = x) {}
57   if (A y = a) {}
58   while (A y = a) {}
59 
60   // With temporaries.
61   if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
62                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
63   // expected-note{{place parentheses around the assignment to silence this warning}}
64   if ((x = (b+b).foo())) {}
65   do {
66   } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
67                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
68   // expected-note{{place parentheses around the assignment to silence this warning}}
69   do {
70   } while ((x = (b+b).foo()));
71   while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
72                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
73   // expected-note{{place parentheses around the assignment to silence this warning}}
74   while ((x = (b+b).foo())) {}
75   for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
76                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
77   // expected-note{{place parentheses around the assignment to silence this warning}}
78   for (; (x = (b+b).foo()); ) {}
79 
80   // With a user-defined operator.
81   if (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
82                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
83   // expected-note{{place parentheses around the assignment to silence this warning}}
84   if ((a = b + b)) {}
85   do {
86   } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
87                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
88   // expected-note{{place parentheses around the assignment to silence this warning}}
89   do {
90   } while ((a = b + b));
91   while (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
92                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
93   // expected-note{{place parentheses around the assignment to silence this warning}}
94   while ((a = b + b)) {}
95   for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
96                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
97   // expected-note{{place parentheses around the assignment to silence this warning}}
98   for (; (a = b + b); ) {}
99 
100   // Compound assignments.
101   if (x |= 2) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
102                 // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
103   // expected-note{{place parentheses around the assignment to silence this warning}}
104 
105   if (a |= b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
106                 // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
107   // expected-note{{place parentheses around the assignment to silence this warning}}
108 
109   if ((x == 5)) {} // expected-warning {{equality comparison with extraneous parentheses}} \
110                    // expected-note {{use '=' to turn this equality comparison into an assignment}} \
111                    // expected-note {{remove extraneous parentheses around the comparison to silence this warning}}
112 
113 #pragma clang diagnostic push
114 #pragma clang diagnostic ignored "-Wparentheses-equality"
115   if ((x == 5)) {} // no-warning
116 #pragma clang diagnostic pop
117 
118   if ((5 == x)) {}
119 
120 #define EQ(x,y) ((x) == (y))
121   if (EQ(x, 5)) {}
122 #undef EQ
123 }
124 
125 void (*fn)();
126 
test2()127 void test2() {
128     if ((fn == test2)) {} // expected-warning {{equality comparison with extraneous parentheses}} \
129                           // expected-note {{use '=' to turn this equality comparison into an assignment}} \
130                           // expected-note {{remove extraneous parentheses around the comparison to silence this warning}}
131     if ((test2 == fn)) {}
132 }
133 
134 namespace rdar9027658 {
135 template <typename T>
f(T t)136 void f(T t) {
137     if ((t.g == 3)) { } // expected-warning {{equality comparison with extraneous parentheses}} \
138                          // expected-note {{use '=' to turn this equality comparison into an assignment}} \
139                          // expected-note {{remove extraneous parentheses around the comparison to silence this warning}}
140 }
141 
142 struct S { int g; };
test()143 void test() {
144   f(S()); // expected-note {{in instantiation}}
145 }
146 }
147