Clang Project

clang_source_code/test/SemaCXX/warn-self-assign-overloaded.cpp
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
13
14#ifdef DUMMY
15struct S {};
16#else
17struct 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;
42};
43#endif
44
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 DUMMY
55  a *= a;
56  a /= a; // expected-warning {{explicitly assigning}}
57  a %= a; // expected-warning {{explicitly assigning}}
58  a += a;
59  a -= a; // expected-warning {{explicitly assigning}}
60  a <<= a;
61  a >>= a;
62  a &= a; // expected-warning {{explicitly assigning}}
63  a |= a; // expected-warning {{explicitly assigning}}
64  a ^= a; // expected-warning {{explicitly assigning}}
65#endif
66}
67
68void 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
81
82  // Ways to silence the warning.
83  a = *&a;
84  a = (S &)a;
85  a = static_cast<decltype(a) &>(a);
86
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
94}
95
96// Do not diagnose self-assigment in an unevaluated context
97struct 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