1// RUN: %clang_cc1 -fsyntax-only -Wparentheses -verify %s
2
3struct A {
4  int foo();
5  friend A operator+(const A&, const A&);
6  A operator|=(const A&);
7  operator bool();
8};
9
10void 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
125void (*fn)();
126
127void 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
134namespace rdar9027658 {
135template <typename T>
136void 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
142struct S { int g; };
143void test() {
144  f(S()); // expected-note {{in instantiation}}
145}
146}
147