189a1d03eSRichard // RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions 289a1d03eSRichard 389a1d03eSRichard // Out of line definition. 489a1d03eSRichard class OL { 589a1d03eSRichard public: 689a1d03eSRichard OL(); 789a1d03eSRichard ~OL(); 889a1d03eSRichard }; 989a1d03eSRichard OL()1089a1d03eSRichardOL::OL() {}; 1189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial default constructor [modernize-use-equals-default] 1289a1d03eSRichard // CHECK-FIXES: OL::OL() = default; ~OL()1389a1d03eSRichardOL::~OL() {} 1489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial destructor [modernize-use-equals-default] 1589a1d03eSRichard // CHECK-FIXES: OL::~OL() = default; 1689a1d03eSRichard 1789a1d03eSRichard // Inline definitions. 1889a1d03eSRichard class IL { 1989a1d03eSRichard public: IL()2089a1d03eSRichard IL() {} ; // Note embedded tab on this line 2189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 2289a1d03eSRichard // CHECK-FIXES: IL() = default ; // Note embedded tab on this line ~IL()2389a1d03eSRichard ~IL() {} 2489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 2589a1d03eSRichard // CHECK-FIXES: ~IL() = default; 2689a1d03eSRichard }; 2789a1d03eSRichard 2889a1d03eSRichard // Non-empty body. 2989a1d03eSRichard void f(); 3089a1d03eSRichard class NE { 3189a1d03eSRichard public: NE()3289a1d03eSRichard NE() { f(); } ~NE()3389a1d03eSRichard ~NE() { f(); } 3489a1d03eSRichard }; 3589a1d03eSRichard 36083e3a17SAlexander Shaposhnikov // Skip unions. 37083e3a17SAlexander Shaposhnikov union NU { NU()38083e3a17SAlexander Shaposhnikov NU() {} 39083e3a17SAlexander Shaposhnikov // CHECK-FIXES: NU() {} ~NU()40083e3a17SAlexander Shaposhnikov ~NU() {} 41083e3a17SAlexander Shaposhnikov // CHECK-FIXES: ~NU() {} 42083e3a17SAlexander Shaposhnikov NE Field; 43083e3a17SAlexander Shaposhnikov }; 44083e3a17SAlexander Shaposhnikov 45*eb87e55cSPiotr Zegar // Skip unions with out-of-line constructor/destructor. 46*eb87e55cSPiotr Zegar union NUO { 47*eb87e55cSPiotr Zegar NUO(); 48*eb87e55cSPiotr Zegar ~NUO(); 49*eb87e55cSPiotr Zegar NE Field; 50*eb87e55cSPiotr Zegar }; 51*eb87e55cSPiotr Zegar NUO()52*eb87e55cSPiotr ZegarNUO::NUO() {} 53*eb87e55cSPiotr Zegar // CHECK-FIXES: NUO::NUO() {} ~NUO()54*eb87e55cSPiotr ZegarNUO::~NUO() {} 55*eb87e55cSPiotr Zegar // CHECK-FIXES: NUO::~NUO() {} 56*eb87e55cSPiotr Zegar 5744503482SAlexander Shaposhnikov // Skip structs/classes containing anonymous unions. 5844503482SAlexander Shaposhnikov struct SU { SUSU5944503482SAlexander Shaposhnikov SU() {} 6044503482SAlexander Shaposhnikov // CHECK-FIXES: SU() {} ~SUSU6144503482SAlexander Shaposhnikov ~SU() {} 6244503482SAlexander Shaposhnikov // CHECK-FIXES: ~SU() {} 6344503482SAlexander Shaposhnikov union { 6444503482SAlexander Shaposhnikov NE Field; 6544503482SAlexander Shaposhnikov }; 6644503482SAlexander Shaposhnikov }; 6744503482SAlexander Shaposhnikov 68d4e81097SAlexander Shaposhnikov // Skip variadic constructors. 69d4e81097SAlexander Shaposhnikov struct VA { VAVA70d4e81097SAlexander Shaposhnikov VA(...) {} 71d4e81097SAlexander Shaposhnikov }; 72d4e81097SAlexander Shaposhnikov 7329e4606cSAlexander Shaposhnikov // Skip template constructors. 7429e4606cSAlexander Shaposhnikov struct TC { 7529e4606cSAlexander Shaposhnikov template <unsigned U> TCTC7629e4606cSAlexander Shaposhnikov TC() {} 7729e4606cSAlexander Shaposhnikov 7829e4606cSAlexander Shaposhnikov template <unsigned U> TCTC7929e4606cSAlexander Shaposhnikov TC(const TC &) {} 8029e4606cSAlexander Shaposhnikov 8129e4606cSAlexander Shaposhnikov template <unsigned U> operator =TC8229e4606cSAlexander Shaposhnikov TC& operator = (const TC &) { return *this; } 8329e4606cSAlexander Shaposhnikov }; 8429e4606cSAlexander Shaposhnikov 8589a1d03eSRichard // Initializer or arguments. 8689a1d03eSRichard class IA { 8789a1d03eSRichard public: 8889a1d03eSRichard // Constructor with initializer. IA()8989a1d03eSRichard IA() : Field(5) {} 9089a1d03eSRichard // Constructor with arguments. IA(int Arg1,int Arg2)9189a1d03eSRichard IA(int Arg1, int Arg2) {} 9289a1d03eSRichard int Field; 9389a1d03eSRichard }; 9489a1d03eSRichard 9589a1d03eSRichard // Default member initializer 9689a1d03eSRichard class DMI { 9789a1d03eSRichard public: DMI()9889a1d03eSRichard DMI() {} // Comment before semi-colon on next line 9989a1d03eSRichard ; 10089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default' 10189a1d03eSRichard // CHECK-FIXES: DMI() = default // Comment before semi-colon on next line 10289a1d03eSRichard // CHECK-FIXES-NEXT: ; 10389a1d03eSRichard int Field = 5; 10489a1d03eSRichard }; 10589a1d03eSRichard 10689a1d03eSRichard // Class member 10789a1d03eSRichard class CM { 10889a1d03eSRichard public: CM()10989a1d03eSRichard CM() {} /* Comments */ /* before */ /* semicolon */; 11089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 11189a1d03eSRichard // CHECK-FIXES: CM() = default /* Comments */ /* before */ /* semicolon */; 11289a1d03eSRichard OL o; 11389a1d03eSRichard }; 11489a1d03eSRichard 11589a1d03eSRichard // Private constructor/destructor. 11689a1d03eSRichard class Priv { 11790d42b1cSAlexander Shaposhnikov Priv(); ~Priv()1186c07bda7SAlexander Shaposhnikov ~Priv() {} 11989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 12089a1d03eSRichard // CHECK-FIXES: ~Priv() = default; 12189a1d03eSRichard }; 12289a1d03eSRichard Priv()12390d42b1cSAlexander ShaposhnikovPriv::Priv() {} 12490d42b1cSAlexander Shaposhnikov // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default' 12590d42b1cSAlexander Shaposhnikov // CHECK-FIXES: Priv::Priv() = default; 12690d42b1cSAlexander Shaposhnikov 1276c07bda7SAlexander Shaposhnikov struct SemiColon { SemiColonSemiColon1286c07bda7SAlexander Shaposhnikov SemiColon() {}; 1296c07bda7SAlexander Shaposhnikov // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 1306c07bda7SAlexander Shaposhnikov // CHECK-FIXES: SemiColon() = default;{{$}} 1316c07bda7SAlexander Shaposhnikov }; 1326c07bda7SAlexander Shaposhnikov 1336c07bda7SAlexander Shaposhnikov struct SemiColonOutOfLine { 1346c07bda7SAlexander Shaposhnikov SemiColonOutOfLine(); 1356c07bda7SAlexander Shaposhnikov }; 1366c07bda7SAlexander Shaposhnikov SemiColonOutOfLine()1376c07bda7SAlexander ShaposhnikovSemiColonOutOfLine::SemiColonOutOfLine() {}; 1386c07bda7SAlexander Shaposhnikov // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use '= default' 1396c07bda7SAlexander Shaposhnikov // CHECK-FIXES: SemiColonOutOfLine::SemiColonOutOfLine() = default;{{$}} 1406c07bda7SAlexander Shaposhnikov 14189a1d03eSRichard // struct. 14289a1d03eSRichard struct ST { STST14389a1d03eSRichard ST() {} 14489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 1456c07bda7SAlexander Shaposhnikov // CHECK-FIXES: ST() = default;{{$}} ~STST14689a1d03eSRichard ~ST() {} 14789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 1486c07bda7SAlexander Shaposhnikov // CHECK-FIXES: ST() = default;{{$}} 14989a1d03eSRichard }; 15089a1d03eSRichard 15189a1d03eSRichard // Deleted constructor/destructor. 15289a1d03eSRichard class Del { 15389a1d03eSRichard public: 15489a1d03eSRichard Del() = delete; 15589a1d03eSRichard ~Del() = delete; 15689a1d03eSRichard }; 15789a1d03eSRichard 15889a1d03eSRichard // Do not remove other keywords. 15989a1d03eSRichard class KW { 16089a1d03eSRichard public: KW()16189a1d03eSRichard explicit KW() {} 16289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use '= default' 16389a1d03eSRichard // CHECK-FIXES: explicit KW() = default; ~KW()16489a1d03eSRichard virtual ~KW() {} 16589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use '= default' 16689a1d03eSRichard // CHECK-FIXES: virtual ~KW() = default; 16789a1d03eSRichard }; 16889a1d03eSRichard 16989a1d03eSRichard // Nested class. 17089a1d03eSRichard struct N { 17189a1d03eSRichard struct NN { NNN::NN17289a1d03eSRichard NN() {} 17389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' 17489a1d03eSRichard // CHECK-FIXES: NN() = default; ~NNN::NN17589a1d03eSRichard ~NN() {} 17689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' 17789a1d03eSRichard // CHECK-FIXES: ~NN() = default; 17889a1d03eSRichard }; 17989a1d03eSRichard int Int; 18089a1d03eSRichard }; 18189a1d03eSRichard 18289a1d03eSRichard // Class template. 18389a1d03eSRichard template <class T> 18489a1d03eSRichard class Temp { 18589a1d03eSRichard public: Temp()18689a1d03eSRichard Temp() {} 18789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 18889a1d03eSRichard // CHECK-FIXES: Temp() = default; ~Temp()18989a1d03eSRichard ~Temp() {} 19089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 19189a1d03eSRichard // CHECK-FIXES: ~Temp() = default; 19289a1d03eSRichard }; 19389a1d03eSRichard 19489a1d03eSRichard // Class template out of line with explicit instantiation. 19589a1d03eSRichard template <class T> 19689a1d03eSRichard class TempODef { 19789a1d03eSRichard public: 19889a1d03eSRichard TempODef(); 19989a1d03eSRichard ~TempODef(); 20089a1d03eSRichard }; 20189a1d03eSRichard 20289a1d03eSRichard template <class T> TempODef()20389a1d03eSRichardTempODef<T>::TempODef() {} 20489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default' 20589a1d03eSRichard // CHECK-FIXES: TempODef<T>::TempODef() = default; 20689a1d03eSRichard template <class T> ~TempODef()20789a1d03eSRichardTempODef<T>::~TempODef() {} 20889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default' 20989a1d03eSRichard // CHECK-FIXES: TempODef<T>::~TempODef() = default; 21089a1d03eSRichard 21189a1d03eSRichard template class TempODef<int>; 21289a1d03eSRichard template class TempODef<double>; 21389a1d03eSRichard 21489a1d03eSRichard // Non user-provided constructor/destructor. 21589a1d03eSRichard struct Imp { 21689a1d03eSRichard int Int; 21789a1d03eSRichard }; g()21889a1d03eSRichardvoid g() { 21989a1d03eSRichard Imp *PtrImp = new Imp(); 22089a1d03eSRichard PtrImp->~Imp(); 22189a1d03eSRichard delete PtrImp; 22289a1d03eSRichard } 22389a1d03eSRichard 22489a1d03eSRichard // Already using default. 22589a1d03eSRichard struct IDef { 22689a1d03eSRichard IDef() = default; 22789a1d03eSRichard ~IDef() = default; 22889a1d03eSRichard }; 22989a1d03eSRichard struct ODef { 23089a1d03eSRichard ODef(); 23189a1d03eSRichard ~ODef(); 23289a1d03eSRichard }; 23389a1d03eSRichard ODef::ODef() = default; 23489a1d03eSRichard ODef::~ODef() = default; 23589a1d03eSRichard 23689a1d03eSRichard // Delegating constructor and overriden destructor. 23789a1d03eSRichard struct DC : KW { DCDC23889a1d03eSRichard DC() : KW() {} ~DCDC23989a1d03eSRichard ~DC() override {} 24089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 2416c07bda7SAlexander Shaposhnikov // CHECK-FIXES: ~DC() override = default;{{$}} 2426c07bda7SAlexander Shaposhnikov }; 2436c07bda7SAlexander Shaposhnikov 2446c07bda7SAlexander Shaposhnikov struct OverrideWithSemiColon : KW { ~OverrideWithSemiColonOverrideWithSemiColon2456c07bda7SAlexander Shaposhnikov ~OverrideWithSemiColon() override {}; 2466c07bda7SAlexander Shaposhnikov // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default' 2476c07bda7SAlexander Shaposhnikov // CHECK-FIXES: ~OverrideWithSemiColon() override = default;{{$}} 24889a1d03eSRichard }; 24989a1d03eSRichard 25089a1d03eSRichard struct Comments { CommentsComments25189a1d03eSRichard Comments() { 25289a1d03eSRichard // Don't erase comments inside the body. 25389a1d03eSRichard } 25489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default' ~CommentsComments25589a1d03eSRichard ~Comments() { 25689a1d03eSRichard // Don't erase comments inside the body. 25789a1d03eSRichard } 25889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default' 25989a1d03eSRichard }; 26089a1d03eSRichard 26189a1d03eSRichard // Try-catch. 26289a1d03eSRichard struct ITC { ITCITC26389a1d03eSRichard ITC() try {} catch(...) {} ~ITCITC26489a1d03eSRichard ~ITC() try {} catch(...) {} 26589a1d03eSRichard }; 26689a1d03eSRichard 26789a1d03eSRichard struct OTC { 26889a1d03eSRichard OTC(); 26989a1d03eSRichard ~OTC(); 27089a1d03eSRichard }; OTC()27189a1d03eSRichardOTC::OTC() try {} catch(...) {} ~OTC()27289a1d03eSRichardOTC::~OTC() try {} catch(...) {} 27389a1d03eSRichard 27489a1d03eSRichard #define STRUCT_WITH_DEFAULT(_base, _type) \ 27589a1d03eSRichard struct _type { \ 27689a1d03eSRichard _type() {} \ 27789a1d03eSRichard _base value; \ 27889a1d03eSRichard }; 27989a1d03eSRichard 28089a1d03eSRichard STRUCT_WITH_DEFAULT(unsigned char, InMacro) 281*eb87e55cSPiotr Zegar 282*eb87e55cSPiotr Zegar #define ZERO_VALUE 0 283*eb87e55cSPiotr Zegar struct PreprocesorDependentTest 284*eb87e55cSPiotr Zegar { 285*eb87e55cSPiotr Zegar void something(); 286*eb87e55cSPiotr Zegar PreprocesorDependentTestPreprocesorDependentTest287*eb87e55cSPiotr Zegar PreprocesorDependentTest() { 288*eb87e55cSPiotr Zegar #if ZERO_VALUE 289*eb87e55cSPiotr Zegar something(); 290*eb87e55cSPiotr Zegar #endif 291*eb87e55cSPiotr Zegar } 292*eb87e55cSPiotr Zegar ~PreprocesorDependentTestPreprocesorDependentTest293*eb87e55cSPiotr Zegar ~PreprocesorDependentTest() { 294*eb87e55cSPiotr Zegar #if ZERO_VALUE 295*eb87e55cSPiotr Zegar something(); 296*eb87e55cSPiotr Zegar #endif 297*eb87e55cSPiotr Zegar } 298*eb87e55cSPiotr Zegar }; 299