1 // RUN: %check_clang_tidy %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
2 
3 // Out of line definition.
4 class OL {
5 public:
6   OL();
7   ~OL();
8 };
9 
OL()10 OL::OL() {};
11 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial default constructor [modernize-use-equals-default]
12 // CHECK-FIXES: OL::OL() = default;
~OL()13 OL::~OL() {}
14 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial destructor [modernize-use-equals-default]
15 // CHECK-FIXES: OL::~OL() = default;
16 
17 // Inline definitions.
18 class IL {
19 public:
IL()20   IL() {} 	 ; // Note embedded tab on this line
21   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
22   // CHECK-FIXES: IL() = default 	 ; // Note embedded tab on this line
~IL()23   ~IL() {}
24   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
25   // CHECK-FIXES: ~IL() = default;
26 };
27 
28 // Non-empty body.
29 void f();
30 class NE {
31 public:
NE()32   NE() { f(); }
~NE()33   ~NE() { f(); }
34 };
35 
36 // Initializer or arguments.
37 class IA {
38 public:
39   // Constructor with initializer.
IA()40   IA() : Field(5) {}
41   // Constructor with arguments.
IA(int Arg1,int Arg2)42   IA(int Arg1, int Arg2) {}
43   int Field;
44 };
45 
46 // Default member initializer
47 class DMI {
48 public:
DMI()49   DMI() {} // Comment before semi-colon on next line
50   ;
51   // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
52   // CHECK-FIXES: DMI() = default // Comment before semi-colon on next line
53   // CHECK-FIXES-NEXT:   ;
54   int Field = 5;
55 };
56 
57 // Class member
58 class CM {
59 public:
CM()60   CM() {} /* Comments */ /* before */ /* semicolon */;
61   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
62   // CHECK-FIXES: CM() = default /* Comments */ /* before */ /* semicolon */;
63   OL o;
64 };
65 
66 // Private constructor/destructor.
67 class Priv {
Priv()68   Priv() {}
69   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
70   // CHECK-FIXES: Priv() = default;
~Priv()71   ~Priv() {};
72   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
73   // CHECK-FIXES: ~Priv() = default;
74 };
75 
76 // struct.
77 struct ST {
STST78   ST() {}
79   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
80   // CHECK-FIXES: ST() = default;
~STST81   ~ST() {}
82   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
83   // CHECK-FIXES: ST() = default;
84 };
85 
86 // Deleted constructor/destructor.
87 class Del {
88 public:
89   Del() = delete;
90   ~Del() = delete;
91 };
92 
93 // Do not remove other keywords.
94 class KW {
95 public:
KW()96   explicit KW() {}
97   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use '= default'
98   // CHECK-FIXES: explicit KW() = default;
~KW()99   virtual ~KW() {}
100   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use '= default'
101   // CHECK-FIXES: virtual ~KW() = default;
102 };
103 
104 // Nested class.
105 struct N {
106   struct NN {
NNN::NN107     NN() {}
108     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
109     // CHECK-FIXES: NN() = default;
~NNN::NN110     ~NN() {}
111     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default'
112     // CHECK-FIXES: ~NN() = default;
113   };
114   int Int;
115 };
116 
117 // Class template.
118 template <class T>
119 class Temp {
120 public:
Temp()121   Temp() {}
122   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
123   // CHECK-FIXES: Temp() = default;
~Temp()124   ~Temp() {}
125   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
126   // CHECK-FIXES: ~Temp() = default;
127 };
128 
129 // Class template out of line with explicit instantiation.
130 template <class T>
131 class TempODef {
132 public:
133   TempODef();
134   ~TempODef();
135 };
136 
137 template <class T>
TempODef()138 TempODef<T>::TempODef() {}
139 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default'
140 // CHECK-FIXES: TempODef<T>::TempODef() = default;
141 template <class T>
~TempODef()142 TempODef<T>::~TempODef() {}
143 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use '= default'
144 // CHECK-FIXES: TempODef<T>::~TempODef() = default;
145 
146 template class TempODef<int>;
147 template class TempODef<double>;
148 
149 // Non user-provided constructor/destructor.
150 struct Imp {
151   int Int;
152 };
g()153 void g() {
154   Imp *PtrImp = new Imp();
155   PtrImp->~Imp();
156   delete PtrImp;
157 }
158 
159 // Already using default.
160 struct IDef {
161   IDef() = default;
162   ~IDef() = default;
163 };
164 struct ODef {
165   ODef();
166   ~ODef();
167 };
168 ODef::ODef() = default;
169 ODef::~ODef() = default;
170 
171 // Delegating constructor and overriden destructor.
172 struct DC : KW {
DCDC173   DC() : KW() {}
~DCDC174   ~DC() override {}
175   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
176   // CHECK-FIXES: ~DC() override = default;
177 };
178 
179 struct Comments {
CommentsComments180   Comments() {
181     // Don't erase comments inside the body.
182   }
183   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
~CommentsComments184   ~Comments() {
185     // Don't erase comments inside the body.
186   }
187   // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use '= default'
188 };
189 
190 // Try-catch.
191 struct ITC {
ITCITC192   ITC() try {} catch(...) {}
~ITCITC193   ~ITC() try {} catch(...) {}
194 };
195 
196 struct OTC {
197   OTC();
198   ~OTC();
199 };
OTC()200 OTC::OTC() try {} catch(...) {}
~OTC()201 OTC::~OTC() try {} catch(...) {}
202 
203 #define STRUCT_WITH_DEFAULT(_base, _type) \
204   struct _type {                          \
205     _type() {}                            \
206     _base value;                          \
207   };
208 
209 STRUCT_WITH_DEFAULT(unsigned char, InMacro)
210