1 // RUN: %check_clang_tidy %s readability-redundant-member-init %t \
2 // RUN: -config="{CheckOptions: \
3 // RUN: [{key: readability-redundant-member-init.IgnoreBaseInCopyConstructors, \
4 // RUN: value: true}] \
5 // RUN: }"
6
7 struct S {
8 S() = default;
SS9 S(int i) : i(i) {}
10 int i = 1;
11 };
12
13 struct T {
TT14 T(int i = 1) : i(i) {}
15 int i;
16 };
17
18 struct U {
19 int i;
20 };
21
22 union V {
23 int i;
24 double f;
25 };
26
27 // Initializer calls default constructor
28 struct F1 {
F1F129 F1() : f() {}
30 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
31 // CHECK-FIXES: F1() {}
32 S f;
33 };
34
35 // Initializer calls default constructor with default argument
36 struct F2 {
F2F237 F2() : f() {}
38 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
39 // CHECK-FIXES: F2() {}
40 T f;
41 };
42
43 // Multiple redundant initializers for same constructor
44 struct F3 {
F3F345 F3() : f(), g(1), h() {}
46 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
47 // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: initializer for member 'h' is redundant
48 // CHECK-FIXES: F3() : g(1) {}
49 S f, g, h;
50 };
51
52 // Templated class independent type
53 template <class V>
54 struct F4 {
F4F455 F4() : f() {}
56 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'f' is redundant
57 // CHECK-FIXES: F4() {}
58 S f;
59 };
60 F4<int> f4i;
61 F4<S> f4s;
62
63 // Base class
64 struct F5 : S {
F5F565 F5() : S() {}
66 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for base class 'S' is redundant
67 // CHECK-FIXES: F5() {}
68 };
69
70 // Constructor call requires cleanup
71 struct Cleanup {
~CleanupCleanup72 ~Cleanup() {}
73 };
74
75 struct UsesCleanup {
UsesCleanupUsesCleanup76 UsesCleanup(const Cleanup &c = Cleanup()) {}
77 };
78
79 struct F6 {
F6F680 F6() : uc() {}
81 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 'uc' is redundant
82 // CHECK-FIXES: F6() {}
83 UsesCleanup uc;
84 };
85
86 // Multiple inheritance
87 struct F7 : S, T {
F7F788 F7() : S(), T() {}
89 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for base class 'S' is redundant
90 // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: initializer for base class 'T' is redundant
91 // CHECK-FIXES: F7() {}
92 };
93
94 namespace Foo {
95 inline namespace Bar {
96 template <int N>
97 struct Template {
98 Template() = default;
99 int i = N;
100 };
101 }
102 }
103
104 enum { N_THINGS = 5 };
105
106 struct F8 : Foo::Template<N_THINGS> {
F8F8107 F8() : Template() {}
108 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for base class 'Foo::Template<N_THINGS>' is redundant
109 // CHECK-FIXES: F8() {}
110 };
111
112 // Anonymous struct
113 struct F9 {
F9F9114 F9() : s1() {}
115 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: initializer for member 's1' is redundant
116 // CHECK-FIXES: F9() {}
117 struct {
118 S s1;
119 S s2;
120 };
121 };
122
123 // struct whose inline copy constructor default-initializes its base class
124 struct WithCopyConstructor1 : public T {
WithCopyConstructor1WithCopyConstructor1125 WithCopyConstructor1(const WithCopyConstructor1& other) : T(),
126 f(),
127 g()
128 {}
129 S f, g;
130 };
131 // No warning in copy constructor about T since IgnoreBaseInCopyConstructors=1
132 // CHECK-MESSAGES: :[[@LINE-6]]:5: warning: initializer for member 'f' is redundant
133 // CHECK-MESSAGES: :[[@LINE-6]]:5: warning: initializer for member 'g' is redundant
134 // CHECK-FIXES: WithCopyConstructor1(const WithCopyConstructor1& other) : T()
135 // CHECK-NEXT:
136 // CHECK-NEXT:
137 // CHECK-NEXT: {}
138
139 // struct whose copy constructor default-initializes its base class
140 struct WithCopyConstructor2 : public T {
141 WithCopyConstructor2(const WithCopyConstructor2& other);
142 S a;
143 };
WithCopyConstructor2(const WithCopyConstructor2 & other)144 WithCopyConstructor2::WithCopyConstructor2(const WithCopyConstructor2& other)
145 : T(), a()
146 {}
147 // No warning in copy constructor about T since IgnoreBaseInCopyConstructors=1
148 // CHECK-MESSAGES: :[[@LINE-3]]:10: warning: initializer for member 'a' is redundant
149 // CHECK-FIXES: {{^}} : T() {{$}}
150 // CHECK-NEXT: {}
151
152 // Initializer not written
153 struct NF1 {
NF1NF1154 NF1() {}
155 S f;
156 };
157
158 // Initializer doesn't call default constructor
159 struct NF2 {
NF2NF2160 NF2() : f(1) {}
161 S f;
162 };
163
164 // Initializer calls default constructor without using default argument
165 struct NF3 {
NF3NF3166 NF3() : f(1) {}
167 T f;
168 };
169
170 // Initializer calls default constructor without using default argument
171 struct NF4 {
NF4NF4172 NF4() : f(2) {}
173 T f;
174 };
175
176 // Initializer is zero-initialization
177 struct NF5 {
NF5NF5178 NF5() : i() {}
179 int i;
180 };
181
182 // Initializer is direct-initialization
183 struct NF6 {
NF6NF6184 NF6() : i(1) {}
185 int i;
186 };
187
188 // Initializer is aggregate initialization of struct
189 struct NF7 {
NF7NF7190 NF7() : f{} {}
191 U f;
192 };
193
194 // Initializer is zero-initialization of struct
195 struct NF7b {
NF7bNF7b196 NF7b() : f() {}
197 U f;
198 };
199
200 // Initializer is aggregate initialization of array
201 struct NF8 {
NF8NF8202 NF8() : f{} {}
203 int f[2];
204 };
205
206 struct NF9 {
NF9NF9207 NF9() : f{} {}
208 S f[2];
209 };
210
211 // Initializing member of union
212 union NF10 {
NF10()213 NF10() : s() {}
214 int i;
215 S s;
216 };
217
218 // Templated class dependent type
219 template <class V>
220 struct NF11 {
NF11NF11221 NF11() : f() {}
222 V f;
223 };
224 NF11<int> nf11i;
225 NF11<S> nf11s;
226
227 // Delegating constructor
228 class NF12 {
229 NF12() = default;
NF12(int)230 NF12(int) : NF12() {}
231 };
232
233 // Const member
234 struct NF13 {
NF13NF13235 NF13() : f() {}
236 const S f;
237 };
238
239 // Union member
240 struct NF14 {
NF14NF14241 NF14() : f() {}
242 V f;
243 };
244
245 // Anonymous union member
246 struct NF15 {
NF15NF15247 NF15() : s1() {}
248 union {
249 S s1;
250 S s2;
251 };
252 };
253