[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaCXX / warn-self-assign-field-builtin.cpp
blob57526242833ed8d5b5c2cd37da4e8016b15fea05
1 // RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -verify %s
3 struct C {
4 int a;
5 int b;
7 C(int a, int b) : a(a), b(b) {}
9 void f() {
10 a = a; // expected-warning {{assigning field to itself}}
11 b = b; // expected-warning {{assigning field to itself}}
12 a = b;
14 this->a = a; // expected-warning {{assigning field to itself}}
15 this->b = b; // expected-warning {{assigning field to itself}}
16 a = this->a; // expected-warning {{assigning field to itself}}
17 b = this->b; // expected-warning {{assigning field to itself}}
18 this->a = this->a; // expected-warning {{assigning field to itself}}
19 this->b = this->b; // expected-warning {{assigning field to itself}}
21 a = b;
22 a = this->b;
23 this->a = b;
24 this->a = this->b;
26 a *= a;
27 a /= a;
28 a %= a;
29 a += a;
30 a -= a;
31 a <<= a;
32 a >>= a;
33 a &= a;
34 a |= a;
35 a ^= a;
38 void false_positives() {
39 #define OP =
40 #define LHS a
41 #define RHS a
42 // These shouldn't warn due to the use of the preprocessor.
43 a OP a;
44 LHS = a;
45 a = RHS;
46 LHS OP RHS;
47 #undef OP
48 #undef LHS
49 #undef RHS
51 // A way to silence the warning.
52 a = (int &)a;
55 // Do not diagnose self-assigment in an unevaluated context
56 void false_positives_unevaluated_ctx() noexcept(noexcept(a = a)) // expected-warning {{expression with side effects has no effect in an unevaluated context}}
58 decltype(a = a) b = a; // expected-warning {{expression with side effects has no effect in an unevaluated context}}
59 static_assert(noexcept(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
60 static_assert(sizeof(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
63 volatile int vol_a;
64 void vol_test() {
65 // Volatile stores aren't side-effect free.
66 vol_a = vol_a;
67 volatile int &vol_a_ref = vol_a;
68 vol_a_ref = vol_a_ref;
72 // Dummy type.
73 struct Dummy {};
75 template <typename T>
76 struct TemplateClass {
77 T var;
78 void f() {
79 var = var; // expected-warning {{assigning field to itself}}
82 void instantiate() {
84 TemplateClass<int> c;
85 c.f();
88 TemplateClass<Dummy> c;
89 c.f();
93 // It may make sense not to warn on the rest of the tests.
94 // It may be a valid use-case to self-assign to tell the compiler that
95 // it is ok to vectorize the store.
97 void f0(C *s, C *t) {
98 s->a = s->a;
99 t->a = s->a;
102 void f1(C &s, C &t) {
103 s.a = s.a;
104 t.a = s.a;
107 struct T {
108 C *s;
111 void f2(T *t, T *t2) {
112 t->s->a = t->s->a;
113 t2->s->a = t->s->a;
116 void f3(T &t, T &t2) {
117 t.s->a = t.s->a;
118 t2.s->a = t.s->a;