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 
12   a *= a;
13   a /= a;
14   a %= a;
15   a += a;
16   a -= a;
17   a <<= a;
18   a >>= a;
19   a &= a; // expected-warning {{explicitly assigning}}
20   a |= a; // expected-warning {{explicitly assigning}}
21   a ^= a;
22 }
23 
24 // Dummy type.
25 struct S {};
26 
false_positives()27 void false_positives() {
28 #define OP =
29 #define LHS a
30 #define RHS a
31   int a = 42;
32   // These shouldn't warn due to the use of the preprocessor.
33   a OP a;
34   LHS = a;
35   a = RHS;
36   LHS OP RHS;
37 #undef OP
38 #undef LHS
39 #undef RHS
40 
41   // A way to silence the warning.
42   a = (int &)a;
43 
44   // Volatile stores aren't side-effect free.
45   volatile int vol_a;
46   vol_a = vol_a;
47   volatile int &vol_a_ref = vol_a;
48   vol_a_ref = vol_a_ref;
49 }
50 
51 // Do not diagnose self-assigment in an unevaluated context
false_positives_unevaluated_ctx(int a)52 void false_positives_unevaluated_ctx(int a) noexcept(noexcept(a = a)) // expected-warning {{expression with side effects has no effect in an unevaluated context}}
53 {
54   decltype(a = a) b = a;              // expected-warning {{expression with side effects has no effect in an unevaluated context}}
55   static_assert(noexcept(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
56   static_assert(sizeof(a = a), "");   // expected-warning {{expression with side effects has no effect in an unevaluated context}}
57 }
58 
59 template <typename T>
g()60 void g() {
61   T a;
62   a = a; // expected-warning{{explicitly assigning}}
63 }
instantiate()64 void instantiate() {
65   g<int>();
66   g<S>();
67 }
68