189a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-copy-constructor-init %t 289a1d03eSRichard 389a1d03eSRichard class NonCopyable { 489a1d03eSRichard public: 589a1d03eSRichard NonCopyable() = default; 689a1d03eSRichard NonCopyable(const NonCopyable &) = delete; 789a1d03eSRichard 889a1d03eSRichard private: 989a1d03eSRichard int a; 1089a1d03eSRichard }; 1189a1d03eSRichard 1289a1d03eSRichard class NonCopyable2 { 1389a1d03eSRichard public: 1489a1d03eSRichard NonCopyable2() = default; 1589a1d03eSRichard 1689a1d03eSRichard private: 1789a1d03eSRichard NonCopyable2(const NonCopyable2 &); 1889a1d03eSRichard int a; 1989a1d03eSRichard }; 2089a1d03eSRichard 2189a1d03eSRichard class Copyable { 2289a1d03eSRichard public: 2389a1d03eSRichard Copyable() = default; 2489a1d03eSRichard Copyable(const Copyable &) = default; 2589a1d03eSRichard 2689a1d03eSRichard private: 2789a1d03eSRichard int a; 2889a1d03eSRichard }; 2989a1d03eSRichard 3089a1d03eSRichard class Copyable2 { 3189a1d03eSRichard public: 3289a1d03eSRichard Copyable2() = default; 3389a1d03eSRichard Copyable2(const Copyable2 &) = default; 3489a1d03eSRichard 3589a1d03eSRichard private: 3689a1d03eSRichard int a; 3789a1d03eSRichard }; 3889a1d03eSRichard 3989a1d03eSRichard class Copyable3 : public Copyable { 4089a1d03eSRichard public: 4189a1d03eSRichard Copyable3() = default; 4289a1d03eSRichard Copyable3(const Copyable3 &) = default; 4389a1d03eSRichard }; 4489a1d03eSRichard 4589a1d03eSRichard template <class C> 4689a1d03eSRichard class Copyable4 { 4789a1d03eSRichard public: 4889a1d03eSRichard Copyable4() = default; 4989a1d03eSRichard Copyable4(const Copyable4 &) = default; 5089a1d03eSRichard 5189a1d03eSRichard private: 5289a1d03eSRichard int a; 5389a1d03eSRichard }; 5489a1d03eSRichard 5589a1d03eSRichard template <class T, class S> 5689a1d03eSRichard class Copyable5 { 5789a1d03eSRichard public: 5889a1d03eSRichard Copyable5() = default; 5989a1d03eSRichard Copyable5(const Copyable5 &) = default; 6089a1d03eSRichard 6189a1d03eSRichard private: 6289a1d03eSRichard int a; 6389a1d03eSRichard }; 6489a1d03eSRichard 6589a1d03eSRichard class EmptyCopyable { 6689a1d03eSRichard public: 6789a1d03eSRichard EmptyCopyable() = default; 6889a1d03eSRichard EmptyCopyable(const EmptyCopyable &) = default; 6989a1d03eSRichard }; 7089a1d03eSRichard 7189a1d03eSRichard template <typename T> 7289a1d03eSRichard using CopyableAlias = Copyable5<T, int>; 7389a1d03eSRichard 7489a1d03eSRichard typedef Copyable5<int, int> CopyableAlias2; 7589a1d03eSRichard 7689a1d03eSRichard class X : public Copyable, public EmptyCopyable { X(const X & other)7789a1d03eSRichard X(const X &other) : Copyable(other) {} 7889a1d03eSRichard }; 7989a1d03eSRichard 8089a1d03eSRichard class X2 : public Copyable2 { X2(const X2 & other)8189a1d03eSRichard X2(const X2 &other) {} 8289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor other than the copy constructor [bugprone-copy-constructor-init] 8389a1d03eSRichard // CHECK-FIXES: X2(const X2 &other) : Copyable2(other) {} 8489a1d03eSRichard }; 8589a1d03eSRichard 8689a1d03eSRichard class X2_A : public Copyable2 { X2_A(const X2_A &)8789a1d03eSRichard X2_A(const X2_A &) {} 8889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 8989a1d03eSRichard // CHECK-FIXES: X2_A(const X2_A &) {} 9089a1d03eSRichard }; 9189a1d03eSRichard 9289a1d03eSRichard class X3 : public Copyable, public Copyable2 { X3(const X3 & other)9389a1d03eSRichard X3(const X3 &other) : Copyable(other) {} 9489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 9589a1d03eSRichard // CHECK-FIXES: X3(const X3 &other) : Copyable(other) {} 9689a1d03eSRichard }; 9789a1d03eSRichard 9889a1d03eSRichard class X4 : public Copyable { X4(const X4 & other)9989a1d03eSRichard X4(const X4 &other) : Copyable() {} 10089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 10189a1d03eSRichard // CHECK-FIXES: X4(const X4 &other) : Copyable(other) {} 10289a1d03eSRichard }; 10389a1d03eSRichard 10489a1d03eSRichard class X5 : public Copyable3 { X5(const X5 & other)10589a1d03eSRichard X5(const X5 &other) {} 10689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 10789a1d03eSRichard // CHECK-FIXES: X5(const X5 &other) : Copyable3(other) {} 10889a1d03eSRichard }; 10989a1d03eSRichard 11089a1d03eSRichard class X6 : public Copyable2, public Copyable3 { X6(const X6 & other)11189a1d03eSRichard X6(const X6 &other) {} 11289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 11389a1d03eSRichard // CHECK-FIXES: X6(const X6 &other) : Copyable2(other), Copyable3(other) {} 11489a1d03eSRichard }; 11589a1d03eSRichard 11689a1d03eSRichard class X7 : public Copyable, public Copyable2 { X7(const X7 & other)11789a1d03eSRichard X7(const X7 &other) : Copyable() {} 11889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 11989a1d03eSRichard // CHECK-FIXES: X7(const X7 &other) : Copyable(other) {} 12089a1d03eSRichard }; 12189a1d03eSRichard 12289a1d03eSRichard class X8 : public Copyable4<int> { X8(const X8 & other)12389a1d03eSRichard X8(const X8 &other) : Copyable4(other) {} 12489a1d03eSRichard }; 12589a1d03eSRichard 12689a1d03eSRichard class X9 : public Copyable4<int> { X9(const X9 & other)12789a1d03eSRichard X9(const X9 &other) : Copyable4() {} 12889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 12989a1d03eSRichard // CHECK-FIXES: X9(const X9 &other) : Copyable4(other) {} 13089a1d03eSRichard }; 13189a1d03eSRichard 13289a1d03eSRichard class X10 : public Copyable4<int> { X10(const X10 & other)13389a1d03eSRichard X10(const X10 &other) {} 13489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 13589a1d03eSRichard // CHECK-FIXES: X10(const X10 &other) : Copyable4(other) {} 13689a1d03eSRichard }; 13789a1d03eSRichard 13889a1d03eSRichard class X11 : public Copyable5<int, float> { X11(const X11 & other)13989a1d03eSRichard X11(const X11 &other) {} 14089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 14189a1d03eSRichard // CHECK-FIXES: X11(const X11 &other) : Copyable5(other) {} 14289a1d03eSRichard }; 14389a1d03eSRichard 14489a1d03eSRichard class X12 : public CopyableAlias<float> { X12(const X12 & other)14589a1d03eSRichard X12(const X12 &other) {} 14689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 14789a1d03eSRichard }; 14889a1d03eSRichard 14989a1d03eSRichard template <typename T> 15089a1d03eSRichard class X13 : T { X13(const X13 & other)15189a1d03eSRichard X13(const X13 &other) {} 15289a1d03eSRichard }; 15389a1d03eSRichard 15489a1d03eSRichard template class X13<EmptyCopyable>; 15589a1d03eSRichard template class X13<Copyable>; 15689a1d03eSRichard 15789a1d03eSRichard #define FROMMACRO \ 15889a1d03eSRichard class X14 : public Copyable2 { \ 15989a1d03eSRichard X14(const X14 &other) {} \ 16089a1d03eSRichard }; 16189a1d03eSRichard 16289a1d03eSRichard FROMMACRO 16389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: calling a base constructor 16489a1d03eSRichard 16589a1d03eSRichard class X15 : public CopyableAlias2 { X15(const X15 & other)16689a1d03eSRichard X15(const X15 &other) {} 16789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 168*15f3cd6bSMatheus Izvekov // CHECK-FIXES: X15(const X15 &other) : Copyable5(other) {} 16989a1d03eSRichard }; 17089a1d03eSRichard 17189a1d03eSRichard class X16 : public NonCopyable { X16(const X16 & other)17289a1d03eSRichard X16(const X16 &other) {} 17389a1d03eSRichard }; 17489a1d03eSRichard 17589a1d03eSRichard class X17 : public NonCopyable2 { X17(const X17 & other)17689a1d03eSRichard X17(const X17 &other) {} 17789a1d03eSRichard }; 17889a1d03eSRichard 17989a1d03eSRichard class X18 : private Copyable { X18(const X18 & other)18089a1d03eSRichard X18(const X18 &other) {} 18189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor 18289a1d03eSRichard // CHECK-FIXES: X18(const X18 &other) : Copyable(other) {} 18389a1d03eSRichard }; 18489a1d03eSRichard 18589a1d03eSRichard class X19 : private Copyable { X19(const X19 & other)18689a1d03eSRichard X19(const X19 &other) : Copyable(other) {} 18789a1d03eSRichard }; 188