brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 7141bc1 Raw
163 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DDUMMY -verify %s2// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV0 -verify %s3// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV1 -verify %s4// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV2 -verify %s5// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV3 -verify %s6// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV4 -verify %s7 8#ifdef DUMMY9struct S {};10#else11struct S {12#if defined(V0)13  S() = default;14#elif defined(V1)15  S &operator=(const S &) = default;16#elif defined(V2)17  S &operator=(S &) = default;18#elif defined(V3)19  S &operator=(const S &);20#elif defined(V4)21  S &operator=(S &);22#else23#error Define something!24#endif25  S &operator*=(const S &);26  S &operator/=(const S &);27  S &operator%=(const S &);28  S &operator+=(const S &);29  S &operator-=(const S &);30  S &operator<<=(const S &);31  S &operator>>=(const S &);32  S &operator&=(const S &);33  S &operator|=(const S &);34  S &operator^=(const S &);35  S &operator=(const volatile S &) volatile;36};37#endif38struct C {39  S a;40  S b;41 42  void f() {43    a = a; // expected-warning {{assigning field to itself}}44    b = b; // expected-warning {{assigning field to itself}}45    a = b;46 47    this->a = a;       // expected-warning {{assigning field to itself}}48    this->b = b;       // expected-warning {{assigning field to itself}}49    a = this->a;       // expected-warning {{assigning field to itself}}50    b = this->b;       // expected-warning {{assigning field to itself}}51    this->a = this->a; // expected-warning {{assigning field to itself}}52    this->b = this->b; // expected-warning {{assigning field to itself}}53 54    a = b;55    a = this->b;56    this->a = b;57    this->a = this->b;58 59#ifndef DUMMY60    a *= a;61    a /= a; // expected-warning {{assigning field to itself}}62    a %= a; // expected-warning {{assigning field to itself}}63    a += a;64    a -= a; // expected-warning {{assigning field to itself}}65    a <<= a;66    a >>= a;67    a &= a; // expected-warning {{assigning field to itself}}68    a |= a; // expected-warning {{assigning field to itself}}69    a ^= a; // expected-warning {{assigning field to itself}}70#endif71  }72 73  void false_positives() {74#define OP =75#define LHS a76#define RHS a77    // These shouldn't warn due to the use of the preprocessor.78    a OP a;79    LHS = a;80    a = RHS;81    LHS OP RHS;82#undef OP83#undef LHS84#undef RHS85 86    // Ways to silence the warning.87    a = *&a;88    a = (S &)a;89    a = static_cast<decltype(a) &>(a);90  }91 92#ifndef DUMMY93  volatile S vol_a;94  void vol_test() {95    // Volatile stores aren't side-effect free.96    vol_a = vol_a;97    volatile S &vol_a_ref = vol_a;98    vol_a_ref = vol_a_ref;99  }100#endif101};102 103// Do not diagnose self-assignment in an unevaluated context104struct SNoExcept {105  SNoExcept() = default;106  SNoExcept &operator=(const SNoExcept &) noexcept;107};108struct false_positives_unevaluated_ctx_class {109  SNoExcept a;110 111  void false_positives_unevaluated_ctx(SNoExcept a) noexcept(noexcept(a = a)) {112    decltype(a = a) b = a;113    static_assert(noexcept(a = a), "");114    static_assert(sizeof(a = a), "");115  }116};117 118template <typename T>119struct TemplateClass {120  T var;121  void f() {122    var = var; // expected-warning {{assigning field to itself}}123  }124};125void instantiate() {126  {127    TemplateClass<int> c;128    c.f();129  }130  {131    TemplateClass<S> c;132    c.f();133  }134}135 136// It may make sense not to warn on the rest of the tests.137// It may be a valid use-case to self-assign to tell the compiler that138// it is ok to vectorize the store.139 140void f0(C *s, C *t) {141  s->a = s->a;142  t->a = s->a;143}144 145void f1(C &s, C &t) {146  s.a = s.a;147  t.a = s.a;148}149 150struct T {151  C *s;152};153 154void f2(T *t, T *t2) {155  t->s->a = t->s->a;156  t2->s->a = t->s->a;157}158 159void f3(T &t, T &t2) {160  t.s->a = t.s->a;161  t2.s->a = t.s->a;162}163