[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-self-assign-overloaded.cpp
blob428797ae40cd072d02b620ebd0d5c973c363ecc5
1 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DDUMMY -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV0 -verify %s
3 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV1 -verify %s
4 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV2 -verify %s
5 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV3 -verify %s
6 // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV4 -verify %s
7 // RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DDUMMY -verify %s
8 // RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV0 -verify %s
9 // RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV1 -verify %s
10 // RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV2 -verify %s
11 // RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV3 -verify %s
12 // RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV4 -verify %s
14 #ifdef DUMMY
15 struct S {};
16 #else
17 struct 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 #else
29 #error Define something!
30 #endif
31 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;
43 #endif
45 void 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;
54 #ifndef DUMMY
55 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 #endif
68 void false_positives() {
69 #define OP =
70 #define LHS a
71 #define RHS a
72 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 OP
79 #undef LHS
80 #undef RHS
82 // Ways to silence the warning.
83 a = *&a;
84 a = (S &)a;
85 a = static_cast<decltype(a) &>(a);
87 #ifndef DUMMY
88 // 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 #endif
96 // Do not diagnose self-assigment in an unevaluated context
97 struct SNoExcept {
98 SNoExcept() = default;
99 SNoExcept &operator=(const SNoExcept &) noexcept;
101 void 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), "");
107 template <typename T>
108 void g() {
109 T a;
110 a = a; // expected-warning{{explicitly assigning}}
112 void instantiate() {
113 g<int>();
114 g<S>();