xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp (revision eb87e55c9aade5d7b42606487e69b5f3a6da1e65)
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()1089a1d03eSRichard OL::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()1389a1d03eSRichard OL::~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 Zegar NUO::NUO() {}
53*eb87e55cSPiotr Zegar // CHECK-FIXES: NUO::NUO() {}
~NUO()54*eb87e55cSPiotr Zegar NUO::~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 Shaposhnikov Priv::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 Shaposhnikov SemiColonOutOfLine::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()20389a1d03eSRichard TempODef<T>::TempODef() {}
20489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default'
20589a1d03eSRichard // CHECK-FIXES: TempODef<T>::TempODef() = default;
20689a1d03eSRichard template <class T>
~TempODef()20789a1d03eSRichard TempODef<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()21889a1d03eSRichard void 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()27189a1d03eSRichard OTC::OTC() try {} catch(...) {}
~OTC()27289a1d03eSRichard OTC::~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