1// RUN: %clang_cc1 -fsyntax-only -Wself-assign -verify %s
2
3void f() {
4  int a = 42, b = 42;
5  a = a; // expected-warning{{explicitly assigning}}
6  b = b; // expected-warning{{explicitly assigning}}
7  a = b;
8  b = a = b;
9  a = a = a; // expected-warning{{explicitly assigning}}
10  a = b = b = a;
11}
12
13// Dummy type.
14struct S {};
15
16void false_positives() {
17#define OP =
18#define LHS a
19#define RHS a
20  int a = 42;
21  // These shouldn't warn due to the use of the preprocessor.
22  a OP a;
23  LHS = a;
24  a = RHS;
25  LHS OP RHS;
26#undef OP
27#undef LHS
28#undef RHS
29
30  S s;
31  s = s; // Not a builtin assignment operator, no warning.
32
33  // Volatile stores aren't side-effect free.
34  volatile int vol_a;
35  vol_a = vol_a;
36  volatile int &vol_a_ref = vol_a;
37  vol_a_ref = vol_a_ref;
38}
39
40template <typename T> void g() {
41  T a;
42  a = a; // May or may not be a builtin assignment operator, no warning.
43}
44void instantiate() {
45  g<int>();
46  g<S>();
47}
48