1 // RUN: %check_clang_tidy %s bugprone-copy-constructor-init %t
2 
3 class NonCopyable {
4 public:
5   NonCopyable() = default;
6   NonCopyable(const NonCopyable &) = delete;
7 
8 private:
9   int a;
10 };
11 
12 class NonCopyable2 {
13 public:
14   NonCopyable2() = default;
15 
16 private:
17   NonCopyable2(const NonCopyable2 &);
18   int a;
19 };
20 
21 class Copyable {
22 public:
23   Copyable() = default;
24   Copyable(const Copyable &) = default;
25 
26 private:
27   int a;
28 };
29 
30 class Copyable2 {
31 public:
32   Copyable2() = default;
33   Copyable2(const Copyable2 &) = default;
34 
35 private:
36   int a;
37 };
38 
39 class Copyable3 : public Copyable {
40 public:
41   Copyable3() = default;
42   Copyable3(const Copyable3 &) = default;
43 };
44 
45 template <class C>
46 class Copyable4 {
47 public:
48   Copyable4() = default;
49   Copyable4(const Copyable4 &) = default;
50 
51 private:
52   int a;
53 };
54 
55 template <class T, class S>
56 class Copyable5 {
57 public:
58   Copyable5() = default;
59   Copyable5(const Copyable5 &) = default;
60 
61 private:
62   int a;
63 };
64 
65 class EmptyCopyable {
66 public:
67   EmptyCopyable() = default;
68   EmptyCopyable(const EmptyCopyable &) = default;
69 };
70 
71 template <typename T>
72 using CopyableAlias = Copyable5<T, int>;
73 
74 typedef Copyable5<int, int> CopyableAlias2;
75 
76 class X : public Copyable, public EmptyCopyable {
X(const X & other)77   X(const X &other) : Copyable(other) {}
78 };
79 
80 class X2 : public Copyable2 {
X2(const X2 & other)81   X2(const X2 &other) {}
82   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor other than the copy constructor [bugprone-copy-constructor-init]
83   // CHECK-FIXES: X2(const X2 &other)  : Copyable2(other) {}
84 };
85 
86 class X2_A : public Copyable2 {
X2_A(const X2_A &)87   X2_A(const X2_A &) {}
88   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
89   // CHECK-FIXES: X2_A(const X2_A &) {}
90 };
91 
92 class X3 : public Copyable, public Copyable2 {
X3(const X3 & other)93   X3(const X3 &other) : Copyable(other) {}
94   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
95   // CHECK-FIXES: X3(const X3 &other) : Copyable(other) {}
96 };
97 
98 class X4 : public Copyable {
X4(const X4 & other)99   X4(const X4 &other) : Copyable() {}
100   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
101   // CHECK-FIXES: X4(const X4 &other) : Copyable(other) {}
102 };
103 
104 class X5 : public Copyable3 {
X5(const X5 & other)105   X5(const X5 &other) {}
106   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
107   // CHECK-FIXES: X5(const X5 &other)  : Copyable3(other) {}
108 };
109 
110 class X6 : public Copyable2, public Copyable3 {
X6(const X6 & other)111   X6(const X6 &other) {}
112   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
113   // CHECK-FIXES: X6(const X6 &other)  : Copyable2(other), Copyable3(other) {}
114 };
115 
116 class X7 : public Copyable, public Copyable2 {
X7(const X7 & other)117   X7(const X7 &other) : Copyable() {}
118   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
119   // CHECK-FIXES: X7(const X7 &other) : Copyable(other) {}
120 };
121 
122 class X8 : public Copyable4<int> {
X8(const X8 & other)123   X8(const X8 &other) : Copyable4(other) {}
124 };
125 
126 class X9 : public Copyable4<int> {
X9(const X9 & other)127   X9(const X9 &other) : Copyable4() {}
128   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
129   // CHECK-FIXES: X9(const X9 &other) : Copyable4(other) {}
130 };
131 
132 class X10 : public Copyable4<int> {
X10(const X10 & other)133   X10(const X10 &other) {}
134   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
135   // CHECK-FIXES: X10(const X10 &other)  : Copyable4(other) {}
136 };
137 
138 class X11 : public Copyable5<int, float> {
X11(const X11 & other)139   X11(const X11 &other) {}
140   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
141   // CHECK-FIXES: X11(const X11 &other)  : Copyable5(other) {}
142 };
143 
144 class X12 : public CopyableAlias<float> {
X12(const X12 & other)145   X12(const X12 &other) {}
146   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
147   // CHECK-FIXES: X12(const X12 &other) {}
148 };
149 
150 template <typename T>
151 class X13 : T {
X13(const X13 & other)152   X13(const X13 &other) {}
153 };
154 
155 template class X13<EmptyCopyable>;
156 template class X13<Copyable>;
157 
158 #define FROMMACRO                \
159   class X14 : public Copyable2 { \
160     X14(const X14 &other) {}     \
161   };
162 
163 FROMMACRO
164 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: calling a base constructor
165 
166 class X15 : public CopyableAlias2 {
X15(const X15 & other)167   X15(const X15 &other) {}
168   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
169   // CHECK-FIXES: X15(const X15 &other) {}
170 };
171 
172 class X16 : public NonCopyable {
X16(const X16 & other)173   X16(const X16 &other) {}
174 };
175 
176 class X17 : public NonCopyable2 {
X17(const X17 & other)177   X17(const X17 &other) {}
178 };
179 
180 class X18 : private Copyable {
X18(const X18 & other)181   X18(const X18 &other) {}
182   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
183   // CHECK-FIXES: X18(const X18 &other)  : Copyable(other) {}
184 };
185 
186 class X19 : private Copyable {
X19(const X19 & other)187   X19(const X19 &other) : Copyable(other) {}
188 };
189