reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
// RUN: %clang_cc1 -fsyntax-only -Wparentheses -verify %s

struct A {
  int foo();
  friend A operator+(const A&, const A&);
  A operator|=(const A&);
  operator bool();
};

void test() {
  int x, *p;
  A a, b;

  // With scalars.
  if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  if ((x = 7)) {}
  do {
  } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  do {
  } while ((x = 7));
  while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}

  while ((x = 7)) {}
  for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  for (; (x = 7); ) {}

  if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  if ((p = p)) {}
  do {
  } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  do {
  } while ((p = p));
  while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  while ((p = p)) {}
  for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  for (; (p = p); ) {}

  // Initializing variables (shouldn't warn).
  if (int y = x) {}
  while (int y = x) {}
  if (A y = a) {}
  while (A y = a) {}

  // With temporaries.
  if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  if ((x = (b+b).foo())) {}
  do {
  } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  do {
  } while ((x = (b+b).foo()));
  while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  while ((x = (b+b).foo())) {}
  for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  for (; (x = (b+b).foo()); ) {}

  // With a user-defined operator.
  if (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  if ((a = b + b)) {}
  do {
  } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  do {
  } while ((a = b + b));
  while (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  while ((a = b + b)) {}
  for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '==' to turn this assignment into an equality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}
  for (; (a = b + b); ) {}

  // Compound assignments.
  if (x |= 2) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}

  if (a |= b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
                // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
  // expected-note{{place parentheses around the assignment to silence this warning}}

  if ((x == 5)) {} // expected-warning {{equality comparison with extraneous parentheses}} \
                   // expected-note {{use '=' to turn this equality comparison into an assignment}} \
                   // expected-note {{remove extraneous parentheses around the comparison to silence this warning}}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wparentheses-equality"
  if ((x == 5)) {} // no-warning
#pragma clang diagnostic pop

  if ((5 == x)) {}

#define EQ(x,y) ((x) == (y))
  if (EQ(x, 5)) {}
#undef EQ
}

void (*fn)();

void test2() {
    if ((fn == test2)) {} // expected-warning {{equality comparison with extraneous parentheses}} \
                          // expected-note {{use '=' to turn this equality comparison into an assignment}} \
                          // expected-note {{remove extraneous parentheses around the comparison to silence this warning}}
    if ((test2 == fn)) {}
}

namespace rdar9027658 {
template <typename T>
void f(T t) {
    if ((t.g == 3)) { } // expected-warning {{equality comparison with extraneous parentheses}} \
                         // expected-note {{use '=' to turn this equality comparison into an assignment}} \
                         // expected-note {{remove extraneous parentheses around the comparison to silence this warning}}
}

struct S { int g; };
void test() {
  f(S()); // expected-note {{in instantiation}}
}
}