1 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -verify %s 2 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 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 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> 60 void g() { 61 T a; 62 a = a; // expected-warning{{explicitly assigning}} 63 } 64 void instantiate() { 65 g<int>(); 66 g<S>(); 67 } 68 69 struct Foo { 70 int A; 71 72 Foo(int A) : A(A) {} 73 74 void setA(int A) { 75 A = A; // expected-warning{{explicitly assigning value of variable of type 'int' to itself; did you mean to assign to member 'A'?}} 76 } 77 78 void setThroughLambda() { 79 [](int A) { 80 // To fix here we would need to insert an explicit capture 'this' 81 A = A; // expected-warning{{explicitly assigning}} 82 }(5); 83 84 [this](int A) { 85 this->A = 0; 86 // This fix would be possible by just adding this-> as above, but currently unsupported. 87 A = A; // expected-warning{{explicitly assigning}} 88 }(5); 89 } 90 }; 91