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