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