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