blob: 7ae07e7de672da3d54cf8dec519cc5b429f24ee6 [file] [log] [blame]
Roman Lebedev61061d62018-04-07 10:39:21 +00001// RUN: %clang_cc1 -fsyntax-only -Wself-assign-field -verify %s
2
3struct C {
4 int a;
5 int b;
6
7 void f() {
8 a = a; // expected-warning {{assigning field to itself}}
9 b = b; // expected-warning {{assigning field to itself}}
10 a = b;
11
12 this->a = a; // expected-warning {{assigning field to itself}}
13 this->b = b; // expected-warning {{assigning field to itself}}
14 a = this->a; // expected-warning {{assigning field to itself}}
15 b = this->b; // expected-warning {{assigning field to itself}}
16 this->a = this->a; // expected-warning {{assigning field to itself}}
17 this->b = this->b; // expected-warning {{assigning field to itself}}
18
19 a = b;
20 a = this->b;
21 this->a = b;
22 this->a = this->b;
23
24 a *= a;
25 a /= a;
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 }
35
36 void false_positives() {
37#define OP =
38#define LHS a
39#define RHS a
40 // These shouldn't warn due to the use of the preprocessor.
41 a OP a;
42 LHS = a;
43 a = RHS;
44 LHS OP RHS;
45#undef OP
46#undef LHS
47#undef RHS
48
49 // A way to silence the warning.
50 a = (int &)a;
51 }
52
53 // Do not diagnose self-assigment in an unevaluated context
54 void false_positives_unevaluated_ctx() noexcept(noexcept(a = a)) // expected-warning {{expression with side effects has no effect in an unevaluated context}}
55 {
56 decltype(a = a) b = a; // expected-warning {{expression with side effects has no effect in an unevaluated context}}
57 static_assert(noexcept(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
58 static_assert(sizeof(a = a), ""); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
59 }
60
61 volatile int vol_a;
62 void vol_test() {
63 // Volatile stores aren't side-effect free.
64 vol_a = vol_a;
65 volatile int &vol_a_ref = vol_a;
66 vol_a_ref = vol_a_ref;
67 }
68};
69
70// Dummy type.
71struct Dummy {};
72
73template <typename T>
74struct TemplateClass {
75 T var;
76 void f() {
77 var = var; // expected-warning {{assigning field to itself}}
78 }
79};
80void instantiate() {
81 {
82 TemplateClass<int> c;
83 c.f();
84 }
85 {
86 TemplateClass<Dummy> c;
87 c.f();
88 }
89}
90
91// It may make sense not to warn on the rest of the tests.
92// It may be a valid use-case to self-assign to tell the compiler that
93// it is ok to vectorize the store.
94
95void f0(C *s, C *t) {
96 s->a = s->a;
97 t->a = s->a;
98}
99
100void f1(C &s, C &t) {
101 s.a = s.a;
102 t.a = s.a;
103}
104
105struct T {
106 C *s;
107};
108
109void f2(T *t, T *t2) {
110 t->s->a = t->s->a;
111 t2->s->a = t->s->a;
112}
113
114void f3(T &t, T &t2) {
115 t.s->a = t.s->a;
116 t2.s->a = t.s->a;
117}