120 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -verify %s2 3struct C {4 int a;5 int b;6 7 C(int a, int b) : a(a), b(b) {}8 9 void f() {10 a = a; // expected-warning {{assigning field to itself}}11 b = b; // expected-warning {{assigning field to itself}}12 a = b;13 14 this->a = a; // expected-warning {{assigning field to itself}}15 this->b = b; // expected-warning {{assigning field to itself}}16 a = this->a; // expected-warning {{assigning field to itself}}17 b = this->b; // expected-warning {{assigning field to itself}}18 this->a = this->a; // expected-warning {{assigning field to itself}}19 this->b = this->b; // expected-warning {{assigning field to itself}}20 21 a = b;22 a = this->b;23 this->a = b;24 this->a = this->b;25 26 a *= a;27 a /= a;28 a %= a;29 a += a;30 a -= a;31 a <<= a;32 a >>= a;33 a &= a;34 a |= a;35 a ^= a;36 }37 38 void false_positives() {39#define OP =40#define LHS a41#define RHS a42 // These shouldn't warn due to the use of the preprocessor.43 a OP a;44 LHS = a;45 a = RHS;46 LHS OP RHS;47#undef OP48#undef LHS49#undef RHS50 51 // A way to silence the warning.52 a = (int &)a;53 }54 55 // Do not diagnose self-assignment in an unevaluated context56 void false_positives_unevaluated_ctx() noexcept(noexcept(a = a)) // expected-warning {{expression with side effects has no effect in an unevaluated context}}57 {58 decltype(a = a) b = a; // expected-warning {{expression with side effects has no effect in an unevaluated context}}59 static_assert(noexcept(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}60 static_assert(sizeof(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}61 }62 63 volatile int vol_a;64 void vol_test() {65 // Volatile stores aren't side-effect free.66 vol_a = vol_a;67 volatile int &vol_a_ref = vol_a;68 vol_a_ref = vol_a_ref;69 }70};71 72// Dummy type.73struct Dummy {};74 75template <typename T>76struct TemplateClass {77 T var;78 void f() {79 var = var; // expected-warning {{assigning field to itself}}80 }81};82void instantiate() {83 {84 TemplateClass<int> c;85 c.f();86 }87 {88 TemplateClass<Dummy> c;89 c.f();90 }91}92 93// It may make sense not to warn on the rest of the tests.94// It may be a valid use-case to self-assign to tell the compiler that95// it is ok to vectorize the store.96 97void f0(C *s, C *t) {98 s->a = s->a;99 t->a = s->a;100}101 102void f1(C &s, C &t) {103 s.a = s.a;104 t.a = s.a;105}106 107struct T {108 C *s;109};110 111void f2(T *t, T *t2) {112 t->s->a = t->s->a;113 t2->s->a = t->s->a;114}115 116void f3(T &t, T &t2) {117 t.s->a = t.s->a;118 t2.s->a = t.s->a;119}120