[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaCXX / warn-self-assign-field-overloaded.cpp
blobc9cec8e406fc4182e828393d81c24e7498ebf468
1 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DDUMMY -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV0 -verify %s
3 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV1 -verify %s
4 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV2 -verify %s
5 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV3 -verify %s
6 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV4 -verify %s
8 #ifdef DUMMY
9 struct S {};
10 #else
11 struct 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 #else
23 #error Define something!
24 #endif
25 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;
37 #endif
38 struct C {
39 S a;
40 S b;
42 void f() {
43 a = a; // expected-warning {{assigning field to itself}}
44 b = b; // expected-warning {{assigning field to itself}}
45 a = b;
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}}
54 a = b;
55 a = this->b;
56 this->a = b;
57 this->a = this->b;
59 #ifndef DUMMY
60 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 #endif
73 void false_positives() {
74 #define OP =
75 #define LHS a
76 #define RHS a
77 // 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 OP
83 #undef LHS
84 #undef RHS
86 // Ways to silence the warning.
87 a = *&a;
88 a = (S &)a;
89 a = static_cast<decltype(a) &>(a);
92 #ifndef DUMMY
93 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;
100 #endif
103 // Do not diagnose self-assigment in an unevaluated context
104 struct SNoExcept {
105 SNoExcept() = default;
106 SNoExcept &operator=(const SNoExcept &) noexcept;
108 struct false_positives_unevaluated_ctx_class {
109 SNoExcept a;
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), "");
118 template <typename T>
119 struct TemplateClass {
120 T var;
121 void f() {
122 var = var; // expected-warning {{assigning field to itself}}
125 void instantiate() {
127 TemplateClass<int> c;
128 c.f();
131 TemplateClass<S> c;
132 c.f();
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 that
138 // it is ok to vectorize the store.
140 void f0(C *s, C *t) {
141 s->a = s->a;
142 t->a = s->a;
145 void f1(C &s, C &t) {
146 s.a = s.a;
147 t.a = s.a;
150 struct T {
151 C *s;
154 void f2(T *t, T *t2) {
155 t->s->a = t->s->a;
156 t2->s->a = t->s->a;
159 void f3(T &t, T &t2) {
160 t.s->a = t.s->a;
161 t2.s->a = t.s->a;