annotate clang/test/SemaCXX/warn-self-assign-field-overloaded.cpp @ 222:81f6424ef0e3 llvm-original

LLVM original branch
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 18 Jul 2021 22:10:01 +0900
parents 1d019706d866
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DDUMMY -verify %s
anatofuz
parents:
diff changeset
2 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV0 -verify %s
anatofuz
parents:
diff changeset
3 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV1 -verify %s
anatofuz
parents:
diff changeset
4 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV2 -verify %s
anatofuz
parents:
diff changeset
5 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV3 -verify %s
anatofuz
parents:
diff changeset
6 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -DV4 -verify %s
anatofuz
parents:
diff changeset
7
anatofuz
parents:
diff changeset
8 #ifdef DUMMY
anatofuz
parents:
diff changeset
9 struct S {};
anatofuz
parents:
diff changeset
10 #else
anatofuz
parents:
diff changeset
11 struct S {
anatofuz
parents:
diff changeset
12 #if defined(V0)
anatofuz
parents:
diff changeset
13 S() = default;
anatofuz
parents:
diff changeset
14 #elif defined(V1)
anatofuz
parents:
diff changeset
15 S &operator=(const S &) = default;
anatofuz
parents:
diff changeset
16 #elif defined(V2)
anatofuz
parents:
diff changeset
17 S &operator=(S &) = default;
anatofuz
parents:
diff changeset
18 #elif defined(V3)
anatofuz
parents:
diff changeset
19 S &operator=(const S &);
anatofuz
parents:
diff changeset
20 #elif defined(V4)
anatofuz
parents:
diff changeset
21 S &operator=(S &);
anatofuz
parents:
diff changeset
22 #else
anatofuz
parents:
diff changeset
23 #error Define something!
anatofuz
parents:
diff changeset
24 #endif
anatofuz
parents:
diff changeset
25 S &operator*=(const S &);
anatofuz
parents:
diff changeset
26 S &operator/=(const S &);
anatofuz
parents:
diff changeset
27 S &operator%=(const S &);
anatofuz
parents:
diff changeset
28 S &operator+=(const S &);
anatofuz
parents:
diff changeset
29 S &operator-=(const S &);
anatofuz
parents:
diff changeset
30 S &operator<<=(const S &);
anatofuz
parents:
diff changeset
31 S &operator>>=(const S &);
anatofuz
parents:
diff changeset
32 S &operator&=(const S &);
anatofuz
parents:
diff changeset
33 S &operator|=(const S &);
anatofuz
parents:
diff changeset
34 S &operator^=(const S &);
anatofuz
parents:
diff changeset
35 S &operator=(const volatile S &) volatile;
anatofuz
parents:
diff changeset
36 };
anatofuz
parents:
diff changeset
37 #endif
anatofuz
parents:
diff changeset
38 struct C {
anatofuz
parents:
diff changeset
39 S a;
anatofuz
parents:
diff changeset
40 S b;
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 void f() {
anatofuz
parents:
diff changeset
43 a = a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
44 b = b; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
45 a = b;
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 this->a = a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
48 this->b = b; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
49 a = this->a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
50 b = this->b; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
51 this->a = this->a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
52 this->b = this->b; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 a = b;
anatofuz
parents:
diff changeset
55 a = this->b;
anatofuz
parents:
diff changeset
56 this->a = b;
anatofuz
parents:
diff changeset
57 this->a = this->b;
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 #ifndef DUMMY
anatofuz
parents:
diff changeset
60 a *= a;
anatofuz
parents:
diff changeset
61 a /= a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
62 a %= a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
63 a += a;
anatofuz
parents:
diff changeset
64 a -= a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
65 a <<= a;
anatofuz
parents:
diff changeset
66 a >>= a;
anatofuz
parents:
diff changeset
67 a &= a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
68 a |= a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
69 a ^= a; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
70 #endif
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 void false_positives() {
anatofuz
parents:
diff changeset
74 #define OP =
anatofuz
parents:
diff changeset
75 #define LHS a
anatofuz
parents:
diff changeset
76 #define RHS a
anatofuz
parents:
diff changeset
77 // These shouldn't warn due to the use of the preprocessor.
anatofuz
parents:
diff changeset
78 a OP a;
anatofuz
parents:
diff changeset
79 LHS = a;
anatofuz
parents:
diff changeset
80 a = RHS;
anatofuz
parents:
diff changeset
81 LHS OP RHS;
anatofuz
parents:
diff changeset
82 #undef OP
anatofuz
parents:
diff changeset
83 #undef LHS
anatofuz
parents:
diff changeset
84 #undef RHS
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86 // Ways to silence the warning.
anatofuz
parents:
diff changeset
87 a = *&a;
anatofuz
parents:
diff changeset
88 a = (S &)a;
anatofuz
parents:
diff changeset
89 a = static_cast<decltype(a) &>(a);
anatofuz
parents:
diff changeset
90 }
anatofuz
parents:
diff changeset
91
anatofuz
parents:
diff changeset
92 #ifndef DUMMY
anatofuz
parents:
diff changeset
93 volatile S vol_a;
anatofuz
parents:
diff changeset
94 void vol_test() {
anatofuz
parents:
diff changeset
95 // Volatile stores aren't side-effect free.
anatofuz
parents:
diff changeset
96 vol_a = vol_a;
anatofuz
parents:
diff changeset
97 volatile S &vol_a_ref = vol_a;
anatofuz
parents:
diff changeset
98 vol_a_ref = vol_a_ref;
anatofuz
parents:
diff changeset
99 }
anatofuz
parents:
diff changeset
100 #endif
anatofuz
parents:
diff changeset
101 };
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 // Do not diagnose self-assigment in an unevaluated context
anatofuz
parents:
diff changeset
104 struct SNoExcept {
anatofuz
parents:
diff changeset
105 SNoExcept() = default;
anatofuz
parents:
diff changeset
106 SNoExcept &operator=(const SNoExcept &) noexcept;
anatofuz
parents:
diff changeset
107 };
anatofuz
parents:
diff changeset
108 struct false_positives_unevaluated_ctx_class {
anatofuz
parents:
diff changeset
109 SNoExcept a;
anatofuz
parents:
diff changeset
110
anatofuz
parents:
diff changeset
111 void false_positives_unevaluated_ctx(SNoExcept a) noexcept(noexcept(a = a)) {
anatofuz
parents:
diff changeset
112 decltype(a = a) b = a;
anatofuz
parents:
diff changeset
113 static_assert(noexcept(a = a), "");
anatofuz
parents:
diff changeset
114 static_assert(sizeof(a = a), "");
anatofuz
parents:
diff changeset
115 }
anatofuz
parents:
diff changeset
116 };
anatofuz
parents:
diff changeset
117
anatofuz
parents:
diff changeset
118 template <typename T>
anatofuz
parents:
diff changeset
119 struct TemplateClass {
anatofuz
parents:
diff changeset
120 T var;
anatofuz
parents:
diff changeset
121 void f() {
anatofuz
parents:
diff changeset
122 var = var; // expected-warning {{assigning field to itself}}
anatofuz
parents:
diff changeset
123 }
anatofuz
parents:
diff changeset
124 };
anatofuz
parents:
diff changeset
125 void instantiate() {
anatofuz
parents:
diff changeset
126 {
anatofuz
parents:
diff changeset
127 TemplateClass<int> c;
anatofuz
parents:
diff changeset
128 c.f();
anatofuz
parents:
diff changeset
129 }
anatofuz
parents:
diff changeset
130 {
anatofuz
parents:
diff changeset
131 TemplateClass<S> c;
anatofuz
parents:
diff changeset
132 c.f();
anatofuz
parents:
diff changeset
133 }
anatofuz
parents:
diff changeset
134 }
anatofuz
parents:
diff changeset
135
anatofuz
parents:
diff changeset
136 // It may make sense not to warn on the rest of the tests.
anatofuz
parents:
diff changeset
137 // It may be a valid use-case to self-assign to tell the compiler that
anatofuz
parents:
diff changeset
138 // it is ok to vectorize the store.
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 void f0(C *s, C *t) {
anatofuz
parents:
diff changeset
141 s->a = s->a;
anatofuz
parents:
diff changeset
142 t->a = s->a;
anatofuz
parents:
diff changeset
143 }
anatofuz
parents:
diff changeset
144
anatofuz
parents:
diff changeset
145 void f1(C &s, C &t) {
anatofuz
parents:
diff changeset
146 s.a = s.a;
anatofuz
parents:
diff changeset
147 t.a = s.a;
anatofuz
parents:
diff changeset
148 }
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 struct T {
anatofuz
parents:
diff changeset
151 C *s;
anatofuz
parents:
diff changeset
152 };
anatofuz
parents:
diff changeset
153
anatofuz
parents:
diff changeset
154 void f2(T *t, T *t2) {
anatofuz
parents:
diff changeset
155 t->s->a = t->s->a;
anatofuz
parents:
diff changeset
156 t2->s->a = t->s->a;
anatofuz
parents:
diff changeset
157 }
anatofuz
parents:
diff changeset
158
anatofuz
parents:
diff changeset
159 void f3(T &t, T &t2) {
anatofuz
parents:
diff changeset
160 t.s->a = t.s->a;
anatofuz
parents:
diff changeset
161 t2.s->a = t.s->a;
anatofuz
parents:
diff changeset
162 }