116 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wself-assign -DDUMMY -verify %s2// RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV0 -verify %s3// RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV1 -verify %s4// RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV2 -verify %s5// RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV3 -verify %s6// RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV4 -verify %s7// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DDUMMY -verify %s8// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV0 -verify %s9// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV1 -verify %s10// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV2 -verify %s11// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV3 -verify %s12// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV4 -verify %s13 14#ifdef DUMMY15struct S {};16#else17struct S {18#if defined(V0)19 S() = default;20#elif defined(V1)21 S &operator=(const S &) = default;22#elif defined(V2)23 S &operator=(S &) = default;24#elif defined(V3)25 S &operator=(const S &);26#elif defined(V4)27 S &operator=(S &);28#else29#error Define something!30#endif31 S &operator*=(const S &);32 S &operator/=(const S &);33 S &operator%=(const S &);34 S &operator+=(const S &);35 S &operator-=(const S &);36 S &operator<<=(const S &);37 S &operator>>=(const S &);38 S &operator&=(const S &);39 S &operator|=(const S &);40 S &operator^=(const S &);41 S &operator=(const volatile S &) volatile;42};43#endif44 45void f() {46 S a, b;47 a = a; // expected-warning{{explicitly assigning}}48 b = b; // expected-warning{{explicitly assigning}}49 a = b;50 b = a = b;51 a = a = a; // expected-warning{{explicitly assigning}}52 a = b = b = a;53 54#ifndef DUMMY55 a *= a;56 a /= a;57 a %= a;58 a += a;59 a -= a;60 a <<= a;61 a >>= a;62 a &= a;63 a |= a;64 a ^= a;65#endif66}67 68void false_positives() {69#define OP =70#define LHS a71#define RHS a72 S a;73 // These shouldn't warn due to the use of the preprocessor.74 a OP a;75 LHS = a;76 a = RHS;77 LHS OP RHS;78#undef OP79#undef LHS80#undef RHS81 82 // Ways to silence the warning.83 a = *&a;84 a = (S &)a;85 a = static_cast<decltype(a) &>(a);86 87#ifndef DUMMY88 // Volatile stores aren't side-effect free.89 volatile S vol_a;90 vol_a = vol_a;91 volatile S &vol_a_ref = vol_a;92 vol_a_ref = vol_a_ref;93#endif94}95 96// Do not diagnose self-assignment in an unevaluated context97struct SNoExcept {98 SNoExcept() = default;99 SNoExcept &operator=(const SNoExcept &) noexcept;100};101void false_positives_unevaluated_ctx(SNoExcept a) noexcept(noexcept(a = a)) {102 decltype(a = a) b = a;103 static_assert(noexcept(a = a), "");104 static_assert(sizeof(a = a), "");105}106 107template <typename T>108void g() {109 T a;110 a = a; // expected-warning{{explicitly assigning}}111}112void instantiate() {113 g<int>();114 g<S>();115}116